Mirroring servlet-spec 4.0.1 at 5574e9b
See https://github.com/javaee/servlet-spec/releases/tag/4.0.1
Change-Id: I40d8dcc8c5740e7af051a54bbd9fc3aca77a67d7
diff --git a/third_party/servlet-spec/CONTRIBUTING.md b/third_party/servlet-spec/CONTRIBUTING.md
new file mode 100644
index 0000000..7630913
--- /dev/null
+++ b/third_party/servlet-spec/CONTRIBUTING.md
@@ -0,0 +1,30 @@
+---
+
+---
+
+# Source Code Submissions
+We welcome your contributions and look forward to collaborating with you. We can only accept source code repository
+submissions from users who have signed and returned the Oracle
+Contributor Agreement. You will find details and the agreement to sign at this OTN web page:
+[Oracle Contributor Agreement](http://www.oracle.com/technetwork/community/oca-486395.html).
+
+# Other Contributions
+For all project Submissions other than source code repository contributions, the following also applies: Oracle does
+not claim ownership of Your Submissions. However, in order to fulfill
+the purposes of this project, You must give Oracle and all Users
+the right to post, access, discuss, use, publish, disseminate, and refine
+Your Submissions.
+
+In legalese: *You hereby grant to Oracle and all
+Users a royalty-free, perpetual, irrevocable, worldwide, non-exclusive,
+and fully sub-licensable right and license, under Your intellectual
+property rights, to reproduce, modify, adapt, publish, translate, create
+derivative works from, distribute, perform, display, and use Your
+Submissions (in whole or part) and to incorporate or implement them in
+other works in any form, media, or technology now known or later
+developed, all subject to the obligation to retain any copyright notices
+included in Your Submissions. All Users, Oracle, and their
+sublicensees are responsible for any modifications they make to the
+Submissions of others.*
+
+Copyright © 2017 Oracle and/or its affiliates. All rights reserved.
diff --git a/third_party/servlet-spec/LICENSE b/third_party/servlet-spec/LICENSE
new file mode 100644
index 0000000..b1c74f9
--- /dev/null
+++ b/third_party/servlet-spec/LICENSE
@@ -0,0 +1,759 @@
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1
+
+1. Definitions.
+
+ 1.1. "Contributor" means each individual or entity that creates or
+ contributes to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Software, prior Modifications used by a Contributor (if any), and
+ the Modifications made by that particular Contributor.
+
+ 1.3. "Covered Software" means (a) the Original Software, or (b)
+ Modifications, or (c) the combination of files containing Original
+ Software with files containing Modifications, in each case including
+ portions thereof.
+
+ 1.4. "Executable" means the Covered Software in any form other than
+ Source Code.
+
+ 1.5. "Initial Developer" means the individual or entity that first
+ makes Original Software available under this License.
+
+ 1.6. "Larger Work" means a work which combines Covered Software or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.7. "License" means this document.
+
+ 1.8. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means the Source Code and Executable form of
+ any of the following:
+
+ A. Any file that results from an addition to, deletion from or
+ modification of the contents of a file containing Original Software
+ or previous Modifications;
+
+ B. Any new file that contains any part of the Original Software or
+ previous Modification; or
+
+ C. Any new file that is contributed or otherwise made available
+ under the terms of this License.
+
+ 1.10. "Original Software" means the Source Code and Executable form
+ of computer software code that is originally released under this
+ License.
+
+ 1.11. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.12. "Source Code" means (a) the common form of computer software
+ code in which modifications are made and (b) associated
+ documentation included in or with such code.
+
+ 1.13. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of,
+ this License. For legal entities, "You" includes any entity which
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject
+ to third party intellectual property claims, the Initial Developer
+ hereby grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer, to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Software (or portions thereof), with or without Modifications,
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using or selling of
+ Original Software, to make, have made, use, practice, sell, and
+ offer for sale, and/or otherwise dispose of the Original Software
+ (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are effective on
+ the date Initial Developer first distributes or otherwise makes the
+ Original Software available to a third party under the terms of this
+ License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: (1) for code that You delete from the Original Software, or
+ (2) for infringements caused by: (i) the modification of the
+ Original Software, or (ii) the combination of the Original Software
+ with other software or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject
+ to third party intellectual property claims, each Contributor hereby
+ grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof), either on an
+ unmodified basis, with other Modifications, as Covered Software
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or selling
+ of Modifications made by that Contributor either alone and/or in
+ combination with its Contributor Version (or portions of such
+ combination), to make, use, sell, offer for sale, have made, and/or
+ otherwise dispose of: (1) Modifications made by that Contributor (or
+ portions thereof); and (2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions of such
+ combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective
+ on the date Contributor first distributes or otherwise makes the
+ Modifications available to a third party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: (1) for any code that Contributor has deleted from the
+ Contributor Version; (2) for infringements caused by: (i) third
+ party modifications of Contributor Version, or (ii) the combination
+ of Modifications made by that Contributor with other software
+ (except as part of the Contributor Version) or other devices; or (3)
+ under Patent Claims infringed by Covered Software in the absence of
+ Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make available
+ in Executable form must also be made available in Source Code form
+ and that Source Code form must be distributed only under the terms
+ of this License. You must include a copy of this License with every
+ copy of the Source Code form of the Covered Software You distribute
+ or otherwise make available. You must inform recipients of any such
+ Covered Software in Executable form as to how they can obtain such
+ Covered Software in Source Code form in a reasonable manner on or
+ through a medium customarily used for software exchange.
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You contribute are
+ governed by the terms of this License. You represent that You
+ believe Your Modifications are Your original creation(s) and/or You
+ have sufficient rights to grant the rights conveyed by this License.
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications that
+ identifies You as the Contributor of the Modification. You may not
+ remove or alter any copyright, patent or trademark notices contained
+ within the Covered Software, or any notices of licensing or any
+ descriptive text giving attribution to any Contributor or the
+ Initial Developer.
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered Software in
+ Source Code form that alters or restricts the applicable version of
+ this License or the recipients' rights hereunder. You may choose to
+ offer, and to charge a fee for, warranty, support, indemnity or
+ liability obligations to one or more recipients of Covered Software.
+ However, you may do so only on Your own behalf, and not on behalf of
+ the Initial Developer or any Contributor. You must make it
+ absolutely clear that any such warranty, support, indemnity or
+ liability obligation is offered by You alone, and You hereby agree
+ to indemnify the Initial Developer and every Contributor for any
+ liability incurred by the Initial Developer or such Contributor as a
+ result of warranty, support, indemnity or liability terms You offer.
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered Software under
+ the terms of this License or under the terms of a license of Your
+ choice, which may contain terms different from this License,
+ provided that You are in compliance with the terms of this License
+ and that the license for the Executable form does not attempt to
+ limit or alter the recipient's rights in the Source Code form from
+ the rights set forth in this License. If You distribute the Covered
+ Software in Executable form under a different license, You must make
+ it absolutely clear that any terms which differ from this License
+ are offered by You alone, not by the Initial Developer or
+ Contributor. You hereby agree to indemnify the Initial Developer and
+ every Contributor for any liability incurred by the Initial
+ Developer or such Contributor as a result of any such terms You offer.
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software with
+ other code not governed by the terms of this License and distribute
+ the Larger Work as a single product. In such a case, You must make
+ sure the requirements of this License are fulfilled for the Covered
+ Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+
+ Oracle is the initial license steward and may publish revised and/or
+ new versions of this License from time to time. Each version will be
+ given a distinguishing version number. Except as provided in Section
+ 4.3, no one other than the license steward has the right to modify
+ this License.
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise make the
+ Covered Software available under the terms of the version of the
+ License under which You originally received the Covered Software. If
+ the Initial Developer includes a notice in the Original Software
+ prohibiting it from being distributed or otherwise made available
+ under any subsequent version of the License, You must distribute and
+ make the Covered Software available under the terms of the version
+ of the License under which You originally received the Covered
+ Software. Otherwise, You may also choose to use, distribute or
+ otherwise make the Covered Software available under the terms of any
+ subsequent version of the License published by the license steward.
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a new
+ license for Your Original Software, You may create and use a
+ modified version of this License if You: (a) rename the license and
+ remove any references to the name of the license steward (except to
+ note that the license differs from this License); and (b) otherwise
+ make it clear that the license contains terms which differ from this
+ License.
+
+5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE
+ IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
+ NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
+ THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE
+ DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY
+ OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,
+ REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS
+ AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to
+ cure such breach within 30 days of becoming aware of the breach.
+ Provisions which, by their nature, must remain in effect beyond the
+ termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding
+ declaratory judgment actions) against Initial Developer or a
+ Contributor (the Initial Developer or Contributor against whom You
+ assert such claim is referred to as "Participant") alleging that the
+ Participant Software (meaning the Contributor Version where the
+ Participant is a Contributor or the Original Software where the
+ Participant is the Initial Developer) directly or indirectly
+ infringes any patent, then any and all rights granted directly or
+ indirectly to You by such Participant, the Initial Developer (if the
+ Initial Developer is not the Participant) and all Contributors under
+ Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice
+ from Participant terminate prospectively and automatically at the
+ expiration of such 60 day notice period, unless if within such 60
+ day period You withdraw Your claim with respect to the Participant
+ Software against such Participant either unilaterally or pursuant to
+ a written agreement with Participant.
+
+ 6.3. If You assert a patent infringement claim against Participant
+ alleging that the Participant Software directly or indirectly
+ infringes any patent where such claim is resolved (such as by
+ license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 6.4. In the event of termination under Sections 6.1 or 6.2 above,
+ all end user licenses that have been validly granted by You or any
+ distributor hereunder prior to termination (excluding licenses
+ granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+ INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+ COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE
+ TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+ LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
+ FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR
+ LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE
+ POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT
+ APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH
+ PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH
+ LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
+ LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION
+ AND LIMITATION MAY NOT APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a "commercial item," as that term is defined
+ in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" (as that term is defined at 48 C.F.R. §
+ 252.227-7014(a)(1)) and "commercial computer software documentation"
+ as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent
+ with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4
+ (June 1995), all U.S. Government End Users acquire Covered Software
+ with only those rights set forth herein. This U.S. Government Rights
+ clause is in lieu of, and supersedes, any other FAR, DFAR, or other
+ clause or provision that addresses Government rights in computer
+ software under this License.
+
+9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ the law of the jurisdiction specified in a notice contained within
+ the Original Software (except to the extent applicable law, if any,
+ provides otherwise), excluding such jurisdiction's conflict-of-law
+ provisions. Any litigation relating to this License shall be subject
+ to the jurisdiction of the courts located in the jurisdiction and
+ venue specified in a notice contained within the Original Software,
+ with the losing party responsible for costs, including, without
+ limitation, court costs and reasonable attorneys' fees and expenses.
+ The application of the United Nations Convention on Contracts for
+ the International Sale of Goods is expressly excluded. Any law or
+ regulation which provides that the language of a contract shall be
+ construed against the drafter shall not apply to this License. You
+ agree that You alone are responsible for compliance with the United
+ States export administration regulations (and the export control
+ laws and regulation of any other countries) when You use, distribute
+ or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+------------------------------------------------------------------------
+
+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION
+LICENSE (CDDL)
+
+The code released under the CDDL shall be governed by the laws of the
+State of California (excluding conflict-of-law provisions). Any
+litigation relating to this License shall be subject to the jurisdiction
+of the Federal Courts of the Northern District of California and the
+state courts of the State of California, with venue lying in Santa Clara
+County, California.
+
+
+
+ The GNU General Public License (GPL) Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor
+Boston, MA 02110-1335
+USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users. This General Public
+License applies to most of the Free Software Foundation's software and
+to any other program whose authors commit to using it. (Some other Free
+Software Foundation software is covered by the GNU Library General
+Public License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.
+Our General Public Licenses are designed to make sure that you have the
+freedom to distribute copies of free software (and charge for this
+service if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone
+to deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis
+or for a fee, you must give the recipients all the rights that you have.
+You must make sure that they, too, receive or can get the source code.
+And you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.
+We wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program
+proprietary. To prevent this, we have made it clear that any patent must
+be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a
+notice placed by the copyright holder saying it may be distributed under
+the terms of this General Public License. The "Program", below, refers
+to any such program or work, and a "work based on the Program" means
+either the Program or any derivative work under copyright law: that is
+to say, a work containing the Program or a portion of it, either
+verbatim or with modifications and/or translated into another language.
+(Hereinafter, translation is included without limitation in the term
+"modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of running
+the Program is not restricted, and the output from the Program is
+covered only if its contents constitute a work based on the Program
+(independent of having been made by running the Program). Whether that
+is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy an appropriate copyright notice
+and disclaimer of warranty; keep intact all the notices that refer to
+this License and to the absence of any warranty; and give any other
+recipients of the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of
+it, thus forming a work based on the Program, and copy and distribute
+such modifications or work under the terms of Section 1 above, provided
+that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+ under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this License.
+ (Exception: if the Program itself is interactive but does not
+ normally print such an announcement, your work based on the Program
+ is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program, and
+can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based on
+the Program, the distribution of the whole must be on the terms of this
+License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of a
+storage or distribution medium does not bring the other work under the
+scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your cost
+ of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed
+ only for noncommercial distribution and only if you received the
+ program in object code or executable form with such an offer, in
+ accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source code
+means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to control
+compilation and installation of the executable. However, as a special
+exception, the source code distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies the
+executable.
+
+If distribution of executable or object code is made by offering access
+to copy from a designated place, then offering equivalent access to copy
+the source code from the same place counts as distribution of the source
+code, even though third parties are not compelled to copy the source
+along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt otherwise
+to copy, modify, sublicense or distribute the Program is void, and will
+automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will
+not have their licenses terminated so long as such parties remain in
+full compliance.
+
+5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and all
+its terms and conditions for copying, distributing or modifying the
+Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further restrictions
+on the recipients' exercise of the rights granted herein. You are not
+responsible for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot distribute
+so as to satisfy simultaneously your obligations under this License and
+any other pertinent obligations, then as a consequence you may not
+distribute the Program at all. For example, if a patent license would
+not permit royalty-free redistribution of the Program by all those who
+receive copies directly or indirectly through you, then the only way you
+could satisfy both it and this License would be to refrain entirely from
+distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is implemented
+by public license practices. Many people have made generous
+contributions to the wide range of software distributed through that
+system in reliance on consistent application of that system; it is up to
+the author/donor to decide if he or she is willing to distribute
+software through any other system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be
+a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License may
+add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among countries
+not thus excluded. In such case, this License incorporates the
+limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new
+versions of the General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Program does not specify a version
+number of this License, you may choose any version ever published by the
+Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the
+author to ask for permission. For software which is copyrighted by the
+Free Software Foundation, write to the Free Software Foundation; we
+sometimes make exceptions for this. Our decision will be guided by the
+two goals of preserving the free status of all derivatives of our free
+software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
+EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
+DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
+(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
+THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
+OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ One line to give the program's name and a brief idea of what it does.
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type
+ `show w'. This is free software, and you are welcome to redistribute
+ it under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the commands
+you use may be called something other than `show w' and `show c'; they
+could even be mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (which makes passes at compilers) written by
+ James Hacker.
+
+ signature of Ty Coon, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications
+with the library. If this is what you want to do, use the GNU Library
+General Public License instead of this License.
+
+#
+
+Certain source files distributed by Oracle America, Inc. and/or its
+affiliates are subject to the following clarification and special
+exception to the GPLv2, based on the GNU Project exception for its
+Classpath libraries, known as the GNU Classpath Exception, but only
+where Oracle has expressly included in the particular source file's
+header the words "Oracle designates this particular file as subject to
+the "Classpath" exception as provided by Oracle in the LICENSE file
+that accompanied this code."
+
+You should also note that Oracle includes multiple, independent
+programs in this software package. Some of those programs are provided
+under licenses deemed incompatible with the GPLv2 by the Free Software
+Foundation and others. For example, the package includes programs
+licensed under the Apache License, Version 2.0. Such programs are
+licensed to you under their original licenses.
+
+Oracle facilitates your further distribution of this package by adding
+the Classpath Exception to the necessary parts of its GPLv2 code, which
+permits you to use that code in combination with other independent
+modules not licensed under the GPLv2. However, note that this would
+not permit you to commingle code under an incompatible license with
+Oracle's GPLv2 licensed code by, for example, cutting and pasting such
+code into a file also containing Oracle's GPLv2 licensed code and then
+distributing the result. Additionally, if you were to remove the
+Classpath Exception from any of the files to which it applies and
+distribute the result, you would likely be required to license some or
+all of the other code in that distribution under the GPLv2 as well, and
+since the GPLv2 is incompatible with the license terms of some items
+included in the distribution by Oracle, removing the Classpath
+Exception could therefore effectively compromise your ability to
+further distribute the package.
+
+Proceed with caution and we recommend that you obtain the advice of a
+lawyer skilled in open source matters before removing the Classpath
+Exception or making modifications to this package which may
+subsequently be redistributed and/or involve the use of third party
+software.
+
+CLASSPATH EXCEPTION
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License version 2 cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from or
+based on this library. If you modify this library, you may extend this
+exception to your version of the library, but you are not obligated to
+do so. If you do not wish to do so, delete this exception statement
+from your version.
diff --git a/third_party/servlet-spec/README.md b/third_party/servlet-spec/README.md
new file mode 100644
index 0000000..5cd7451
--- /dev/null
+++ b/third_party/servlet-spec/README.md
@@ -0,0 +1,22 @@
+Java Servlet API
+================
+
+Building
+--------
+
+Prerequisites:
+
+* JDK8+
+* Maven 3.0.3+
+
+Run the build:
+
+`mvn install`
+
+The build runs copyright check and generates the jar, sources-jar and javadoc-jar by default.
+
+Checking findbugs
+-----------------
+
+`mvn -DskipTests -Dfindbugs.threshold=Low findbugs:findbugs`
+
diff --git a/third_party/servlet-spec/copyright-exclude b/third_party/servlet-spec/copyright-exclude
new file mode 100644
index 0000000..2430b60
--- /dev/null
+++ b/third_party/servlet-spec/copyright-exclude
@@ -0,0 +1,10 @@
+copyright-exclude
+LICENSE
+README
+CONTRIBUTING.md
+src/main/javadoc/doc-files/expert-draft-bg-blank.graffle
+src/main/javadoc/doc-files/expert-draft-bg-blank.png
+src/main/javadoc/doc-files/expert-draft-bg-non-blank.graffle
+src/main/javadoc/doc-files/expert-draft-bg-non-blank.png
+src/main/javadoc/doc-files/expert-draft-bg.png
+src/main/javadoc/doc-files/speclicense.html
diff --git a/third_party/servlet-spec/exclude.xml b/third_party/servlet-spec/exclude.xml
new file mode 100644
index 0000000..fbc3147
--- /dev/null
+++ b/third_party/servlet-spec/exclude.xml
@@ -0,0 +1,53 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ or LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<FindBugsFilter>
+ <!--
+ Shing Wai Chan has discussed this issue with Bill Shannon.
+ The ServletRequestEvent is not intended to be a Serializable,
+ which is inherited from java.util.EventObject.
+ -->
+ <Match>
+ <Class name="javax.servlet.ServletRequestEvent"/>
+ <Bug pattern="SE_TRANSIENT_FIELD_NOT_RESTORED"/>
+ </Match>
+</FindBugsFilter>
diff --git a/third_party/servlet-spec/pom.xml b/third_party/servlet-spec/pom.xml
new file mode 100644
index 0000000..1a1198e
--- /dev/null
+++ b/third_party/servlet-spec/pom.xml
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ or LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>net.java</groupId>
+ <artifactId>jvnet-parent</artifactId>
+ <version>3</version>
+ </parent>
+
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <packaging>jar</packaging>
+ <version>4.0.1</version>
+
+ <properties>
+ <spec.version>4.0</spec.version>
+ <extension.name>javax.servlet</extension.name>
+ <bundle.symbolicName>javax.servlet-api</bundle.symbolicName>
+ <bundle.version>4.0.0</bundle.version>
+ <window.title>Java Servlet 4.0</window.title>
+ <doc.title>Java Servlet 4.0 API Specification</doc.title>
+ <vendor.name>Oracle Corporation</vendor.name>
+ <implementation.vendor.id>org.glassfish</implementation.vendor.id>
+ <findbugs.version>3.0.4</findbugs.version>
+ <findbugs.exclude>exclude.xml</findbugs.exclude>
+ <findbugs.threshold>Low</findbugs.threshold>
+ <copyright-plugin.version>1.49</copyright-plugin.version>
+ </properties>
+ <name>Java Servlet API</name>
+
+ <url>https://javaee.github.io/servlet-spec/</url>
+
+ <developers>
+ <developer>
+ <id>edburns</id>
+ <name>Ed Burns</name>
+ <url>http://purl.oclc.org/NET/edburns/</url>
+ <organization>Oracle</organization>
+ <roles>
+ <role>co-lead</role>
+ <role>developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>shingwaichan</id>
+ <name>Shing Wai Chan</name>
+ <organization>Oracle</organization>
+ <roles>
+ <role>lead</role>
+ <role>developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <distributionManagement>
+ <snapshotRepository>
+ <id>jvnet-nexus-snapshots</id>
+ <name>Java.net Nexus Snapshots Repository</name>
+ <url>https://maven.java.net/content/repositories/snapshots/</url>
+ </snapshotRepository>
+ <repository>
+ <id>jvnet-nexus-staging</id>
+ <name>Java.net Nexus Staging Repository</name>
+ <url>https://maven.java.net/service/local/staging/deploy/maven2/</url>
+ </repository>
+ </distributionManagement>
+
+ <organization>
+ <name>GlassFish Community</name>
+ <url>https://javaee.github.io</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>CDDL + GPLv2 with classpath exception</name>
+ <url>https://oss.oracle.com/licenses/CDDL+GPL-1.1</url>
+ <distribution>repo</distribution>
+ <comments>A business-friendly OSS license</comments>
+ </license>
+ </licenses>
+ <issueManagement>
+ <system>github</system>
+ <url>https://github.com/javaee/servlet-spec/issues</url>
+ </issueManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Servlet Developer</name>
+ <archive>servlet-spec@javaee.groups.io</archive>
+ </mailingList>
+ </mailingLists>
+ <scm>
+ <connection>scm:git:https://github.com/javaee/servlet-spec.git</connection>
+ <developerConnection>scm:git:git@github.com:javaee/servlet-spec.git</developerConnection>
+ <url>https://github.com/javaee/servlet-spec</url>
+ <tag>4.0.1</tag>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <compilerArgument>-Xlint:all</compilerArgument>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.3</version>
+ <configuration>
+ <supportedProjectTypes>
+ <supportedProjectType>jar</supportedProjectType>
+ </supportedProjectTypes>
+ <instructions>
+ <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
+ <Bundle-Description>
+ Java(TM) Servlet ${spec.version} API Design Specification
+ </Bundle-Description>
+ <Bundle-Version>${bundle.version}</Bundle-Version>
+ <Extension-Name>${extension.name}</Extension-Name>
+ <Specification-Version>${spec.version}</Specification-Version>
+ <Specification-Vendor>${vendor.name}</Specification-Vendor>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+ <Implementation-Vendor-Id>${implementation.vendor.id}</Implementation-Vendor-Id>
+ </instructions>
+ </configuration>
+ <executions>
+ <execution>
+ <id>bundle-manifest</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.2.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.glassfish:legal:1.1</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <includePom>true</includePom>
+ </configuration>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10.4</version>
+ <configuration>
+ <sourcepath>src</sourcepath>
+ <doctitle>${doc.title}</doctitle>
+ <windowtitle>${window.title}</windowtitle>
+ <stylesheetfile>javax.servlet-api.css</stylesheetfile>
+ <docfilessubdirs>true</docfilessubdirs>
+ <groups>
+ <group>
+ <title>Servlet API Documentation</title>
+ <packages>javax.servlet</packages>
+ </group>
+ </groups>
+ <bottom>
+<![CDATA[Copyright © 1999-2017,
+ <a href="http://www.oracle.com">Oracle</a>
+ and/or its affiliates. All Rights Reserved.
+ Use is subject to
+ <a href="{@docRoot}/doc-files/speclicense.html" target="_top">license terms</a>.
+ Portions Copyright © 1999-2002 The Apache Software Foundation.
+]]>
+ </bottom>
+ <tags>
+ <tag>
+ <name>implSpec</name>
+ <placement>a</placement>
+ <head>Implementation Requirements:</head>
+ </tag>
+ <tag>
+ <name>param</name>
+ </tag>
+ <tag>
+ <name>return</name>
+ </tag>
+ <tag>
+ <name>throws</name>
+ </tag>
+ <tag>
+ <name>since</name>
+ </tag>
+ <tag>
+ <name>version</name>
+ </tag>
+ <tag>
+ <name>serialData</name>
+ </tag>
+ <tag>
+ <name>factory</name>
+ </tag>
+ <tag>
+ <name>see</name>
+ </tag>
+ </tags>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs.version}</version>
+ <configuration>
+ <threshold>${findbugs.threshold}</threshold>
+ <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
+ <findbugsXmlOutput>true</findbugsXmlOutput>
+ <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.5.3</version>
+ <configuration>
+ <mavenExecutorId>forked-path</mavenExecutorId>
+ <useReleaseProfile>false</useReleaseProfile>
+ <tagNameFormat>@{project.version}</tagNameFormat>
+ <arguments>${release.arguments}</arguments>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-gitexe</artifactId>
+ <version>1.8.1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.glassfish.copyright</groupId>
+ <artifactId>glassfish-copyright-maven-plugin</artifactId>
+ <version>${copyright-plugin.version}</version>
+ <configuration>
+ <scm>git</scm>
+ <scmOnly>true</scmOnly>
+ <excludeFile>
+ ${basedir}/copyright-exclude
+ </excludeFile>
+ <ignoreYear>true</ignoreYear>
+ </configuration>
+ <executions>
+ <execution>
+ <id>check-copyright</id>
+ <phase>process-test-sources</phase>
+ <goals>
+ <goal>copyright</goal>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <resources>
+ <resource>
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**/*.properties</include>
+ <include>**/*.html</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <excludes>
+ <exclude>META-INF/README</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs.version}</version>
+ <configuration>
+ <threshold>${findbugs.threshold}</threshold>
+ <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/third_party/servlet-spec/release.sh b/third_party/servlet-spec/release.sh
new file mode 100755
index 0000000..6229b24
--- /dev/null
+++ b/third_party/servlet-spec/release.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common Development
+# and Distribution License("CDDL") (collectively, the "License"). You
+# may not use this file except in compliance with the License. You can
+# obtain a copy of the License at
+# https://oss.oracle.com/licenses/CDDL+GPL-1.1
+# or LICENSE.txt. See the License for the specific
+# language governing permissions and limitations under the License.
+#
+# When distributing the software, include this License Header Notice in each
+# file and include the License file at LICENSE.txt.
+#
+# GPL Classpath Exception:
+# Oracle designates this particular file as subject to the "Classpath"
+# exception as provided by Oracle in the GPL Version 2 section of the License
+# file that accompanied this code.
+#
+# Modifications:
+# If applicable, add the following below the License Header, with the fields
+# enclosed by brackets [] replaced by your own identifying information:
+# "Portions Copyright [year] [name of copyright owner]"
+#
+# Contributor(s):
+# If you wish your version of this file to be governed by only the CDDL or
+# only the GPL Version 2, indicate your decision by adding "[Contributor]
+# elects to include this software in this distribution under the [CDDL or GPL
+# Version 2] license." If you don't indicate a single choice of license, a
+# recipient has the option to distribute your version of this file under
+# either the CDDL, the GPL Version 2 or to extend the choice of license to
+# its licensees as provided above. However, if you add GPL Version 2 code
+# and therefore, elected the GPL Version 2 license, then the option applies
+# only if the new code is made subject to such option by the copyright
+# holder.
+#
+
+#------------------------------------------------------
+#-- BE SURE TO HAVE THE FOLLOWING IN YOUR SETTINGS.XML
+#------------------------------------------------------
+#
+# <servers>
+# <server>
+# <id>jvnet-nexus-staging</id>
+# <username>jvnet_id</username>
+# <password>password</password>
+# </server>
+# </servers>
+# <profiles>
+# <profile>
+# <id>release</id>
+# <properties>
+# <release.arguments>-Dhttps.proxyHost=www-proxy.us.oracle.com -Dhttps.proxyPort=80 -Dgpg.passphrase=glassfish -Pjvnet-release</release.arguments>
+# </properties>
+# <activation>
+# <activeByDefault>false</activeByDefault>
+# </activation>
+# </profile>
+# </profiles>
+
+# see the following URL for gpg issues
+# https://docs.sonatype.org/display/Repository/How+To+Generate+PGP+Signatures+With+Maven#HowToGeneratePGPSignaturesWithMaven-GenerateaKeyPair
+
+# login to nexus at maven.java.net and release (Close) the artifact
+# https://maven.java.net/index.html#stagingRepositories
+
+# More information:
+# https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8.ReleaseIt
+# http://aseng-wiki.us.oracle.com/asengwiki/display/GlassFish/Migrating+Maven+deployment+to+maven.java.net
+
+mvn -B release:prepare -Prelease
+mvn -B release:perform -Prelease
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/AsyncContext.java b/third_party/servlet-spec/src/main/java/javax/servlet/AsyncContext.java
new file mode 100644
index 0000000..68e29e6
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/AsyncContext.java
@@ -0,0 +1,515 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+/**
+ * Class representing the execution context for an asynchronous operation
+ * that was initiated on a ServletRequest.
+ *
+ * <p>An AsyncContext is created and initialized by a call to
+ * {@link ServletRequest#startAsync()} or
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}.
+ * Repeated invocations of these methods will return the same AsyncContext
+ * instance, reinitialized as appropriate.
+ *
+ * <p>In the event that an asynchronous operation has timed out, the
+ * container must run through these steps:
+ * <ol>
+ * <li>Invoke, at their {@link AsyncListener#onTimeout onTimeout} method, all
+ * {@link AsyncListener} instances registered with the ServletRequest
+ * on which the asynchronous operation was initiated.</li>
+ * <li>If none of the listeners called {@link #complete} or any of the
+ * {@link #dispatch} methods, perform an error dispatch with a status code
+ * equal to <tt>HttpServletResponse.SC_INTERNAL_SERVER_ERROR</tt>.</li>
+ * <li>If no matching error page was found, or the error page did not call
+ * {@link #complete} or any of the {@link #dispatch} methods, call
+ * {@link #complete}.</li>
+ * </ol>
+ *
+ * @since Servlet 3.0
+ */
+public interface AsyncContext {
+
+ /**
+ * The name of the request attribute under which the original
+ * request URI is made available to the target of a
+ * {@link #dispatch(String)} or {@link #dispatch(ServletContext,String)}
+ */
+ static final String ASYNC_REQUEST_URI = "javax.servlet.async.request_uri";
+
+ /**
+ * The name of the request attribute under which the original
+ * context path is made available to the target of a
+ * {@link #dispatch(String)} or {@link #dispatch(ServletContext,String)}
+ */
+ static final String ASYNC_CONTEXT_PATH = "javax.servlet.async.context_path";
+
+ /**
+ * The name of the request attribute under which the original
+ * {@link javax.servlet.http.HttpServletMapping} is made available to the target of a
+ * {@link #dispatch(String)} or {@link #dispatch(ServletContext,String)}
+ */
+ static final String ASYNC_MAPPING = "javax.servlet.async.mapping";
+
+ /**
+ * The name of the request attribute under which the original
+ * path info is made available to the target of a
+ * {@link #dispatch(String)} or {@link #dispatch(ServletContext,String)}
+ */
+ static final String ASYNC_PATH_INFO = "javax.servlet.async.path_info";
+
+ /**
+ * The name of the request attribute under which the original
+ * servlet path is made available to the target of a
+ * {@link #dispatch(String)} or {@link #dispatch(ServletContext,String)}
+ */
+ static final String ASYNC_SERVLET_PATH = "javax.servlet.async.servlet_path";
+
+ /**
+ * The name of the request attribute under which the original
+ * query string is made available to the target of a
+ * {@link #dispatch(String)} or {@link #dispatch(ServletContext,String)}
+ */
+ static final String ASYNC_QUERY_STRING = "javax.servlet.async.query_string";
+
+
+ /**
+ * Gets the request that was used to initialize this AsyncContext
+ * by calling {@link ServletRequest#startAsync()} or
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}.
+ *
+ * @return the request that was used to initialize this AsyncContext
+ *
+ * @exception IllegalStateException if {@link #complete} or any of the
+ * {@link #dispatch} methods has been
+ * called in the asynchronous cycle
+ */
+ public ServletRequest getRequest();
+
+
+ /**
+ * Gets the response that was used to initialize this AsyncContext
+ * by calling {@link ServletRequest#startAsync()} or
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}.
+ *
+ * @return the response that was used to initialize this AsyncContext
+ *
+ * @exception IllegalStateException if {@link #complete} or any of the
+ * {@link #dispatch} methods has been
+ * called in the asynchronous cycle
+ */
+ public ServletResponse getResponse();
+
+
+ /**
+ * Checks if this AsyncContext was initialized with the original or
+ * application-wrapped request and response objects.
+ *
+ * <p>This information may be used by filters invoked in the
+ * <i>outbound</i> direction, after a request was put into
+ * asynchronous mode, to determine whether any request and/or response
+ * wrappers that they added during their <i>inbound</i> invocation need
+ * to be preserved for the duration of the asynchronous operation, or may
+ * be released.
+ *
+ * @return true if this AsyncContext was initialized with the original
+ * request and response objects by calling
+ * {@link ServletRequest#startAsync()}, or if it was initialized by
+ * calling
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)},
+ * and neither the ServletRequest nor ServletResponse arguments
+ * carried any application-provided wrappers; false otherwise
+ */
+ public boolean hasOriginalRequestAndResponse();
+
+
+ /**
+ * Dispatches the request and response objects of this AsyncContext
+ * to the servlet container.
+ *
+ * <p>If the asynchronous cycle was started with
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)},
+ * and the request passed is an instance of HttpServletRequest,
+ * then the dispatch is to the URI returned by
+ * {@link javax.servlet.http.HttpServletRequest#getRequestURI}.
+ * Otherwise, the dispatch is to the URI of the request when it was
+ * last dispatched by the container.
+ *
+ * <p>The following sequence illustrates how this will work:
+ * <pre>{@code
+ * // REQUEST dispatch to /url/A
+ * AsyncContext ac = request.startAsync();
+ * ...
+ * ac.dispatch(); // ASYNC dispatch to /url/A
+ *
+ * // REQUEST to /url/A
+ * // FORWARD dispatch to /url/B
+ * request.getRequestDispatcher("/url/B").forward(request,response);
+ * // Start async operation from within the target of the FORWARD
+ * // dispatch
+ * ac = request.startAsync();
+ * ...
+ * ac.dispatch(); // ASYNC dispatch to /url/A
+ *
+ * // REQUEST to /url/A
+ * // FORWARD dispatch to /url/B
+ * request.getRequestDispatcher("/url/B").forward(request,response);
+ * // Start async operation from within the target of the FORWARD
+ * // dispatch
+ * ac = request.startAsync(request,response);
+ * ...
+ * ac.dispatch(); // ASYNC dispatch to /url/B
+ * }</pre>
+ *
+ * <p>This method returns immediately after passing the request
+ * and response objects to a container managed thread, on which the
+ * dispatch operation will be performed.
+ * If this method is called before the container-initiated dispatch
+ * that called <tt>startAsync</tt> has returned to the container, the
+ * dispatch operation will be delayed until after the container-initiated
+ * dispatch has returned to the container.
+ *
+ * <p>The dispatcher type of the request is set to
+ * <tt>DispatcherType.ASYNC</tt>. Unlike
+ * {@link RequestDispatcher#forward(ServletRequest, ServletResponse)
+ * forward dispatches}, the response buffer and
+ * headers will not be reset, and it is legal to dispatch even if the
+ * response has already been committed.
+ *
+ * <p>Control over the request and response is delegated
+ * to the dispatch target, and the response will be closed when the
+ * dispatch target has completed execution, unless
+ * {@link ServletRequest#startAsync()} or
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}
+ * are called.
+ *
+ * <p>Any errors or exceptions that may occur during the execution
+ * of this method must be caught and handled by the container, as
+ * follows:
+ * <ol>
+ * <li>Invoke, at their {@link AsyncListener#onError onError} method, all
+ * {@link AsyncListener} instances registered with the ServletRequest
+ * for which this AsyncContext was created, and make the caught
+ * <tt>Throwable</tt> available via {@link AsyncEvent#getThrowable}.</li>
+ * <li>If none of the listeners called {@link #complete} or any of the
+ * {@link #dispatch} methods, perform an error dispatch with a status code
+ * equal to <tt>HttpServletResponse.SC_INTERNAL_SERVER_ERROR</tt>, and
+ * make the above <tt>Throwable</tt> available as the value of the
+ * <tt>RequestDispatcher.ERROR_EXCEPTION</tt> request attribute.</li>
+ * <li>If no matching error page was found, or the error page did not call
+ * {@link #complete} or any of the {@link #dispatch} methods, call
+ * {@link #complete}.</li>
+ * </ol>
+ *
+ * <p>There can be at most one asynchronous dispatch operation per
+ * asynchronous cycle, which is started by a call to one of the
+ * {@link ServletRequest#startAsync} methods. Any attempt to perform an
+ * additional asynchronous dispatch operation within the same
+ * asynchronous cycle will result in an IllegalStateException.
+ * If startAsync is subsequently called on the dispatched request,
+ * then any of the dispatch or {@link #complete} methods may be called.
+ *
+ * @throws IllegalStateException if one of the dispatch methods
+ * has been called and the startAsync method has not been
+ * called during the resulting dispatch, or if {@link #complete}
+ * was called
+ *
+ * @see ServletRequest#getDispatcherType
+ */
+ public void dispatch();
+
+
+ /**
+ * Dispatches the request and response objects of this AsyncContext
+ * to the given <tt>path</tt>.
+ *
+ * <p>The <tt>path</tt> parameter is interpreted in the same way
+ * as in {@link ServletRequest#getRequestDispatcher(String)}, within
+ * the scope of the {@link ServletContext} from which this
+ * AsyncContext was initialized.
+ *
+ * <p>All path related query methods of the request must reflect the
+ * dispatch target, while the original request URI, context path,
+ * path info, servlet path, and query string may be recovered from
+ * the {@link #ASYNC_REQUEST_URI}, {@link #ASYNC_CONTEXT_PATH},
+ * {@link #ASYNC_PATH_INFO}, {@link #ASYNC_SERVLET_PATH}, and
+ * {@link #ASYNC_QUERY_STRING} attributes of the request. These
+ * attributes will always reflect the original path elements, even under
+ * repeated dispatches.
+ *
+ * <p>There can be at most one asynchronous dispatch operation per
+ * asynchronous cycle, which is started by a call to one of the
+ * {@link ServletRequest#startAsync} methods. Any attempt to perform an
+ * additional asynchronous dispatch operation within the same
+ * asynchronous cycle will result in an IllegalStateException.
+ * If startAsync is subsequently called on the dispatched request,
+ * then any of the dispatch or {@link #complete} methods may be called.
+ *
+ * <p>See {@link #dispatch()} for additional details, including error
+ * handling.
+ *
+ * @param path the path of the dispatch target, scoped to the
+ * ServletContext from which this AsyncContext was initialized
+ *
+ * @throws IllegalStateException if one of the dispatch methods
+ * has been called and the startAsync method has not been
+ * called during the resulting dispatch, or if {@link #complete}
+ * was called
+ *
+ * @see ServletRequest#getDispatcherType
+ */
+ public void dispatch(String path);
+
+
+ /**
+ * Dispatches the request and response objects of this AsyncContext
+ * to the given <tt>path</tt> scoped to the given <tt>context</tt>.
+ *
+ * <p>The <tt>path</tt> parameter is interpreted in the same way
+ * as in {@link ServletRequest#getRequestDispatcher(String)}, except that
+ * it is scoped to the given <tt>context</tt>.
+ *
+ * <p>All path related query methods of the request must reflect the
+ * dispatch target, while the original request URI, context path,
+ * path info, servlet path, and query string may be recovered from
+ * the {@link #ASYNC_REQUEST_URI}, {@link #ASYNC_CONTEXT_PATH},
+ * {@link #ASYNC_PATH_INFO}, {@link #ASYNC_SERVLET_PATH}, and
+ * {@link #ASYNC_QUERY_STRING} attributes of the request. These
+ * attributes will always reflect the original path elements, even under
+ * repeated dispatches.
+ *
+ * <p>There can be at most one asynchronous dispatch operation per
+ * asynchronous cycle, which is started by a call to one of the
+ * {@link ServletRequest#startAsync} methods. Any attempt to perform an
+ * additional asynchronous dispatch operation within the same
+ * asynchronous cycle will result in an IllegalStateException.
+ * If startAsync is subsequently called on the dispatched request,
+ * then any of the dispatch or {@link #complete} methods may be called.
+ *
+ * <p>See {@link #dispatch()} for additional details, including error
+ * handling.
+ *
+ * @param context the ServletContext of the dispatch target
+ * @param path the path of the dispatch target, scoped to the given
+ * ServletContext
+ *
+ * @throws IllegalStateException if one of the dispatch methods
+ * has been called and the startAsync method has not been
+ * called during the resulting dispatch, or if {@link #complete}
+ * was called
+ *
+ * @see ServletRequest#getDispatcherType
+ */
+ public void dispatch(ServletContext context, String path);
+
+
+ /**
+ * Completes the asynchronous operation that was started on the request
+ * that was used to initialze this AsyncContext, closing the response
+ * that was used to initialize this AsyncContext.
+ *
+ * <p>Any listeners of type {@link AsyncListener} that were registered
+ * with the ServletRequest for which this AsyncContext was created will
+ * be invoked at their {@link AsyncListener#onComplete(AsyncEvent)
+ * onComplete} method.
+ *
+ * <p>It is legal to call this method any time after a call to
+ * {@link ServletRequest#startAsync()} or
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)},
+ * and before a call to one of the <tt>dispatch</tt> methods
+ * of this class.
+ * If this method is called before the container-initiated dispatch
+ * that called <tt>startAsync</tt> has returned to the container, then
+ * the call will not take effect (and any invocations of
+ * {@link AsyncListener#onComplete(AsyncEvent)} will be delayed) until
+ * after the container-initiated dispatch has returned to the container.
+ */
+ public void complete();
+
+
+ /**
+ * Causes the container to dispatch a thread, possibly from a managed
+ * thread pool, to run the specified <tt>Runnable</tt>. The container may
+ * propagate appropriate contextual information to the <tt>Runnable</tt>.
+ *
+ * @param run the asynchronous handler
+ */
+ public void start(Runnable run);
+
+
+ /**
+ * Registers the given {@link AsyncListener} with the most recent
+ * asynchronous cycle that was started by a call to one of the
+ * {@link ServletRequest#startAsync} methods.
+ *
+ * <p>The given AsyncListener will receive an {@link AsyncEvent} when
+ * the asynchronous cycle completes successfully, times out, results
+ * in an error, or a new asynchronous cycle is being initiated via
+ * one of the {@link ServletRequest#startAsync} methods.
+ *
+ * <p>AsyncListener instances will be notified in the order in which
+ * they were added.
+ *
+ * <p>If {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}
+ * or {@link ServletRequest#startAsync} is called,
+ * the exact same request and response objects are available from the
+ * {@link AsyncEvent} when the {@link AsyncListener} is notified.
+ *
+ * @param listener the AsyncListener to be registered
+ *
+ * @throws IllegalStateException if this method is called after
+ * the container-initiated dispatch, during which one of the
+ * {@link ServletRequest#startAsync} methods was called, has
+ * returned to the container
+ */
+ public void addListener(AsyncListener listener);
+
+
+ /**
+ * Registers the given {@link AsyncListener} with the most recent
+ * asynchronous cycle that was started by a call to one of the
+ * {@link ServletRequest#startAsync} methods.
+ *
+ * <p>The given AsyncListener will receive an {@link AsyncEvent} when
+ * the asynchronous cycle completes successfully, times out, results
+ * in an error, or a new asynchronous cycle is being initiated via
+ * one of the {@link ServletRequest#startAsync} methods.
+ *
+ * <p>AsyncListener instances will be notified in the order in which
+ * they were added.
+ *
+ * <p>The given ServletRequest and ServletResponse objects will
+ * be made available to the given AsyncListener via the
+ * {@link AsyncEvent#getSuppliedRequest getSuppliedRequest} and
+ * {@link AsyncEvent#getSuppliedResponse getSuppliedResponse} methods,
+ * respectively, of the {@link AsyncEvent} delivered to it. These objects
+ * should not be read from or written to, respectively, at the time the
+ * AsyncEvent is delivered, because additional wrapping may have
+ * occurred since the given AsyncListener was registered, but may be used
+ * in order to release any resources associated with them.
+ *
+ * @param listener the AsyncListener to be registered
+ * @param servletRequest the ServletRequest that will be included
+ * in the AsyncEvent
+ * @param servletResponse the ServletResponse that will be included
+ * in the AsyncEvent
+ *
+ * @throws IllegalStateException if this method is called after
+ * the container-initiated dispatch, during which one of the
+ * {@link ServletRequest#startAsync} methods was called, has
+ * returned to the container
+ */
+ public void addListener(AsyncListener listener,
+ ServletRequest servletRequest,
+ ServletResponse servletResponse);
+
+
+ /**
+ * Instantiates the given {@link AsyncListener} class.
+ *
+ * <p>The returned AsyncListener instance may be further customized
+ * before it is registered with this AsyncContext via a call to one of
+ * the <code>addListener</code> methods.
+ *
+ * <p>The given AsyncListener class must define a zero argument
+ * constructor, which is used to instantiate it.
+ *
+ * <p>This method supports resource injection if the given
+ * <tt>clazz</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+
+ * <p>This method supports any annotations applicable to AsyncListener.
+ *
+ * @param <T> the class of the object to instantiate
+ * @param clazz the AsyncListener class to instantiate
+ *
+ * @return the new AsyncListener instance
+ *
+ * @throws ServletException if the given <tt>clazz</tt> fails to be
+ * instantiated
+ */
+ public <T extends AsyncListener> T createListener(Class<T> clazz)
+ throws ServletException;
+
+
+ /**
+ * Sets the timeout (in milliseconds) for this AsyncContext.
+ *
+ * <p>The timeout applies to this AsyncContext once the
+ * container-initiated dispatch during which one of the
+ * {@link ServletRequest#startAsync} methods was called has
+ * returned to the container.
+ *
+ * <p>The timeout will expire if neither the {@link #complete} method
+ * nor any of the dispatch methods are called. A timeout value of
+ * zero or less indicates no timeout.
+ *
+ * <p>If {@link #setTimeout} is not called, then the container's
+ * default timeout, which is available via a call to
+ * {@link #getTimeout}, will apply.
+ *
+ * <p>The default value is <code>30000</code> ms.
+ *
+ * @param timeout the timeout in milliseconds
+ *
+ * @throws IllegalStateException if this method is called after
+ * the container-initiated dispatch, during which one of the
+ * {@link ServletRequest#startAsync} methods was called, has
+ * returned to the container
+ */
+ public void setTimeout(long timeout);
+
+
+ /**
+ * Gets the timeout (in milliseconds) for this AsyncContext.
+ *
+ * <p>This method returns the container's default timeout for
+ * asynchronous operations, or the timeout value passed to the most
+ * recent invocation of {@link #setTimeout}.
+ *
+ * <p>A timeout value of zero or less indicates no timeout.
+ *
+ * @return the timeout in milliseconds
+ */
+ public long getTimeout();
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/AsyncEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/AsyncEvent.java
new file mode 100644
index 0000000..d1739ec
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/AsyncEvent.java
@@ -0,0 +1,166 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+/**
+ * Event that gets fired when the asynchronous operation initiated on a
+ * ServletRequest (via a call to {@link ServletRequest#startAsync} or
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)})
+ * has completed, timed out, or produced an error.
+ *
+ * @since Servlet 3.0
+ */
+public class AsyncEvent {
+
+ private AsyncContext context;
+ private ServletRequest request;
+ private ServletResponse response;
+ private Throwable throwable;
+
+
+ /**
+ * Constructs an AsyncEvent from the given AsyncContext.
+ *
+ * @param context the AsyncContex to be delivered with this AsyncEvent
+ */
+ public AsyncEvent(AsyncContext context) {
+ this(context, context.getRequest(), context.getResponse(), null);
+ }
+
+ /**
+ * Constructs an AsyncEvent from the given AsyncContext, ServletRequest,
+ * and ServletResponse.
+ *
+ * @param context the AsyncContex to be delivered with this AsyncEvent
+ * @param request the ServletRequest to be delivered with this AsyncEvent
+ * @param response the ServletResponse to be delivered with this
+ * AsyncEvent
+ */
+ public AsyncEvent(AsyncContext context, ServletRequest request,
+ ServletResponse response) {
+ this(context, request, response, null);
+ }
+
+ /**
+ * Constructs an AsyncEvent from the given AsyncContext and Throwable.
+ *
+ * @param context the AsyncContex to be delivered with this AsyncEvent
+ * @param throwable the Throwable to be delivered with this AsyncEvent
+ */
+ public AsyncEvent(AsyncContext context, Throwable throwable) {
+ this(context, context.getRequest(), context.getResponse(), throwable);
+ }
+
+ /**
+ * Constructs an AsyncEvent from the given AsyncContext, ServletRequest,
+ * ServletResponse, and Throwable.
+ *
+ * @param context the AsyncContex to be delivered with this AsyncEvent
+ * @param request the ServletRequest to be delivered with this AsyncEvent
+ * @param response the ServletResponse to be delivered with this
+ * AsyncEvent
+ * @param throwable the Throwable to be delivered with this AsyncEvent
+ */
+ public AsyncEvent(AsyncContext context, ServletRequest request,
+ ServletResponse response, Throwable throwable) {
+ this.context = context;
+ this.request = request;
+ this.response = response;
+ this.throwable = throwable;
+ }
+
+ /**
+ * Gets the AsyncContext from this AsyncEvent.
+ *
+ * @return the AsyncContext that was used to initialize this AsyncEvent
+ */
+ public AsyncContext getAsyncContext() {
+ return context;
+ }
+
+ /**
+ * Gets the ServletRequest from this AsyncEvent.
+ *
+ * <p>If the AsyncListener to which this AsyncEvent is being delivered
+ * was added using {@link AsyncContext#addListener(AsyncListener,
+ * ServletRequest, ServletResponse)}, the returned ServletRequest
+ * will be the same as the one supplied to the above method.
+ * If the AsyncListener was added via
+ * {@link AsyncContext#addListener(AsyncListener)}, this method
+ * must return null.
+ *
+ * @return the ServletRequest that was used to initialize this AsyncEvent,
+ * or null if this AsyncEvent was initialized without any ServletRequest
+ */
+ public ServletRequest getSuppliedRequest() {
+ return request;
+ }
+
+ /**
+ * Gets the ServletResponse from this AsyncEvent.
+ *
+ * <p>If the AsyncListener to which this AsyncEvent is being delivered
+ * was added using {@link AsyncContext#addListener(AsyncListener,
+ * ServletRequest, ServletResponse)}, the returned ServletResponse
+ * will be the same as the one supplied to the above method.
+ * If the AsyncListener was added via
+ * {@link AsyncContext#addListener(AsyncListener)}, this method
+ * must return null.
+ *
+ * @return the ServletResponse that was used to initialize this AsyncEvent,
+ * or null if this AsyncEvent was initialized without any ServletResponse
+ */
+ public ServletResponse getSuppliedResponse() {
+ return response;
+ }
+
+ /**
+ * Gets the Throwable from this AsyncEvent.
+ *
+ * @return the Throwable that was used to initialize this AsyncEvent,
+ * or null if this AsyncEvent was initialized without any Throwable
+ */
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/AsyncListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/AsyncListener.java
new file mode 100644
index 0000000..ebe6cb3
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/AsyncListener.java
@@ -0,0 +1,164 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.util.EventListener;
+
+/**
+ * Listener that will be notified in the event that an asynchronous
+ * operation initiated on a ServletRequest to which the listener had been
+ * added has completed, timed out, or resulted in an error.
+ *
+ * @since Servlet 3.0
+ */
+public interface AsyncListener extends EventListener {
+
+ /**
+ * Notifies this AsyncListener that an asynchronous operation
+ * has been completed.
+ *
+ * <p>The {@link AsyncContext} corresponding to the asynchronous
+ * operation that has been completed may be obtained by calling
+ * {@link AsyncEvent#getAsyncContext getAsyncContext} on the given
+ * <tt>event</tt>.
+ *
+ * <p>In addition, if this AsyncListener had been registered via a call
+ * to {@link AsyncContext#addListener(AsyncListener,
+ * ServletRequest, ServletResponse)}, the supplied ServletRequest and
+ * ServletResponse objects may be retrieved by calling
+ * {@link AsyncEvent#getSuppliedRequest getSuppliedRequest} and
+ * {@link AsyncEvent#getSuppliedResponse getSuppliedResponse},
+ * respectively, on the given <tt>event</tt>.
+ *
+ * @param event the AsyncEvent indicating that an asynchronous
+ * operation has been completed
+ *
+ * @throws IOException if an I/O related error has occurred during the
+ * processing of the given AsyncEvent
+ */
+ public void onComplete(AsyncEvent event) throws IOException;
+
+
+ /**
+ * Notifies this AsyncListener that an asynchronous operation
+ * has timed out.
+ *
+ * <p>The {@link AsyncContext} corresponding to the asynchronous
+ * operation that has timed out may be obtained by calling
+ * {@link AsyncEvent#getAsyncContext getAsyncContext} on the given
+ * <tt>event</tt>.
+ *
+ * <p>In addition, if this AsyncListener had been registered via a call
+ * to {@link AsyncContext#addListener(AsyncListener,
+ * ServletRequest, ServletResponse)}, the supplied ServletRequest and
+ * ServletResponse objects may be retrieved by calling
+ * {@link AsyncEvent#getSuppliedRequest getSuppliedRequest} and
+ * {@link AsyncEvent#getSuppliedResponse getSuppliedResponse},
+ * respectively, on the given <tt>event</tt>.
+ *
+ * @param event the AsyncEvent indicating that an asynchronous
+ * operation has timed out
+ *
+ * @throws IOException if an I/O related error has occurred during the
+ * processing of the given AsyncEvent
+ */
+ public void onTimeout(AsyncEvent event) throws IOException;
+
+
+ /**
+ * Notifies this AsyncListener that an asynchronous operation
+ * has failed to complete.
+ *
+ * <p>The {@link AsyncContext} corresponding to the asynchronous
+ * operation that failed to complete may be obtained by calling
+ * {@link AsyncEvent#getAsyncContext getAsyncContext} on the given
+ * <tt>event</tt>.
+ *
+ * <p>In addition, if this AsyncListener had been registered via a call
+ * to {@link AsyncContext#addListener(AsyncListener,
+ * ServletRequest, ServletResponse)}, the supplied ServletRequest and
+ * ServletResponse objects may be retrieved by calling
+ * {@link AsyncEvent#getSuppliedRequest getSuppliedRequest} and
+ * {@link AsyncEvent#getSuppliedResponse getSuppliedResponse},
+ * respectively, on the given <tt>event</tt>.
+ *
+ * @param event the AsyncEvent indicating that an asynchronous
+ * operation has failed to complete
+ *
+ * @throws IOException if an I/O related error has occurred during the
+ * processing of the given AsyncEvent
+ */
+ public void onError(AsyncEvent event) throws IOException;
+
+
+ /**
+ * Notifies this AsyncListener that a new asynchronous cycle is being
+ * initiated via a call to one of the {@link ServletRequest#startAsync}
+ * methods.
+ *
+ * <p>The {@link AsyncContext} corresponding to the asynchronous
+ * operation that is being reinitialized may be obtained by calling
+ * {@link AsyncEvent#getAsyncContext getAsyncContext} on the given
+ * <tt>event</tt>.
+ *
+ * <p>In addition, if this AsyncListener had been registered via a call
+ * to {@link AsyncContext#addListener(AsyncListener,
+ * ServletRequest, ServletResponse)}, the supplied ServletRequest and
+ * ServletResponse objects may be retrieved by calling
+ * {@link AsyncEvent#getSuppliedRequest getSuppliedRequest} and
+ * {@link AsyncEvent#getSuppliedResponse getSuppliedResponse},
+ * respectively, on the given <tt>event</tt>.
+ *
+ * <p>This AsyncListener will not receive any events related to the
+ * new asynchronous cycle unless it registers itself (via a call
+ * to {@link AsyncContext#addListener}) with the AsyncContext that
+ * is delivered as part of the given AsyncEvent.
+ *
+ * @param event the AsyncEvent indicating that a new asynchronous
+ * cycle is being initiated
+ *
+ * @throws IOException if an I/O related error has occurred during the
+ * processing of the given AsyncEvent
+ */
+ public void onStartAsync(AsyncEvent event) throws IOException;
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/DispatcherType.java b/third_party/servlet-spec/src/main/java/javax/servlet/DispatcherType.java
new file mode 100644
index 0000000..65d1b18
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/DispatcherType.java
@@ -0,0 +1,54 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+/**
+ * Enumeration of filter dispatcher types.
+ *
+ * @since Servlet 3.0
+ */
+public enum DispatcherType {
+ FORWARD,
+ INCLUDE,
+ REQUEST,
+ ASYNC,
+ ERROR
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/Filter.java b/third_party/servlet-spec/src/main/java/javax/servlet/Filter.java
new file mode 100644
index 0000000..7f67f46
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/Filter.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+
+/**
+ * <p>A filter is an object that performs
+ * filtering tasks on either the request to a resource (a servlet or static content), or on the response
+ * from a resource, or both.</p>
+ *
+ * <p>Filters perform filtering in the <code>doFilter</code> method.
+ * Every Filter has access to a FilterConfig object from which it can obtain
+ * its initialization parameters, and a reference to the ServletContext which
+ * it can use, for example, to load resources needed for filtering tasks.
+ *
+ * <p>Filters are configured in the deployment descriptor of a web
+ * application.
+ *
+ * <p>Examples that have been identified for this design are:
+ * <ol>
+ * <li>Authentication Filters
+ * <li>Logging and Auditing Filters
+ * <li>Image conversion Filters
+ * <li>Data compression Filters
+ * <li>Encryption Filters
+ * <li>Tokenizing Filters
+ * <li>Filters that trigger resource access events
+ * <li>XSL/T filters
+ * <li>Mime-type chain Filter
+ * </ol>
+ *
+ * @since Servlet 2.3
+ */
+
+public interface Filter {
+
+ /**
+ * <p>Called by the web container
+ * to indicate to a filter that it is being placed into service.</p>
+ *
+ * <p>The servlet container calls the init
+ * method exactly once after instantiating the filter. The init
+ * method must complete successfully before the filter is asked to do any
+ * filtering work.</p>
+ *
+ * <p>The web container cannot place the filter into service if the init
+ * method either</p>
+ * <ol>
+ * <li>Throws a ServletException
+ * <li>Does not return within a time period defined by the web container
+ * </ol>
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param filterConfig a <code>FilterConfig</code> object containing the
+ * filter's configuration and initialization parameters
+ * @throws ServletException if an exception has occurred that interferes with
+ * the filter's normal operation
+ */
+ default public void init(FilterConfig filterConfig) throws ServletException {}
+
+
+ /**
+ * The <code>doFilter</code> method of the Filter is called by the
+ * container each time a request/response pair is passed through the
+ * chain due to a client request for a resource at the end of the chain.
+ * The FilterChain passed in to this method allows the Filter to pass
+ * on the request and response to the next entity in the chain.
+ *
+ * <p>A typical implementation of this method would follow the following
+ * pattern:
+ * <ol>
+ * <li>Examine the request
+ * <li>Optionally wrap the request object with a custom implementation to
+ * filter content or headers for input filtering
+ * <li>Optionally wrap the response object with a custom implementation to
+ * filter content or headers for output filtering
+ * <li>
+ * <ul>
+ * <li><strong>Either</strong> invoke the next entity in the chain
+ * using the FilterChain object
+ * (<code>chain.doFilter()</code>),
+ * <li><strong>or</strong> not pass on the request/response pair to
+ * the next entity in the filter chain to
+ * block the request processing
+ * </ul>
+ * <li>Directly set headers on the response after invocation of the
+ * next entity in the filter chain.
+ * </ol>
+ *
+ * @param request the <code>ServletRequest</code> object contains the client's request
+ * @param response the <code>ServletResponse</code> object contains the filter's response
+ * @param chain the <code>FilterChain</code> for invoking the next filter or the resource
+ * @throws IOException if an I/O related error has occurred during the processing
+ * @throws ServletException if an exception occurs that interferes with the
+ * filter's normal operation
+ *
+ * @see UnavailableException
+ */
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain)
+ throws IOException, ServletException;
+
+
+ /**
+ * <p>Called by the web container
+ * to indicate to a filter that it is being
+ * taken out of service.</p>
+ *
+ * <p>This method is only called once all threads within the filter's
+ * doFilter method have exited or after a timeout period has passed.
+ * After the web container calls this method, it will not call the
+ * doFilter method again on this instance of the filter.</p>
+ *
+ * <p>This method gives the filter an opportunity to clean up any
+ * resources that are being held (for example, memory, file handles,
+ * threads) and make sure that any persistent state is synchronized
+ * with the filter's current state in memory.</p>
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void destroy() {}
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/FilterChain.java b/third_party/servlet-spec/src/main/java/javax/servlet/FilterChain.java
new file mode 100644
index 0000000..cefe387
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/FilterChain.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+
+ /**
+ * A FilterChain is an object provided by the servlet container to the developer
+ * giving a view into the invocation chain of a filtered request for a resource. Filters
+ * use the FilterChain to invoke the next filter in the chain, or if the calling filter
+ * is the last filter in the chain, to invoke the resource at the end of the chain.
+ *
+ * @see Filter
+ * @since Servlet 2.3
+ */
+
+public interface FilterChain {
+
+ /**
+ * Causes the next filter in the chain to be invoked, or if the calling filter is the last filter
+ * in the chain, causes the resource at the end of the chain to be invoked.
+ *
+ * @param request the request to pass along the chain.
+ * @param response the response to pass along the chain.
+ * @throws IOException if an I/O related error has occurred during the processing
+ * @throws ServletException if an exception has occurred that interferes with the
+ * filterChain's normal operation
+ */
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/FilterConfig.java b/third_party/servlet-spec/src/main/java/javax/servlet/FilterConfig.java
new file mode 100644
index 0000000..95ce0a1
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/FilterConfig.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.util.Enumeration;
+
+/**
+ * A filter configuration object used by a servlet container
+ * to pass information to a filter during initialization.
+ *
+ * @see Filter
+ * @since Servlet 2.3
+ */
+public interface FilterConfig {
+
+ /**
+ * Returns the filter-name of this filter as defined in the deployment
+ * descriptor.
+ *
+ * @return the filter name of this filter
+ */
+ public String getFilterName();
+
+
+ /**
+ * Returns a reference to the {@link ServletContext} in which the caller
+ * is executing.
+ *
+ * @return a {@link ServletContext} object, used by the caller to
+ * interact with its servlet container
+ *
+ * @see ServletContext
+ */
+ public ServletContext getServletContext();
+
+
+ /**
+ * Returns a <code>String</code> containing the value of the
+ * named initialization parameter, or <code>null</code> if
+ * the initialization parameter does not exist.
+ *
+ * @param name a <code>String</code> specifying the name of the
+ * initialization parameter
+ *
+ * @return a <code>String</code> containing the value of the
+ * initialization parameter, or <code>null</code> if
+ * the initialization parameter does not exist
+ */
+ public String getInitParameter(String name);
+
+
+ /**
+ * Returns the names of the filter's initialization parameters
+ * as an <code>Enumeration</code> of <code>String</code> objects,
+ * or an empty <code>Enumeration</code> if the filter has
+ * no initialization parameters.
+ *
+ * @return an <code>Enumeration</code> of <code>String</code> objects
+ * containing the names of the filter's initialization parameters
+ */
+ public Enumeration<String> getInitParameterNames();
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/FilterRegistration.java b/third_party/servlet-spec/src/main/java/javax/servlet/FilterRegistration.java
new file mode 100644
index 0000000..99c95b9
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/FilterRegistration.java
@@ -0,0 +1,150 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.util.*;
+
+/**
+ * Interface through which a {@link Filter} may be further configured.
+ *
+ * @since Servlet 3.0
+ */
+public interface FilterRegistration extends Registration {
+
+ /**
+ * Adds a filter mapping with the given servlet names and dispatcher
+ * types for the Filter represented by this FilterRegistration.
+ *
+ * <p>Filter mappings are matched in the order in which they were
+ * added.
+ *
+ * <p>Depending on the value of the <tt>isMatchAfter</tt> parameter, the
+ * given filter mapping will be considered after or before any
+ * <i>declared</i> filter mappings of the ServletContext from which this
+ * FilterRegistration was obtained.
+ *
+ * <p>If this method is called multiple times, each successive call
+ * adds to the effects of the former.
+ *
+ * @param dispatcherTypes the dispatcher types of the filter mapping,
+ * or null if the default <tt>DispatcherType.REQUEST</tt> is to be used
+ * @param isMatchAfter true if the given filter mapping should be matched
+ * after any declared filter mappings, and false if it is supposed to
+ * be matched before any declared filter mappings of the ServletContext
+ * from which this FilterRegistration was obtained
+ * @param servletNames the servlet names of the filter mapping
+ *
+ * @throws IllegalArgumentException if <tt>servletNames</tt> is null or
+ * empty
+ * @throws IllegalStateException if the ServletContext from which this
+ * FilterRegistration was obtained has already been initialized
+ */
+ public void addMappingForServletNames(
+ EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
+ String... servletNames);
+
+ /**
+ * Gets the currently available servlet name mappings
+ * of the Filter represented by this <code>FilterRegistration</code>.
+ *
+ * <p>If permitted, any changes to the returned <code>Collection</code> must not
+ * affect this <code>FilterRegistration</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the currently
+ * available servlet name mappings of the Filter represented by this
+ * <code>FilterRegistration</code>
+ */
+ public Collection<String> getServletNameMappings();
+
+ /**
+ * Adds a filter mapping with the given url patterns and dispatcher
+ * types for the Filter represented by this FilterRegistration.
+ *
+ * <p>Filter mappings are matched in the order in which they were
+ * added.
+ *
+ * <p>Depending on the value of the <tt>isMatchAfter</tt> parameter, the
+ * given filter mapping will be considered after or before any
+ * <i>declared</i> filter mappings of the ServletContext from which
+ * this FilterRegistration was obtained.
+ *
+ * <p>If this method is called multiple times, each successive call
+ * adds to the effects of the former.
+ *
+ * @param dispatcherTypes the dispatcher types of the filter mapping,
+ * or null if the default <tt>DispatcherType.REQUEST</tt> is to be used
+ * @param isMatchAfter true if the given filter mapping should be matched
+ * after any declared filter mappings, and false if it is supposed to
+ * be matched before any declared filter mappings of the ServletContext
+ * from which this FilterRegistration was obtained
+ * @param urlPatterns the url patterns of the filter mapping
+ *
+ * @throws IllegalArgumentException if <tt>urlPatterns</tt> is null or
+ * empty
+ * @throws IllegalStateException if the ServletContext from which this
+ * FilterRegistration was obtained has already been initialized
+ */
+ public void addMappingForUrlPatterns(
+ EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
+ String... urlPatterns);
+
+ /**
+ * Gets the currently available URL pattern mappings of the Filter
+ * represented by this <code>FilterRegistration</code>.
+ *
+ * <p>If permitted, any changes to the returned <code>Collection</code> must not
+ * affect this <code>FilterRegistration</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the currently
+ * available URL pattern mappings of the Filter represented by this
+ * <code>FilterRegistration</code>
+ */
+ public Collection<String> getUrlPatternMappings();
+
+ /**
+ * Interface through which a {@link Filter} registered via one of the
+ * <tt>addFilter</tt> methods on {@link ServletContext} may be further
+ * configured.
+ */
+ interface Dynamic extends FilterRegistration, Registration.Dynamic {
+ }
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/GenericFilter.java b/third_party/servlet-spec/src/main/java/javax/servlet/GenericFilter.java
new file mode 100644
index 0000000..02e1e0f
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/GenericFilter.java
@@ -0,0 +1,254 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+
+/**
+ *
+ * <p>Defines a generic, protocol-independent
+ * filter. To write an HTTP filter for use on the
+ * Web, extend {@link javax.servlet.http.HttpFilter} instead.</p>
+ *
+ * <p><code>GenericFilter</code> implements the <code>Filter</code>
+ * and <code>FilterConfig</code> interfaces. <code>GenericFilter</code>
+ * may be directly extended by a filter, although it's more common to extend
+ * a protocol-specific subclass such as <code>HttpFilter</code>.
+ *
+ * <p><code>GenericFilter</code> makes writing filters
+ * easier. It provides simple versions of the lifecycle methods
+ * <code>init</code> and <code>destroy</code> and of the methods
+ * in the <code>FilterConfig</code> interface.
+ *
+ * <p>To write a generic filter, you need only
+ * override the abstract <code>doFilter</code> method.
+ *
+ * @author Various
+ *
+ * @since Servlet 4.0
+ */
+
+
+public abstract class GenericFilter
+ implements Filter, FilterConfig, java.io.Serializable
+{
+ private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
+ private static final ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+ private transient FilterConfig config;
+
+
+ /**
+ *
+ * <p>Does nothing. All of the filter initialization
+ * is done by one of the <code>init</code> methods.</p>
+ *
+ * @since Servlet 4.0
+ */
+ public GenericFilter() { }
+
+
+ /**
+ * <p>Returns a <code>String</code> containing the value of the named
+ * initialization parameter, or <code>null</code> if the parameter does
+ * not exist. See {@link FilterConfig#getInitParameter}.</p>
+ *
+ * <p>This method is supplied for convenience. It gets the
+ * value of the named parameter from the servlet's
+ * <code>ServletConfig</code> object.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of the initialization parameter
+ *
+ * @return String a <code>String</code> containing the value
+ * of the initialization parameter
+ *
+ * @since Servlet 4.0
+ *
+ */
+ @Override
+ public String getInitParameter(String name) {
+ FilterConfig fc = getFilterConfig();
+ if (fc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.filter_config_not_initialized"));
+ }
+
+ return fc.getInitParameter(name);
+ }
+
+
+ /**
+ * <p>Returns the names of the filter's initialization parameters
+ * as an <code>Enumeration</code> of <code>String</code> objects,
+ * or an empty <code>Enumeration</code> if the filter has no
+ * initialization parameters. See {@link
+ * FilterConfig#getInitParameterNames}.</p>
+ *
+ * <p>This method is supplied for convenience. It gets the
+ * parameter names from the filter's <code>FilterConfig</code> object.
+ *
+ * @return Enumeration an enumeration of <code>String</code>
+ * objects containing the names of
+ * the filter's initialization parameters
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ FilterConfig fc = getFilterConfig();
+ if (fc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.filter_config_not_initialized"));
+ }
+
+ return fc.getInitParameterNames();
+ }
+
+
+ /**
+ * <p>Returns this servlet's {@link ServletConfig} object.</p>
+ *
+ * @return FilterConfig the <code>FilterConfig</code> object
+ * that initialized this filter
+ *
+ * @since Servlet 4.0
+ */
+ public FilterConfig getFilterConfig() {
+ return config;
+ }
+
+
+ /**
+ * <p>Returns a reference to the {@link ServletContext} in which this filter
+ * is running. See {@link FilterConfig#getServletContext}.</p>
+ *
+ * <p>This method is supplied for convenience. It gets the
+ * context from the filter's <code>FilterConfig</code> object.
+ *
+ * @return ServletContext the <code>ServletContext</code> object
+ * passed to this filter by the <code>init</code>
+ * method
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public ServletContext getServletContext() {
+ FilterConfig sc = getFilterConfig();
+ if (sc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.filter_config_not_initialized"));
+ }
+
+ return sc.getServletContext();
+ }
+
+
+ /**
+ * <p>Called by the servlet container to indicate to a filter that
+ * it is being placed into service. See {@link Filter#init}.</p>
+ *
+ * <p>This implementation stores the {@link FilterConfig}
+ * object it receives from the servlet container for later use.
+ * When overriding this form of the method, call
+ * <code>super.init(config)</code>.
+ *
+ * @param config the <code>FilterConfig</code> object
+ * that contains configuration
+ * information for this filter
+ *
+ * @exception ServletException if an exception occurs that
+ * interrupts the servlet's normal
+ * operation
+ *
+ * @see UnavailableException
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public void init(FilterConfig config) throws ServletException {
+ this.config = config;
+ this.init();
+ }
+
+ /**
+ * <p>A convenience method which can be overridden so that there's no need
+ * to call <code>super.init(config)</code>.</p>
+ *
+ * <p>Instead of overriding {@link #init(FilterConfig)}, simply override
+ * this method and it will be called by
+ * <code>GenericFilter.init(FilterConfig config)</code>.
+ * The <code>FilterConfig</code> object can still be retrieved via {@link
+ * #getFilterConfig}.
+ *
+ * @exception ServletException if an exception occurs that
+ * interrupts the servlet's
+ * normal operation
+ *
+ * @since Servlet 4.0
+ */
+ public void init() throws ServletException {
+
+ }
+
+
+ /**
+ * <p>Returns the name of this filter instance.
+ * See {@link FilterConfig#getFilterName}.</p>
+ *
+ * @return the name of this filter instance
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public String getFilterName() {
+ FilterConfig sc = getFilterConfig();
+ if (sc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.servlet_config_not_initialized"));
+ }
+
+ return sc.getFilterName();
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/GenericServlet.java b/third_party/servlet-spec/src/main/java/javax/servlet/GenericServlet.java
new file mode 100644
index 0000000..4a51a5b
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/GenericServlet.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+
+/**
+ *
+ * Defines a generic, protocol-independent
+ * servlet. To write an HTTP servlet for use on the
+ * Web, extend {@link javax.servlet.http.HttpServlet} instead.
+ *
+ * <p><code>GenericServlet</code> implements the <code>Servlet</code>
+ * and <code>ServletConfig</code> interfaces. <code>GenericServlet</code>
+ * may be directly extended by a servlet, although it's more common to extend
+ * a protocol-specific subclass such as <code>HttpServlet</code>.
+ *
+ * <p><code>GenericServlet</code> makes writing servlets
+ * easier. It provides simple versions of the lifecycle methods
+ * <code>init</code> and <code>destroy</code> and of the methods
+ * in the <code>ServletConfig</code> interface. <code>GenericServlet</code>
+ * also implements the <code>log</code> method, declared in the
+ * <code>ServletContext</code> interface.
+ *
+ * <p>To write a generic servlet, you need only
+ * override the abstract <code>service</code> method.
+ *
+ *
+ * @author Various
+ */
+
+
+public abstract class GenericServlet
+ implements Servlet, ServletConfig, java.io.Serializable
+{
+ private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+ private transient ServletConfig config;
+
+
+ /**
+ *
+ * Does nothing. All of the servlet initialization
+ * is done by one of the <code>init</code> methods.
+ *
+ */
+ public GenericServlet() { }
+
+
+ /**
+ * Called by the servlet container to indicate to a servlet that the
+ * servlet is being taken out of service. See {@link Servlet#destroy}.
+ *
+ *
+ */
+ public void destroy() {
+ }
+
+
+ /**
+ * Returns a <code>String</code> containing the value of the named
+ * initialization parameter, or <code>null</code> if the parameter does
+ * not exist. See {@link ServletConfig#getInitParameter}.
+ *
+ * <p>This method is supplied for convenience. It gets the
+ * value of the named parameter from the servlet's
+ * <code>ServletConfig</code> object.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of the initialization parameter
+ *
+ * @return String a <code>String</code> containing the value
+ * of the initialization parameter
+ *
+ */
+ public String getInitParameter(String name) {
+ ServletConfig sc = getServletConfig();
+ if (sc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.servlet_config_not_initialized"));
+ }
+
+ return sc.getInitParameter(name);
+ }
+
+
+ /**
+ * Returns the names of the servlet's initialization parameters
+ * as an <code>Enumeration</code> of <code>String</code> objects,
+ * or an empty <code>Enumeration</code> if the servlet has no
+ * initialization parameters. See {@link
+ * ServletConfig#getInitParameterNames}.
+ *
+ * <p>This method is supplied for convenience. It gets the
+ * parameter names from the servlet's <code>ServletConfig</code> object.
+ *
+ *
+ * @return Enumeration an enumeration of <code>String</code>
+ * objects containing the names of
+ * the servlet's initialization parameters
+ */
+ public Enumeration<String> getInitParameterNames() {
+ ServletConfig sc = getServletConfig();
+ if (sc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.servlet_config_not_initialized"));
+ }
+
+ return sc.getInitParameterNames();
+ }
+
+
+ /**
+ * Returns this servlet's {@link ServletConfig} object.
+ *
+ * @return ServletConfig the <code>ServletConfig</code> object
+ * that initialized this servlet
+ */
+ public ServletConfig getServletConfig() {
+ return config;
+ }
+
+
+ /**
+ * Returns a reference to the {@link ServletContext} in which this servlet
+ * is running. See {@link ServletConfig#getServletContext}.
+ *
+ * <p>This method is supplied for convenience. It gets the
+ * context from the servlet's <code>ServletConfig</code> object.
+ *
+ *
+ * @return ServletContext the <code>ServletContext</code> object
+ * passed to this servlet by the <code>init</code>
+ * method
+ */
+ public ServletContext getServletContext() {
+ ServletConfig sc = getServletConfig();
+ if (sc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.servlet_config_not_initialized"));
+ }
+
+ return sc.getServletContext();
+ }
+
+
+ /**
+ * Returns information about the servlet, such as
+ * author, version, and copyright.
+ * By default, this method returns an empty string. Override this method
+ * to have it return a meaningful value. See {@link
+ * Servlet#getServletInfo}.
+ *
+ *
+ * @return String information about this servlet, by default an
+ * empty string
+ */
+ public String getServletInfo() {
+ return "";
+ }
+
+
+ /**
+ * Called by the servlet container to indicate to a servlet that the
+ * servlet is being placed into service. See {@link Servlet#init}.
+ *
+ * <p>This implementation stores the {@link ServletConfig}
+ * object it receives from the servlet container for later use.
+ * When overriding this form of the method, call
+ * <code>super.init(config)</code>.
+ *
+ * @param config the <code>ServletConfig</code> object
+ * that contains configuration
+ * information for this servlet
+ *
+ * @exception ServletException if an exception occurs that
+ * interrupts the servlet's normal
+ * operation
+ *
+ * @see UnavailableException
+ */
+ public void init(ServletConfig config) throws ServletException {
+ this.config = config;
+ this.init();
+ }
+
+
+ /**
+ * A convenience method which can be overridden so that there's no need
+ * to call <code>super.init(config)</code>.
+ *
+ * <p>Instead of overriding {@link #init(ServletConfig)}, simply override
+ * this method and it will be called by
+ * <code>GenericServlet.init(ServletConfig config)</code>.
+ * The <code>ServletConfig</code> object can still be retrieved via {@link
+ * #getServletConfig}.
+ *
+ * @exception ServletException if an exception occurs that
+ * interrupts the servlet's
+ * normal operation
+ */
+ public void init() throws ServletException {
+
+ }
+
+
+ /**
+ * Writes the specified message to a servlet log file, prepended by the
+ * servlet's name. See {@link ServletContext#log(String)}.
+ *
+ * @param msg a <code>String</code> specifying
+ * the message to be written to the log file
+ */
+ public void log(String msg) {
+ getServletContext().log(getServletName() + ": "+ msg);
+ }
+
+
+ /**
+ * Writes an explanatory message and a stack trace
+ * for a given <code>Throwable</code> exception
+ * to the servlet log file, prepended by the servlet's name.
+ * See {@link ServletContext#log(String, Throwable)}.
+ *
+ *
+ * @param message a <code>String</code> that describes
+ * the error or exception
+ *
+ * @param t the <code>java.lang.Throwable</code> error
+ * or exception
+ */
+ public void log(String message, Throwable t) {
+ getServletContext().log(getServletName() + ": " + message, t);
+ }
+
+
+ /**
+ * Called by the servlet container to allow the servlet to respond to
+ * a request. See {@link Servlet#service}.
+ *
+ * <p>This method is declared abstract so subclasses, such as
+ * <code>HttpServlet</code>, must override it.
+ *
+ * @param req the <code>ServletRequest</code> object
+ * that contains the client's request
+ *
+ * @param res the <code>ServletResponse</code> object
+ * that will contain the servlet's response
+ *
+ * @exception ServletException if an exception occurs that
+ * interferes with the servlet's
+ * normal operation occurred
+ *
+ * @exception IOException if an input or output
+ * exception occurs
+ */
+
+ public abstract void service(ServletRequest req, ServletResponse res)
+ throws ServletException, IOException;
+
+
+ /**
+ * Returns the name of this servlet instance.
+ * See {@link ServletConfig#getServletName}.
+ *
+ * @return the name of this servlet instance
+ */
+ public String getServletName() {
+ ServletConfig sc = getServletConfig();
+ if (sc == null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.servlet_config_not_initialized"));
+ }
+
+ return sc.getServletName();
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/HttpConstraintElement.java b/third_party/servlet-spec/src/main/java/javax/servlet/HttpConstraintElement.java
new file mode 100644
index 0000000..47763a4
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/HttpConstraintElement.java
@@ -0,0 +1,172 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.util.*;
+import javax.servlet.annotation.HttpConstraint;
+import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
+import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
+
+/**
+ * Java Class representation of an {@link HttpConstraint} annotation value.
+ *
+ * @since Servlet 3.0
+ */
+public class HttpConstraintElement {
+
+ private EmptyRoleSemantic emptyRoleSemantic;
+ private TransportGuarantee transportGuarantee;
+ private String[] rolesAllowed;
+
+ /**
+ * Constructs a default HTTP constraint element
+ */
+ public HttpConstraintElement() {
+ this(EmptyRoleSemantic.PERMIT);
+ }
+
+ /**
+ * Convenience constructor to establish <tt>EmptyRoleSemantic.DENY</tt>
+ *
+ * @param semantic should be EmptyRoleSemantic.DENY
+ */
+ public HttpConstraintElement(EmptyRoleSemantic semantic) {
+ this(semantic, TransportGuarantee.NONE, new String[0]);
+ }
+
+ /**
+ * Constructor to establish non-empty getRolesAllowed and/or
+ * <tt>TransportGuarantee.CONFIDENTIAL</tt>.
+ *
+ * @param guarantee <tt>TransportGuarantee.NONE</tt> or
+ * <tt>TransportGuarantee.CONFIDENTIAL</tt>
+ * @param roleNames the names of the roles that are to be
+ * allowed access
+ */
+ public HttpConstraintElement(TransportGuarantee guarantee,
+ String... roleNames) {
+ this(EmptyRoleSemantic.PERMIT, guarantee, roleNames);
+ }
+
+ /**
+ * Constructor to establish all of getEmptyRoleSemantic,
+ * getRolesAllowed, and getTransportGuarantee.
+ *
+ * @param semantic <tt>EmptyRoleSemantic.DENY</tt> or
+ * <tt>EmptyRoleSemantic.PERMIT</tt>
+ * @param guarantee <tt>TransportGuarantee.NONE</tt> or
+ * <tt>TransportGuarantee.CONFIDENTIAL</tt>
+ * @param roleNames the names of the roles that are to be allowed
+ * access, or missing if the semantic is <tt>EmptyRoleSemantic.DENY</tt>
+ */
+ public HttpConstraintElement(EmptyRoleSemantic semantic,
+ TransportGuarantee guarantee, String... roleNames) {
+ if (semantic == EmptyRoleSemantic.DENY && roleNames.length > 0) {
+ throw new IllegalArgumentException(
+ "Deny semantic with rolesAllowed");
+ }
+ this.emptyRoleSemantic = semantic;
+ this.transportGuarantee = guarantee;
+ this.rolesAllowed = copyStrings(roleNames);
+ }
+
+ /**
+ * Gets the default authorization semantic.
+ *
+ * <p>This value is insignificant when <code>getRolesAllowed</code>
+ * returns a non-empty array, and should not be specified when a
+ * non-empty array is specified for <tt>getRolesAllowed</tt>.
+ *
+ * @return the {@link EmptyRoleSemantic} to be applied when
+ * <code>getRolesAllowed</code> returns an empty (that is, zero-length)
+ * array
+ */
+ public EmptyRoleSemantic getEmptyRoleSemantic() {
+ return this.emptyRoleSemantic;
+ }
+
+ /**
+ * Gets the data protection requirement (i.e., whether or not SSL/TLS is
+ * required) that must be satisfied by the transport connection.
+ *
+ * @return the {@link TransportGuarantee} indicating the data
+ * protection that must be provided by the connection
+ */
+ public TransportGuarantee getTransportGuarantee() {
+ return this.transportGuarantee;
+ }
+
+ /**
+ * Gets the names of the authorized roles.
+ *
+ * <p>Duplicate role names appearing in getRolesAllowed are insignificant
+ * and may be discarded. The String <tt>"*"</tt> has no special meaning
+ * as a role name (should it occur in getRolesAllowed).
+ *
+ * @return a (possibly empty) array of role names. When the
+ * array is empty, its meaning depends on the value of
+ * {@link #getEmptyRoleSemantic}. If its value is <tt>DENY</tt>,
+ * and <code>getRolesAllowed</code> returns an empty array,
+ * access is to be denied independent of authentication state and
+ * identity. Conversely, if its value is <code>PERMIT</code>, it
+ * indicates that access is to be allowed independent of authentication
+ * state and identity. When the array contains the names of one or
+ * more roles, it indicates that access is contingent on membership in at
+ * least one of the named roles (independent of the value of
+ * {@link #getEmptyRoleSemantic}).
+ */
+ public String[] getRolesAllowed() {
+ return copyStrings(this.rolesAllowed);
+ }
+
+ private String[] copyStrings(String[] strings) {
+ String[] arr = null;
+ if (strings != null) {
+ int len = strings.length;
+ arr = new String[len];
+ if (len > 0) {
+ System.arraycopy(strings, 0, arr, 0, len);
+ }
+ }
+
+ return ((arr != null) ? arr : new String[0]);
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/HttpMethodConstraintElement.java b/third_party/servlet-spec/src/main/java/javax/servlet/HttpMethodConstraintElement.java
new file mode 100644
index 0000000..17bd88b
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/HttpMethodConstraintElement.java
@@ -0,0 +1,98 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import javax.servlet.annotation.HttpMethodConstraint;
+
+/**
+ * Java Class represntation of an {@link HttpMethodConstraint} annotation value.
+ *
+ * @since Servlet 3.0
+ */
+public class HttpMethodConstraintElement extends HttpConstraintElement {
+
+ private String methodName;
+
+ /**
+ * Constructs an instance with default {@link HttpConstraintElement}
+ * value.
+ *
+ * @param methodName the name of an HTTP protocol method. The name must
+ * not be null, or the empty string, and must be a legitimate HTTP
+ * Method name as defined by RFC 2616
+ */
+ public HttpMethodConstraintElement(String methodName) {
+ if (methodName == null || methodName.length() == 0) {
+ throw new IllegalArgumentException("invalid HTTP method name");
+ }
+ this.methodName = methodName;
+ }
+ /**
+ * Constructs an instance with specified {@link HttpConstraintElement}
+ * value.
+ *
+ * @param methodName the name of an HTTP protocol method. The name must
+ * not be null, or the empty string, and must be a legitimate HTTP
+ * Method name as defined by RFC 2616
+ *
+ * @param constraint the HTTPconstraintElement value to assign to the
+ * named HTTP method
+ */
+ public HttpMethodConstraintElement(String methodName,
+ HttpConstraintElement constraint) {
+ super(constraint.getEmptyRoleSemantic(),
+ constraint.getTransportGuarantee(),
+ constraint.getRolesAllowed());
+ if (methodName == null || methodName.length() == 0) {
+ throw new IllegalArgumentException("invalid HTTP method name");
+ }
+ this.methodName = methodName;
+ }
+
+ /**
+ * Gets the HTTP method name.
+ *
+ * @return the Http method name
+ */
+ public String getMethodName() {
+ return this.methodName;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings.properties b/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings.properties
new file mode 100644
index 0000000..7a478e0
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# Default localized string information
+# Localized for Locale en_US
+
+err.not_iso8859_1=Not an ISO 8859-1 character: {0}
+err.servlet_config_not_initialized=ServletConfig has not been initialized
+value.true=true
+value.false=false
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings_fr.properties b/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings_fr.properties
new file mode 100644
index 0000000..af9a2f0
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings_fr.properties
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# Default localized string information
+# Localized for Locale fr_FR
+
+err.not_iso8859_1={0} n''est pas un caractère ISO 8859-1
+value.true=true
+value.false=false
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings_ja.properties b/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings_ja.properties
new file mode 100644
index 0000000..7d55785
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/LocalStrings_ja.properties
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# Default localized string information
+# Localized for Locale ja_JP
+
+err.not_iso8859_1=ISO 8859-1 \u306e\u6587\u5b57\u3067\u306f\u3042\u308a\u307e\u305b\u3093: {0}
+value.true=true
+value.false=false
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/MultipartConfigElement.java b/third_party/servlet-spec/src/main/java/javax/servlet/MultipartConfigElement.java
new file mode 100644
index 0000000..dd36f82
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/MultipartConfigElement.java
@@ -0,0 +1,142 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import javax.servlet.annotation.MultipartConfig;
+
+/**
+ * Java Class represntation of an {@link MultipartConfig} annotation value.
+ *
+ * @since Servlet 3.0
+ */
+public class MultipartConfigElement {
+
+ private String location;
+ private long maxFileSize;
+ private long maxRequestSize;
+ private int fileSizeThreshold;
+
+ /**
+ * Constructs an instance with defaults for all but location.
+ *
+ * @param location defualts to "" if values is null.
+ */
+ public MultipartConfigElement(String location) {
+ if (location == null) {
+ this.location = "";
+ } else {
+ this.location = location;
+ }
+ this.maxFileSize = -1L;
+ this.maxRequestSize = -1L;
+ this.fileSizeThreshold = 0;
+ }
+
+ /**
+ * Constructs an instance with all values specified.
+ *
+ * @param location the directory location where files will be stored
+ * @param maxFileSize the maximum size allowed for uploaded files
+ * @param maxRequestSize the maximum size allowed for
+ * multipart/form-data requests
+ * @param fileSizeThreshold the size threshold after which files will
+ * be written to disk
+ */
+ public MultipartConfigElement(String location, long maxFileSize,
+ long maxRequestSize, int fileSizeThreshold) {
+ if (location == null) {
+ this.location = "";
+ } else {
+ this.location = location;
+ }
+ this.maxFileSize = maxFileSize;
+ this.maxRequestSize = maxRequestSize;
+ this.fileSizeThreshold = fileSizeThreshold;
+ }
+
+ /**
+ * Constructs an instance from a {@link MultipartConfig} annotation value.
+ *
+ * @param annotation the annotation value
+ */
+ public MultipartConfigElement(MultipartConfig annotation) {
+ this.location = annotation.location();
+ this.fileSizeThreshold = annotation.fileSizeThreshold();
+ this.maxFileSize = annotation.maxFileSize();
+ this.maxRequestSize = annotation.maxRequestSize();
+ }
+
+ /**
+ * Gets the directory location where files will be stored.
+ *
+ * @return the directory location where files will be stored
+ */
+ public String getLocation() {
+ return this.location;
+ }
+
+ /**
+ * Gets the maximum size allowed for uploaded files.
+ *
+ * @return the maximum size allowed for uploaded files
+ */
+ public long getMaxFileSize() {
+ return this.maxFileSize;
+ }
+
+ /**
+ * Gets the maximum size allowed for multipart/form-data requests.
+ *
+ * @return the maximum size allowed for multipart/form-data requests
+ */
+ public long getMaxRequestSize() {
+ return this.maxRequestSize;
+ }
+
+ /**
+ * Gets the size threshold after which files will be written to disk.
+ *
+ * @return the size threshold after which files will be written to disk
+ */
+ public int getFileSizeThreshold() {
+ return this.fileSizeThreshold;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ReadListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/ReadListener.java
new file mode 100644
index 0000000..82a5449
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ReadListener.java
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.util.EventListener;
+
+/**
+ * <p>
+ * This class represents a call-back mechanism that will notify implementations
+ * as HTTP request data becomes available to be read without blocking.
+ * </p>
+ *
+ * @since Servlet 3.1
+ */
+public interface ReadListener extends EventListener {
+
+ /**
+ * When an instance of the <code>ReadListener</code> is registered with a {@link ServletInputStream},
+ * this method will be invoked by the container the first time when it is possible
+ * to read data. Subsequently the container will invoke this method if and only
+ * if the {@link javax.servlet.ServletInputStream#isReady()} method
+ * has been called and has returned a value of <code>false</code> <em>and</em>
+ * data has subsequently become available to read.
+ *
+ * @throws IOException if an I/O related error has occurred during processing
+ */
+ public void onDataAvailable() throws IOException;
+
+ /**
+ * Invoked when all data for the current request has been read.
+ *
+ * @throws IOException if an I/O related error has occurred during processing
+ */
+
+ public void onAllDataRead() throws IOException;
+
+ /**
+ * Invoked when an error occurs processing the request.
+ *
+ * @param t the throwable to indicate why the read operation failed
+ */
+ public void onError(Throwable t);
+
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/Registration.java b/third_party/servlet-spec/src/main/java/javax/servlet/Registration.java
new file mode 100644
index 0000000..26df091
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/Registration.java
@@ -0,0 +1,187 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Interface through which a {@link Servlet} or {@link Filter} may be
+ * further configured.
+ *
+ * <p>A Registration object whose {@link #getClassName} method returns null
+ * is considered <i>preliminary</i>. Servlets and Filters whose implementation
+ * class is container implementation specific may be declared without
+ * any <tt>servlet-class</tt> or <tt>filter-class</tt> elements, respectively,
+ * and will be represented as preliminary Registration objects.
+ * Preliminary registrations must be completed by calling one of the
+ * <tt>addServlet</tt> or <tt>addFilter</tt> methods on
+ * {@link ServletContext}, and passing in the Servlet or Filter name
+ * (obtained via {@link #getName}) along with the supporting Servlet or Filter
+ * implementation class name, Class object, or instance, respectively.
+ * In most cases, preliminary registrations will be completed by an
+ * appropriate, container-provided {@link ServletContainerInitializer}.
+ *
+ * @since Servlet 3.0
+ */
+public interface Registration {
+
+ /**
+ * Gets the name of the Servlet or Filter that is represented by this
+ * Registration.
+ *
+ * @return the name of the Servlet or Filter that is represented by this
+ * Registration
+ */
+ public String getName();
+
+ /**
+ * Gets the fully qualified class name of the Servlet or Filter that
+ * is represented by this Registration.
+ *
+ * @return the fully qualified class name of the Servlet or Filter
+ * that is represented by this Registration, or null if this
+ * Registration is preliminary
+ */
+ public String getClassName();
+
+ /**
+ * Sets the initialization parameter with the given name and value
+ * on the Servlet or Filter that is represented by this Registration.
+ *
+ * @param name the initialization parameter name
+ * @param value the initialization parameter value
+ *
+ * @return true if the update was successful, i.e., an initialization
+ * parameter with the given name did not already exist for the Servlet
+ * or Filter represented by this Registration, and false otherwise
+ *
+ * @throws IllegalStateException if the ServletContext from which this
+ * Registration was obtained has already been initialized
+ * @throws IllegalArgumentException if the given name or value is
+ * <tt>null</tt>
+ */
+ public boolean setInitParameter(String name, String value);
+
+ /**
+ * Gets the value of the initialization parameter with the given name
+ * that will be used to initialize the Servlet or Filter represented
+ * by this Registration object.
+ *
+ * @param name the name of the initialization parameter whose value is
+ * requested
+ *
+ * @return the value of the initialization parameter with the given
+ * name, or <tt>null</tt> if no initialization parameter with the given
+ * name exists
+ */
+ public String getInitParameter(String name);
+
+ /**
+ * Sets the given initialization parameters on the Servlet or Filter
+ * that is represented by this Registration.
+ *
+ * <p>The given map of initialization parameters is processed
+ * <i>by-value</i>, i.e., for each initialization parameter contained
+ * in the map, this method calls {@link #setInitParameter(String,String)}.
+ * If that method would return false for any of the
+ * initialization parameters in the given map, no updates will be
+ * performed, and false will be returned. Likewise, if the map contains
+ * an initialization parameter with a <tt>null</tt> name or value, no
+ * updates will be performed, and an IllegalArgumentException will be
+ * thrown.
+ *
+ * <p>The returned set is not backed by the {@code Registration} object,
+ * so changes in the returned set are not reflected in the
+ * {@code Registration} object, and vice-versa.</p>
+ *
+ * @param initParameters the initialization parameters
+ *
+ * @return the (possibly empty) Set of initialization parameter names
+ * that are in conflict
+ *
+ * @throws IllegalStateException if the ServletContext from which this
+ * Registration was obtained has already been initialized
+ * @throws IllegalArgumentException if the given map contains an
+ * initialization parameter with a <tt>null</tt> name or value
+ */
+ public Set<String> setInitParameters(Map<String, String> initParameters);
+
+ /**
+ * Gets an immutable (and possibly empty) Map containing the
+ * currently available initialization parameters that will be used to
+ * initialize the Servlet or Filter represented by this Registration
+ * object.
+ *
+ * @return Map containing the currently available initialization
+ * parameters that will be used to initialize the Servlet or Filter
+ * represented by this Registration object
+ */
+ public Map<String, String> getInitParameters();
+
+ /**
+ * Interface through which a {@link Servlet} or {@link Filter} registered
+ * via one of the <tt>addServlet</tt> or <tt>addFilter</tt> methods,
+ * respectively, on {@link ServletContext} may be further configured.
+ */
+ interface Dynamic extends Registration {
+
+ /**
+ * Configures the Servlet or Filter represented by this dynamic
+ * Registration as supporting asynchronous operations or not.
+ *
+ * <p>By default, servlet and filters do not support asynchronous
+ * operations.
+ *
+ * <p>A call to this method overrides any previous setting.
+ *
+ * @param isAsyncSupported true if the Servlet or Filter represented
+ * by this dynamic Registration supports asynchronous operations,
+ * false otherwise
+ *
+ * @throws IllegalStateException if the ServletContext from which
+ * this dynamic Registration was obtained has already been
+ * initialized
+ */
+ public void setAsyncSupported(boolean isAsyncSupported);
+ }
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/RequestDispatcher.java b/third_party/servlet-spec/src/main/java/javax/servlet/RequestDispatcher.java
new file mode 100644
index 0000000..19cdacc
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/RequestDispatcher.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+
+/**
+ * Defines an object that receives requests from the client
+ * and sends them to any resource (such as a servlet,
+ * HTML file, or JSP file) on the server. The servlet
+ * container creates the <code>RequestDispatcher</code> object,
+ * which is used as a wrapper around a server resource located
+ * at a particular path or given by a particular name.
+ *
+ * <p>This interface is intended to wrap servlets,
+ * but a servlet container can create <code>RequestDispatcher</code>
+ * objects to wrap any type of resource.
+ *
+ * @author Various
+ *
+ * @see ServletContext#getRequestDispatcher(java.lang.String)
+ * @see ServletContext#getNamedDispatcher(java.lang.String)
+ * @see ServletRequest#getRequestDispatcher(java.lang.String)
+ */
+
+public interface RequestDispatcher {
+
+ /**
+ * The name of the request attribute under which the original
+ * request URI is made available to the target of a
+ * {@link #forward(ServletRequest,ServletResponse) forward}
+ */
+ static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
+
+ /**
+ * The name of the request attribute under which the original
+ * context path is made available to the target of a
+ * {@link #forward(ServletRequest,ServletResponse) forward}
+ */
+ static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
+
+ /**
+ * The name of the request attribute under which the original
+ * {@link javax.servlet.http.HttpServletMapping} is made available
+ * to the target of a
+ * {@link #forward(ServletRequest,ServletResponse) forward}
+ *
+ * @since 4.0
+ */
+ static final String FORWARD_MAPPING = "javax.servlet.forward.mapping";
+
+ /**
+ * The name of the request attribute under which the original
+ * path info is made available to the target of a
+ * {@link #forward(ServletRequest,ServletResponse) forward}
+ */
+ static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
+
+ /**
+ * The name of the request attribute under which the original
+ * servlet path is made available to the target of a
+ * {@link #forward(ServletRequest,ServletResponse) forward}
+ */
+ static final String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
+
+ /**
+ * The name of the request attribute under which the original
+ * query string is made available to the target of a
+ * {@link #forward(ServletRequest,ServletResponse) forward}
+ */
+ static final String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
+
+ /**
+ * The name of the request attribute under which the request URI
+ * of the target of an {@link #include(ServletRequest,ServletResponse)
+ * include} is stored
+ */
+ static final String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
+
+ /**
+ * The name of the request attribute under which the context path
+ * of the target of an {@link #include(ServletRequest,ServletResponse)
+ * include} is stored
+ */
+ static final String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
+
+ /**
+ * The name of the request attribute under which the path info
+ * of the target of an {@link #include(ServletRequest,ServletResponse)
+ * include} is stored
+ */
+ static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
+
+ /**
+ * The name of the request attribute under which the
+ * {@link javax.servlet.http.HttpServletMapping}
+ * of the target of an {@link #include(ServletRequest,ServletResponse)
+ * include} is stored
+ */
+ static final String INCLUDE_MAPPING = "javax.servlet.include.mapping";
+
+ /**
+ * The name of the request attribute under which the servlet path
+ * of the target of an {@link #include(ServletRequest,ServletResponse)
+ * include} is stored
+ */
+ static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
+
+ /**
+ * The name of the request attribute under which the query string
+ * of the target of an {@link #include(ServletRequest,ServletResponse)
+ * include} is stored
+ */
+ static final String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
+
+ /**
+ * The name of the request attribute under which the exception object
+ * is propagated during an error dispatch
+ */
+ public static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
+
+ /**
+ * The name of the request attribute under which the type of the
+ * exception object is propagated during an error dispatch
+ */
+ public static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
+
+ /**
+ * The name of the request attribute under which the exception message
+ * is propagated during an error dispatch
+ */
+ public static final String ERROR_MESSAGE = "javax.servlet.error.message";
+
+ /**
+ * The name of the request attribute under which the request URI
+ * whose processing caused the error is propagated during an error
+ * dispatch
+ */
+ public static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
+
+ /**
+ * The name of the request attribute under which the name of the servlet
+ * in which the error occurred is propagated during an error dispatch
+ */
+ public static final String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";
+
+ /**
+ * The name of the request attribute under which the response status
+ * is propagated during an error dispatch
+ */
+ public static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
+
+
+ /**
+ * Forwards a request from
+ * a servlet to another resource (servlet, JSP file, or
+ * HTML file) on the server. This method allows
+ * one servlet to do preliminary processing of
+ * a request and another resource to generate
+ * the response.
+ *
+ * <p>For a <code>RequestDispatcher</code> obtained via
+ * <code>getRequestDispatcher()</code>, the <code>ServletRequest</code>
+ * object has its path elements and parameters adjusted to match
+ * the path of the target resource.
+ *
+ * <p><code>forward</code> should be called before the response has been
+ * committed to the client (before response body output has been flushed).
+ * If the response already has been committed, this method throws
+ * an <code>IllegalStateException</code>.
+ * Uncommitted output in the response buffer is automatically cleared
+ * before the forward.
+ *
+ * <p>The request and response parameters must be either the same
+ * objects as were passed to the calling servlet's service method or be
+ * subclasses of the {@link ServletRequestWrapper} or
+ * {@link ServletResponseWrapper} classes
+ * that wrap them.
+ *
+ * <p>This method sets the dispatcher type of the given request to
+ * <code>DispatcherType.FORWARD</code>.
+ *
+ * @param request a {@link ServletRequest} object that represents the
+ * request the client makes of the servlet
+ *
+ * @param response a {@link ServletResponse} object that represents
+ * the response the servlet returns to the client
+ *
+ * @throws ServletException if the target resource throws this exception
+ *
+ * @throws IOException if the target resource throws this exception
+ *
+ * @throws IllegalStateException if the response was already committed
+ *
+ * @see ServletRequest#getDispatcherType
+ */
+ public void forward(ServletRequest request, ServletResponse response)
+ throws ServletException, IOException;
+
+ /**
+ *
+ * Includes the content of a resource (servlet, JSP page,
+ * HTML file) in the response. In essence, this method enables
+ * programmatic server-side includes.
+ *
+ * <p>The {@link ServletResponse} object has its path elements
+ * and parameters remain unchanged from the caller's. The included
+ * servlet cannot change the response status code or set headers;
+ * any attempt to make a change is ignored.
+ *
+ * <p>The request and response parameters must be either the same
+ * objects as were passed to the calling servlet's service method or be
+ * subclasses of the {@link ServletRequestWrapper} or
+ * {@link ServletResponseWrapper} classes that wrap them.
+ *
+ * <p>This method sets the dispatcher type of the given request to
+ * <code>DispatcherType.INCLUDE</code>.
+ *
+ * @param request a {@link ServletRequest} object that contains the
+ * client's request
+ *
+ * @param response a {@link ServletResponse} object that contains the
+ * servlet's response
+ *
+ * @throws ServletException if the included resource throws this
+ * exception
+ *
+ * @throws IOException if the included resource throws this exception
+ *
+ * @see ServletRequest#getDispatcherType
+ */
+ public void include(ServletRequest request, ServletResponse response)
+ throws ServletException, IOException;
+}
+
+
+
+
+
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/Servlet.java b/third_party/servlet-spec/src/main/java/javax/servlet/Servlet.java
new file mode 100644
index 0000000..abb0250
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/Servlet.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+
+
+/**
+ * Defines methods that all servlets must implement.
+ *
+ * <p>A servlet is a small Java program that runs within a Web server.
+ * Servlets receive and respond to requests from Web clients,
+ * usually across HTTP, the HyperText Transfer Protocol.
+ *
+ * <p>To implement this interface, you can write a generic servlet
+ * that extends
+ * <code>javax.servlet.GenericServlet</code> or an HTTP servlet that
+ * extends <code>javax.servlet.http.HttpServlet</code>.
+ *
+ * <p>This interface defines methods to initialize a servlet,
+ * to service requests, and to remove a servlet from the server.
+ * These are known as life-cycle methods and are called in the
+ * following sequence:
+ * <ol>
+ * <li>The servlet is constructed, then initialized with the <code>init</code> method.
+ * <li>Any calls from clients to the <code>service</code> method are handled.
+ * <li>The servlet is taken out of service, then destroyed with the
+ * <code>destroy</code> method, then garbage collected and finalized.
+ * </ol>
+ *
+ * <p>In addition to the life-cycle methods, this interface
+ * provides the <code>getServletConfig</code> method, which the servlet
+ * can use to get any startup information, and the <code>getServletInfo</code>
+ * method, which allows the servlet to return basic information about itself,
+ * such as author, version, and copyright.
+ *
+ * @author Various
+ *
+ * @see GenericServlet
+ * @see javax.servlet.http.HttpServlet
+ *
+ */
+
+
+public interface Servlet {
+
+ /**
+ * Called by the servlet container to indicate to a servlet that the
+ * servlet is being placed into service.
+ *
+ * <p>The servlet container calls the <code>init</code>
+ * method exactly once after instantiating the servlet.
+ * The <code>init</code> method must complete successfully
+ * before the servlet can receive any requests.
+ *
+ * <p>The servlet container cannot place the servlet into service
+ * if the <code>init</code> method
+ * <ol>
+ * <li>Throws a <code>ServletException</code>
+ * <li>Does not return within a time period defined by the Web server
+ * </ol>
+ *
+ *
+ * @param config a <code>ServletConfig</code> object
+ * containing the servlet's
+ * configuration and initialization parameters
+ *
+ * @exception ServletException if an exception has occurred that
+ * interferes with the servlet's normal
+ * operation
+ *
+ * @see UnavailableException
+ * @see #getServletConfig
+ *
+ */
+
+ public void init(ServletConfig config) throws ServletException;
+
+
+
+ /**
+ *
+ * Returns a {@link ServletConfig} object, which contains
+ * initialization and startup parameters for this servlet.
+ * The <code>ServletConfig</code> object returned is the one
+ * passed to the <code>init</code> method.
+ *
+ * <p>Implementations of this interface are responsible for storing the
+ * <code>ServletConfig</code> object so that this
+ * method can return it. The {@link GenericServlet}
+ * class, which implements this interface, already does this.
+ *
+ * @return the <code>ServletConfig</code> object
+ * that initializes this servlet
+ *
+ * @see #init
+ *
+ */
+
+ public ServletConfig getServletConfig();
+
+
+
+ /**
+ * Called by the servlet container to allow the servlet to respond to
+ * a request.
+ *
+ * <p>This method is only called after the servlet's <code>init()</code>
+ * method has completed successfully.
+ *
+ * <p> The status code of the response always should be set for a servlet
+ * that throws or sends an error.
+ *
+ *
+ * <p>Servlets typically run inside multithreaded servlet containers
+ * that can handle multiple requests concurrently. Developers must
+ * be aware to synchronize access to any shared resources such as files,
+ * network connections, and as well as the servlet's class and instance
+ * variables.
+ * More information on multithreaded programming in Java is available in
+ * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
+ * the Java tutorial on multi-threaded programming</a>.
+ *
+ *
+ * @param req the <code>ServletRequest</code> object that contains
+ * the client's request
+ *
+ * @param res the <code>ServletResponse</code> object that contains
+ * the servlet's response
+ *
+ * @exception ServletException if an exception occurs that interferes
+ * with the servlet's normal operation
+ *
+ * @exception IOException if an input or output exception occurs
+ *
+ */
+
+ public void service(ServletRequest req, ServletResponse res)
+ throws ServletException, IOException;
+
+
+
+ /**
+ * Returns information about the servlet, such
+ * as author, version, and copyright.
+ *
+ * <p>The string that this method returns should
+ * be plain text and not markup of any kind (such as HTML, XML,
+ * etc.).
+ *
+ * @return a <code>String</code> containing servlet information
+ *
+ */
+
+ public String getServletInfo();
+
+
+
+ /**
+ *
+ * Called by the servlet container to indicate to a servlet that the
+ * servlet is being taken out of service. This method is
+ * only called once all threads within the servlet's
+ * <code>service</code> method have exited or after a timeout
+ * period has passed. After the servlet container calls this
+ * method, it will not call the <code>service</code> method again
+ * on this servlet.
+ *
+ * <p>This method gives the servlet an opportunity
+ * to clean up any resources that are being held (for example, memory,
+ * file handles, threads) and make sure that any persistent state is
+ * synchronized with the servlet's current state in memory.
+ *
+ */
+
+ public void destroy();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletConfig.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletConfig.java
new file mode 100644
index 0000000..2140916
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletConfig.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.util.Enumeration;
+
+/**
+ * A servlet configuration object used by a servlet container
+ * to pass information to a servlet during initialization.
+ */
+ public interface ServletConfig {
+
+ /**
+ * Returns the name of this servlet instance.
+ * The name may be provided via server administration, assigned in the
+ * web application deployment descriptor, or for an unregistered (and thus
+ * unnamed) servlet instance it will be the servlet's class name.
+ *
+ * @return the name of the servlet instance
+ */
+ public String getServletName();
+
+
+ /**
+ * Returns a reference to the {@link ServletContext} in which the caller
+ * is executing.
+ *
+ * @return a {@link ServletContext} object, used
+ * by the caller to interact with its servlet container
+ *
+ * @see ServletContext
+ */
+ public ServletContext getServletContext();
+
+
+ /**
+ * Gets the value of the initialization parameter with the given name.
+ *
+ * @param name the name of the initialization parameter whose value to
+ * get
+ *
+ * @return a <code>String</code> containing the value
+ * of the initialization parameter, or <code>null</code> if
+ * the initialization parameter does not exist
+ */
+ public String getInitParameter(String name);
+
+
+ /**
+ * Returns the names of the servlet's initialization parameters
+ * as an <code>Enumeration</code> of <code>String</code> objects,
+ * or an empty <code>Enumeration</code> if the servlet has
+ * no initialization parameters.
+ *
+ * @return an <code>Enumeration</code> of <code>String</code>
+ * objects containing the names of the servlet's
+ * initialization parameters
+ */
+ public Enumeration<String> getInitParameterNames();
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletContainerInitializer.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContainerInitializer.java
new file mode 100644
index 0000000..a7e873e
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContainerInitializer.java
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.util.Set;
+
+/**
+ * Interface which allows a library/runtime to be notified of a web
+ * application's startup phase and perform any required programmatic
+ * registration of servlets, filters, and listeners in response to it.
+ *
+ * <p>Implementations of this interface may be annotated with
+ * {@link javax.servlet.annotation.HandlesTypes HandlesTypes}, in order to
+ * receive (at their {@link #onStartup} method) the Set of application
+ * classes that implement, extend, or have been annotated with the class
+ * types specified by the annotation.
+ *
+ * <p>If an implementation of this interface does not use <tt>HandlesTypes</tt>
+ * annotation, or none of the application classes match the ones specified
+ * by the annotation, the container must pass a <tt>null</tt> Set of classes
+ * to {@link #onStartup}.
+ *
+ * <p>When examining the classes of an application to see if they match
+ * any of the criteria specified by the <tt>HandlesTypes</tt> annotation
+ * of a <tt>ServletContainerInitializer</tt>, the container may run into
+ * classloading problems if any of the application's optional JAR
+ * files are missing. Because the container is not in a position to decide
+ * whether these types of classloading failures will prevent
+ * the application from working correctly, it must ignore them,
+ * while at the same time providing a configuration option that would
+ * log them.
+ *
+ * <p>Implementations of this interface must be declared by a JAR file
+ * resource located inside the <tt>META-INF/services</tt> directory and
+ * named for the fully qualified class name of this interface, and will be
+ * discovered using the runtime's service provider lookup mechanism
+ * or a container specific mechanism that is semantically equivalent to
+ * it. In either case, <tt>ServletContainerInitializer</tt> services from web
+ * fragment JAR files excluded from an absolute ordering must be ignored,
+ * and the order in which these services are discovered must follow the
+ * application's classloading delegation model.
+ *
+ * @see javax.servlet.annotation.HandlesTypes
+ *
+ * @since Servlet 3.0
+ */
+public interface ServletContainerInitializer {
+
+ /**
+ * Notifies this <tt>ServletContainerInitializer</tt> of the startup
+ * of the application represented by the given <tt>ServletContext</tt>.
+ *
+ * <p>If this <tt>ServletContainerInitializer</tt> is bundled in a JAR
+ * file inside the <tt>WEB-INF/lib</tt> directory of an application,
+ * its <tt>onStartup</tt> method will be invoked only once during the
+ * startup of the bundling application. If this
+ * <tt>ServletContainerInitializer</tt> is bundled inside a JAR file
+ * outside of any <tt>WEB-INF/lib</tt> directory, but still
+ * discoverable as described above, its <tt>onStartup</tt> method
+ * will be invoked every time an application is started.
+ *
+ * @param c the Set of application classes that extend, implement, or
+ * have been annotated with the class types specified by the
+ * {@link javax.servlet.annotation.HandlesTypes HandlesTypes} annotation,
+ * or <tt>null</tt> if there are no matches, or this
+ * <tt>ServletContainerInitializer</tt> has not been annotated with
+ * <tt>HandlesTypes</tt>
+ *
+ * @param ctx the <tt>ServletContext</tt> of the web application that
+ * is being started and in which the classes contained in <tt>c</tt>
+ * were found
+ *
+ * @throws ServletException if an error has occurred
+ */
+ public void onStartup(Set<Class<?>> c, ServletContext ctx)
+ throws ServletException;
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletContext.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContext.java
new file mode 100644
index 0000000..3bd5431
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContext.java
@@ -0,0 +1,1757 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.EnumSet;
+import java.util.EventListener;
+import java.util.Map;
+import java.util.Set;
+import javax.servlet.descriptor.JspConfigDescriptor;
+
+/**
+ * Defines a set of methods that a servlet uses to communicate with its
+ * servlet container, for example, to get the MIME type of a file,
+ * dispatch requests, or write to a log file.
+ *
+ * <p>There is one context per "web application" per Java Virtual Machine. (A
+ * "web application" is a collection of servlets and content installed under a
+ * specific subset of the server's URL namespace such as <code>/catalog</code>
+ * and possibly installed via a <code>.war</code> file.)
+ *
+ * <p>In the case of a web
+ * application marked "distributed" in its deployment descriptor, there will
+ * be one context instance for each virtual machine. In this situation, the
+ * context cannot be used as a location to share global information (because
+ * the information won't be truly global). Use an external resource like
+ * a database instead.
+ *
+ * <p>The <code>ServletContext</code> object is contained within
+ * the {@link ServletConfig} object, which the Web server provides the
+ * servlet when the servlet is initialized.
+ *
+ * @author Various
+ *
+ * @see Servlet#getServletConfig
+ * @see ServletConfig#getServletContext
+ */
+
+public interface ServletContext {
+
+ /**
+ * The name of the <tt>ServletContext</tt> attribute which stores
+ * the private temporary directory (of type <tt>java.io.File</tt>)
+ * provided by the servlet container for the <tt>ServletContext</tt>
+ */
+ public static final String TEMPDIR = "javax.servlet.context.tempdir";
+
+
+ /**
+ * The name of the <code>ServletContext</code> attribute whose value
+ * (of type <code>java.util.List<java.lang.String></code>) contains
+ * the list of names of JAR files in <code>WEB-INF/lib</code> ordered by
+ * their web fragment names (with possible exclusions if
+ * <code><absolute-ordering></code> without any
+ * <code><others/></code> is being used), or null if no
+ * absolute or relative ordering has been specified
+ */
+ public static final String ORDERED_LIBS =
+ "javax.servlet.context.orderedLibs";
+
+
+ /**
+ * Returns the context path of the web application.
+ *
+ * <p>The context path is the portion of the request URI that is used
+ * to select the context of the request. The context path always comes
+ * first in a request URI. If this context is the "root" context
+ * rooted at the base of the Web server's URL name space, this path
+ * will be an empty string. Otherwise, if the context is not rooted at
+ * the root of the server's name space, the path starts with a /
+ * character but does not end with a / character.
+ *
+ * <p>It is possible that a servlet container may match a context by
+ * more than one context path. In such cases the
+ * {@link javax.servlet.http.HttpServletRequest#getContextPath()}
+ * will return the actual context path used by the request and it may
+ * differ from the path returned by this method.
+ * The context path returned by this method should be considered as the
+ * prime or preferred context path of the application.
+ *
+ * @return The context path of the web application, or "" for the
+ * root context
+ *
+ * @see javax.servlet.http.HttpServletRequest#getContextPath()
+ *
+ * @since Servlet 2.5
+ */
+ public String getContextPath();
+
+
+ /**
+ * Returns a <code>ServletContext</code> object that
+ * corresponds to a specified URL on the server.
+ *
+ * <p>This method allows servlets to gain
+ * access to the context for various parts of the server, and as
+ * needed obtain {@link RequestDispatcher} objects from the context.
+ * The given path must be begin with <tt>/</tt>, is interpreted relative
+ * to the server's document root and is matched against the context
+ * roots of other web applications hosted on this container.
+ *
+ * <p>In a security conscious environment, the servlet container may
+ * return <code>null</code> for a given URL.
+ *
+ * @param uripath a <code>String</code> specifying the context path of
+ * another web application in the container.
+ * @return the <code>ServletContext</code> object that
+ * corresponds to the named URL, or null if either
+ none exists or the container wishes to restrict
+ * this access.
+ *
+ * @see RequestDispatcher
+ */
+ public ServletContext getContext(String uripath);
+
+
+ /**
+ * Returns the major version of the Servlet API that this
+ * servlet container supports. All implementations that comply
+ * with Version 4.0 must have this method return the integer 4.
+ *
+ * @return 4
+ */
+ public int getMajorVersion();
+
+
+ /**
+ * Returns the minor version of the Servlet API that this
+ * servlet container supports. All implementations that comply
+ * with Version 4.0 must have this method return the integer 0.
+ *
+ * @return 0
+ */
+ public int getMinorVersion();
+
+
+ /**
+ * Gets the major version of the Servlet specification that the
+ * application represented by this ServletContext is based on.
+ *
+ * <p>The value returned may be different from {@link #getMajorVersion},
+ * which returns the major version of the Servlet specification
+ * supported by the Servlet container.
+ *
+ * @return the major version of the Servlet specification that the
+ * application represented by this ServletContext is based on
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public int getEffectiveMajorVersion();
+
+
+ /**
+ * Gets the minor version of the Servlet specification that the
+ * application represented by this ServletContext is based on.
+ *
+ * <p>The value returned may be different from {@link #getMinorVersion},
+ * which returns the minor version of the Servlet specification
+ * supported by the Servlet container.
+ *
+ * @return the minor version of the Servlet specification that the
+ * application represented by this ServletContext is based on
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public int getEffectiveMinorVersion();
+
+
+ /**
+ * Returns the MIME type of the specified file, or <code>null</code> if
+ * the MIME type is not known. The MIME type is determined
+ * by the configuration of the servlet container, and may be specified
+ * in a web application deployment descriptor. Common MIME
+ * types include <code>text/html</code> and <code>image/gif</code>.
+ *
+ * @param file a <code>String</code> specifying the name of a file
+ *
+ * @return a <code>String</code> specifying the file's MIME type
+ */
+ public String getMimeType(String file);
+
+
+ /**
+ * Returns a directory-like listing of all the paths to resources
+ * within the web application whose longest sub-path matches the
+ * supplied path argument.
+ *
+ * <p>Paths indicating subdirectory paths end with a <tt>/</tt>.
+ *
+ * <p>The returned paths are all relative to the root of the web
+ * application, or relative to the <tt>/META-INF/resources</tt>
+ * directory of a JAR file inside the web application's
+ * <tt>/WEB-INF/lib</tt> directory, and have a leading <tt>/</tt>.
+ *
+ * <p>The returned set is not backed by the {@code ServletContext} object,
+ * so changes in the returned set are not reflected in the
+ * {@code ServletContext} object, and vice-versa.</p>
+ *
+ * <p>For example, for a web application containing:
+ *
+ * <pre>{@code
+ * /welcome.html
+ * /catalog/index.html
+ * /catalog/products.html
+ * /catalog/offers/books.html
+ * /catalog/offers/music.html
+ * /customer/login.jsp
+ * /WEB-INF/web.xml
+ * /WEB-INF/classes/com.acme.OrderServlet.class
+ * /WEB-INF/lib/catalog.jar!/META-INF/resources/catalog/moreOffers/books.html
+ * }</pre>
+ *
+ * <tt>getResourcePaths("/")</tt> would return
+ * <tt>{"/welcome.html", "/catalog/", "/customer/", "/WEB-INF/"}</tt>,
+ * and <tt>getResourcePaths("/catalog/")</tt> would return
+ * <tt>{"/catalog/index.html", "/catalog/products.html",
+ * "/catalog/offers/", "/catalog/moreOffers/"}</tt>.
+ *
+ * @param path the partial path used to match the resources,
+ * which must start with a <tt>/</tt>
+ * @return a Set containing the directory listing, or null if there
+ * are no resources in the web application whose path
+ * begins with the supplied path.
+ *
+ * @since Servlet 2.3
+ */
+ public Set<String> getResourcePaths(String path);
+
+
+ /**
+ * Returns a URL to the resource that is mapped to the given path.
+ *
+ * <p>The path must begin with a <tt>/</tt> and is interpreted
+ * as relative to the current context root,
+ * or relative to the <tt>/META-INF/resources</tt> directory
+ * of a JAR file inside the web application's <tt>/WEB-INF/lib</tt>
+ * directory.
+ * This method will first search the document root of the
+ * web application for the requested resource, before searching
+ * any of the JAR files inside <tt>/WEB-INF/lib</tt>.
+ * The order in which the JAR files inside <tt>/WEB-INF/lib</tt>
+ * are searched is undefined.
+ *
+ * <p>This method allows the servlet container to make a resource
+ * available to servlets from any source. Resources
+ * can be located on a local or remote
+ * file system, in a database, or in a <code>.war</code> file.
+ *
+ * <p>The servlet container must implement the URL handlers
+ * and <code>URLConnection</code> objects that are necessary
+ * to access the resource.
+ *
+ * <p>This method returns <code>null</code>
+ * if no resource is mapped to the pathname.
+ *
+ * <p>Some containers may allow writing to the URL returned by
+ * this method using the methods of the URL class.
+ *
+ * <p>The resource content is returned directly, so be aware that
+ * requesting a <code>.jsp</code> page returns the JSP source code.
+ * Use a <code>RequestDispatcher</code> instead to include results of
+ * an execution.
+ *
+ * <p>This method has a different purpose than
+ * <code>java.lang.Class.getResource</code>,
+ * which looks up resources based on a class loader. This
+ * method does not use class loaders.
+ *
+ * @param path a <code>String</code> specifying
+ * the path to the resource
+ *
+ * @return the resource located at the named path,
+ * or <code>null</code> if there is no resource at that path
+ *
+ * @exception MalformedURLException if the pathname is not given in
+ * the correct form
+ */
+ public URL getResource(String path) throws MalformedURLException;
+
+
+ /**
+ * Returns the resource located at the named path as
+ * an <code>InputStream</code> object.
+ *
+ * <p>The data in the <code>InputStream</code> can be
+ * of any type or length. The path must be specified according
+ * to the rules given in <code>getResource</code>.
+ * This method returns <code>null</code> if no resource exists at
+ * the specified path.
+ *
+ * <p>Meta-information such as content length and content type
+ * that is available via <code>getResource</code>
+ * method is lost when using this method.
+ *
+ * <p>The servlet container must implement the URL handlers
+ * and <code>URLConnection</code> objects necessary to access
+ * the resource.
+ *
+ * <p>This method is different from
+ * <code>java.lang.Class.getResourceAsStream</code>,
+ * which uses a class loader. This method allows servlet containers
+ * to make a resource available
+ * to a servlet from any location, without using a class loader.
+ *
+ *
+ * @param path a <code>String</code> specifying the path
+ * to the resource
+ *
+ * @return the <code>InputStream</code> returned to the
+ * servlet, or <code>null</code> if no resource
+ * exists at the specified path
+ */
+ public InputStream getResourceAsStream(String path);
+
+
+ /**
+ *
+ * Returns a {@link RequestDispatcher} object that acts
+ * as a wrapper for the resource located at the given path.
+ * A <code>RequestDispatcher</code> object can be used to forward
+ * a request to the resource or to include the resource in a response.
+ * The resource can be dynamic or static.
+ *
+ * <p>The pathname must begin with a <tt>/</tt> and is interpreted as
+ * relative to the current context root. Use <code>getContext</code>
+ * to obtain a <code>RequestDispatcher</code> for resources in foreign
+ * contexts.
+ *
+ * <p>This method returns <code>null</code> if the
+ * <code>ServletContext</code> cannot return a
+ * <code>RequestDispatcher</code>.
+ *
+ * @param path a <code>String</code> specifying the pathname
+ * to the resource
+ *
+ * @return a <code>RequestDispatcher</code> object
+ * that acts as a wrapper for the resource
+ * at the specified path, or <code>null</code> if
+ * the <code>ServletContext</code> cannot return
+ * a <code>RequestDispatcher</code>
+ *
+ * @see RequestDispatcher
+ * @see ServletContext#getContext
+ */
+ public RequestDispatcher getRequestDispatcher(String path);
+
+
+ /**
+ * Returns a {@link RequestDispatcher} object that acts
+ * as a wrapper for the named servlet.
+ *
+ * <p>Servlets (and JSP pages also) may be given names via server
+ * administration or via a web application deployment descriptor.
+ * A servlet instance can determine its name using
+ * {@link ServletConfig#getServletName}.
+ *
+ * <p>This method returns <code>null</code> if the
+ * <code>ServletContext</code>
+ * cannot return a <code>RequestDispatcher</code> for any reason.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of a servlet to wrap
+ *
+ * @return a <code>RequestDispatcher</code> object
+ * that acts as a wrapper for the named servlet,
+ * or <code>null</code> if the <code>ServletContext</code>
+ * cannot return a <code>RequestDispatcher</code>
+ *
+ * @see RequestDispatcher
+ * @see ServletContext#getContext
+ * @see ServletConfig#getServletName
+ */
+ public RequestDispatcher getNamedDispatcher(String name);
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+ *
+ * <p>This method was originally defined to retrieve a servlet
+ * from a <code>ServletContext</code>. In this version, this method
+ * always returns <code>null</code> and remains only to preserve
+ * binary compatibility. This method will be permanently removed
+ * in a future version of the Java Servlet API.
+ *
+ * <p>In lieu of this method, servlets can share information using the
+ * <code>ServletContext</code> class and can perform shared business logic
+ * by invoking methods on common non-servlet classes.
+ *
+ * @param name the servlet name
+ * @return the {@code javax.servlet.Servlet Servlet} with the given name
+ * @throws ServletException if an exception has occurred that interfaces
+ * with servlet's normal operation
+ */
+ @Deprecated
+ public Servlet getServlet(String name) throws ServletException;
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.0, with no replacement.
+ *
+ * <p>This method was originally defined to return an
+ * <code>Enumeration</code> of all the servlets known to this servlet
+ * context.
+ * In this version, this method always returns an empty enumeration and
+ * remains only to preserve binary compatibility. This method
+ * will be permanently removed in a future version of the Java
+ * Servlet API.
+ *
+ * @return an <code>Enumeration</code> of {@code javax.servlet.Servlet Servlet}
+ */
+ @Deprecated
+ public Enumeration<Servlet> getServlets();
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.1, with no replacement.
+ *
+ * <p>This method was originally defined to return an
+ * <code>Enumeration</code>
+ * of all the servlet names known to this context. In this version,
+ * this method always returns an empty <code>Enumeration</code> and
+ * remains only to preserve binary compatibility. This method will
+ * be permanently removed in a future version of the Java Servlet API.
+ *
+ * @return an <code>Enumeration</code> of {@code javax.servlet.Servlet Servlet} names
+ */
+ @Deprecated
+ public Enumeration<String> getServletNames();
+
+
+ /**
+ *
+ * Writes the specified message to a servlet log file, usually
+ * an event log. The name and type of the servlet log file is
+ * specific to the servlet container.
+ *
+ * @param msg a <code>String</code> specifying the
+ * message to be written to the log file
+ */
+ public void log(String msg);
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.1, use
+ * {@link #log(String message, Throwable throwable)}
+ * instead.
+ *
+ * <p>This method was originally defined to write an
+ * exception's stack trace and an explanatory error message
+ * to the servlet log file.
+ *
+ * @param exception the <code>Exception</code> error
+ * @param msg a <code>String</code> that describes the exception
+ */
+ @Deprecated
+ public void log(Exception exception, String msg);
+
+
+ /**
+ * Writes an explanatory message and a stack trace
+ * for a given <code>Throwable</code> exception
+ * to the servlet log file. The name and type of the servlet log
+ * file is specific to the servlet container, usually an event log.
+ *
+ * @param message a <code>String</code> that
+ * describes the error or exception
+ *
+ * @param throwable the <code>Throwable</code> error
+ * or exception
+ */
+ public void log(String message, Throwable throwable);
+
+
+ /**
+ * Gets the <i>real</i> path corresponding to the given
+ * <i>virtual</i> path.
+ *
+ * <p>For example, if <tt>path</tt> is equal to <tt>/index.html</tt>,
+ * this method will return the absolute file path on the server's
+ * filesystem to which a request of the form
+ * <tt>http://<host>:<port>/<contextPath>/index.html</tt>
+ * would be mapped, where <tt><contextPath></tt> corresponds to the
+ * context path of this ServletContext.
+ *
+ * <p>The real path returned will be in a form
+ * appropriate to the computer and operating system on
+ * which the servlet container is running, including the
+ * proper path separators.
+ *
+ * <p>Resources inside the <tt>/META-INF/resources</tt>
+ * directories of JAR files bundled in the application's
+ * <tt>/WEB-INF/lib</tt> directory must be considered only if the
+ * container has unpacked them from their containing JAR file, in
+ * which case the path to the unpacked location must be returned.
+ *
+ * <p>This method returns <code>null</code> if the servlet container
+ * is unable to translate the given <i>virtual</i> path to a
+ * <i>real</i> path.
+ *
+ * @param path the <i>virtual</i> path to be translated to a
+ * <i>real</i> path
+ *
+ * @return the <i>real</i> path, or <tt>null</tt> if the
+ * translation cannot be performed
+ */
+ public String getRealPath(String path);
+
+
+ /**
+ * Returns the name and version of the servlet container on which
+ * the servlet is running.
+ *
+ * <p>The form of the returned string is
+ * <i>servername</i>/<i>versionnumber</i>.
+ * For example, the JavaServer Web Development Kit may return the string
+ * <code>JavaServer Web Dev Kit/1.0</code>.
+ *
+ * <p>The servlet container may return other optional information
+ * after the primary string in parentheses, for example,
+ * <code>JavaServer Web Dev Kit/1.0 (JDK 1.1.6; Windows NT 4.0 x86)</code>.
+ *
+ *
+ * @return a <code>String</code> containing at least the
+ * servlet container name and version number
+ */
+ public String getServerInfo();
+
+
+ /**
+ * Returns a <code>String</code> containing the value of the named
+ * context-wide initialization parameter, or <code>null</code> if
+ * the parameter does not exist.
+ *
+ * <p>This method can make available configuration information useful
+ * to an entire web application. For example, it can provide a
+ * webmaster's email address or the name of a system that holds
+ * critical data.
+ *
+ * @param name a <code>String</code> containing the name of the
+ * parameter whose value is requested
+ *
+ * @return a <code>String</code> containing the value of the
+ * context's initialization parameter, or <code>null</code> if the
+ * context's initialization parameter does not exist.
+ *
+ * @throws NullPointerException if the argument {@code name} is
+ * {@code null}
+ *
+ * @see ServletConfig#getInitParameter
+ */
+ public String getInitParameter(String name);
+
+
+ /**
+ * Returns the names of the context's initialization parameters as an
+ * <code>Enumeration</code> of <code>String</code> objects, or an
+ * empty <code>Enumeration</code> if the context has no initialization
+ * parameters.
+ *
+ * @return an <code>Enumeration</code> of <code>String</code>
+ * objects containing the names of the context's
+ * initialization parameters
+ *
+ * @see ServletConfig#getInitParameter
+ */
+ public Enumeration<String> getInitParameterNames();
+
+
+ /**
+ * Sets the context initialization parameter with the given name and
+ * value on this ServletContext.
+ *
+ * @param name the name of the context initialization parameter to set
+ * @param value the value of the context initialization parameter to set
+ *
+ * @return true if the context initialization parameter with the given
+ * name and value was set successfully on this ServletContext, and false
+ * if it was not set because this ServletContext already contains a
+ * context initialization parameter with a matching name
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws NullPointerException if the name parameter is {@code null}
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public boolean setInitParameter(String name, String value);
+
+
+ /**
+ * Returns the servlet container attribute with the given name, or
+ * <code>null</code> if there is no attribute by that name.
+ *
+ * <p>An attribute allows a servlet container to give the
+ * servlet additional information not
+ * already provided by this interface. See your
+ * server documentation for information about its attributes.
+ * A list of supported attributes can be retrieved using
+ * <code>getAttributeNames</code>.
+ *
+ * <p>The attribute is returned as a <code>java.lang.Object</code>
+ * or some subclass.
+ *
+ * <p>Attribute names should follow the same convention as package
+ * names. The Java Servlet API specification reserves names
+ * matching <code>java.*</code>, <code>javax.*</code>,
+ * and <code>sun.*</code>.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of the attribute
+ *
+ * @return an <code>Object</code> containing the value of the
+ * attribute, or <code>null</code> if no attribute
+ * exists matching the given name.
+ *
+ * @see ServletContext#getAttributeNames
+ *
+ * @throws NullPointerException if the argument {@code name} is
+ * {@code null}
+ *
+ */
+ public Object getAttribute(String name);
+
+
+ /**
+ * Returns an <code>Enumeration</code> containing the
+ * attribute names available within this ServletContext.
+ *
+ * <p>Use the {@link #getAttribute} method with an attribute name
+ * to get the value of an attribute.
+ *
+ * @return an <code>Enumeration</code> of attribute
+ * names
+ *
+ * @see #getAttribute
+ */
+ public Enumeration<String> getAttributeNames();
+
+
+ /**
+ * Binds an object to a given attribute name in this ServletContext. If
+ * the name specified is already used for an attribute, this
+ * method will replace the attribute with the new to the new attribute.
+ * <p>If listeners are configured on the <code>ServletContext</code> the
+ * container notifies them accordingly.
+ * <p>
+ * If a null value is passed, the effect is the same as calling
+ * <code>removeAttribute()</code>.
+ *
+ * <p>Attribute names should follow the same convention as package
+ * names. The Java Servlet API specification reserves names
+ * matching <code>java.*</code>, <code>javax.*</code>, and
+ * <code>sun.*</code>.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of the attribute
+ *
+ * @param object an <code>Object</code> representing the
+ * attribute to be bound
+ *
+ * @throws NullPointerException if the name parameter is {@code null}
+ *
+ */
+ public void setAttribute(String name, Object object);
+
+
+ /**
+ * Removes the attribute with the given name from
+ * this ServletContext. After removal, subsequent calls to
+ * {@link #getAttribute} to retrieve the attribute's value
+ * will return <code>null</code>.
+ *
+ * <p>If listeners are configured on the <code>ServletContext</code> the
+ * container notifies them accordingly.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of the attribute to be removed
+ */
+ public void removeAttribute(String name);
+
+
+ /**
+ * Returns the name of this web application corresponding to this
+ * ServletContext as specified in the deployment descriptor for this
+ * web application by the display-name element.
+ *
+ * @return The name of the web application or null if no name has been
+ * declared in the deployment descriptor.
+ *
+ * @since Servlet 2.3
+ */
+ public String getServletContextName();
+
+
+ /**
+ * Adds the servlet with the given name and class name to this servlet
+ * context.
+ *
+ * <p>The registered servlet may be further configured via the returned
+ * {@link ServletRegistration} object.
+ *
+ * <p>The specified <tt>className</tt> will be loaded using the
+ * classloader associated with the application represented by this
+ * ServletContext.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * ServletRegistration for a servlet with the given <tt>servletName</tt>,
+ * it will be completed (by assigning the given <tt>className</tt> to it)
+ * and returned.
+ *
+ * <p>This method introspects the class with the given <tt>className</tt>
+ * for the {@link javax.servlet.annotation.ServletSecurity},
+ * {@link javax.servlet.annotation.MultipartConfig},
+ * <tt>javax.annotation.security.RunAs</tt>, and
+ * <tt>javax.annotation.security.DeclareRoles</tt> annotations.
+ * In addition, this method supports resource injection if the
+ * class with the given <tt>className</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param servletName the name of the servlet
+ * @param className the fully qualified class name of the servlet
+ *
+ * @return a ServletRegistration object that may be used to further
+ * configure the registered servlet, or <tt>null</tt> if this
+ * ServletContext already contains a complete ServletRegistration for
+ * a servlet with the given <tt>servletName</tt>
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws IllegalArgumentException if <code>servletName</code> is null
+ * or an empty String
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public ServletRegistration.Dynamic addServlet(
+ String servletName, String className);
+
+
+ /**
+ * Registers the given servlet instance with this ServletContext
+ * under the given <tt>servletName</tt>.
+ *
+ * <p>The registered servlet may be further configured via the returned
+ * {@link ServletRegistration} object.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * ServletRegistration for a servlet with the given <tt>servletName</tt>,
+ * it will be completed (by assigning the class name of the given servlet
+ * instance to it) and returned.
+ *
+ * @param servletName the name of the servlet
+ * @param servlet the servlet instance to register
+ *
+ * @return a ServletRegistration object that may be used to further
+ * configure the given servlet, or <tt>null</tt> if this
+ * ServletContext already contains a complete ServletRegistration for a
+ * servlet with the given <tt>servletName</tt> or if the same servlet
+ * instance has already been registered with this or another
+ * ServletContext in the same container
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @throws IllegalArgumentException if the given servlet instance
+ * implements {@link SingleThreadModel}, or <code>servletName</code> is null
+ * or an empty String
+ *
+ * @since Servlet 3.0
+ */
+ public ServletRegistration.Dynamic addServlet(
+ String servletName, Servlet servlet);
+
+
+ /**
+ * Adds the servlet with the given name and class type to this servlet
+ * context.
+ *
+ * <p>The registered servlet may be further configured via the returned
+ * {@link ServletRegistration} object.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * ServletRegistration for a servlet with the given <tt>servletName</tt>,
+ * it will be completed (by assigning the name of the given
+ * <tt>servletClass</tt> to it) and returned.
+ *
+ * <p>This method introspects the given <tt>servletClass</tt> for
+ * the {@link javax.servlet.annotation.ServletSecurity},
+ * {@link javax.servlet.annotation.MultipartConfig},
+ * <tt>javax.annotation.security.RunAs</tt>, and
+ * <tt>javax.annotation.security.DeclareRoles</tt> annotations.
+ * In addition, this method supports resource injection if the
+ * given <tt>servletClass</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param servletName the name of the servlet
+ * @param servletClass the class object from which the servlet will be
+ * instantiated
+ *
+ * @return a ServletRegistration object that may be used to further
+ * configure the registered servlet, or <tt>null</tt> if this
+ * ServletContext already contains a complete ServletRegistration for
+ * the given <tt>servletName</tt>
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws IllegalArgumentException if <code>servletName</code> is null
+ * or an empty String
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public ServletRegistration.Dynamic addServlet(String servletName,
+ Class <? extends Servlet> servletClass);
+
+
+ /**
+ * Adds the servlet with the given jsp file to this servlet context.
+ *
+ * <p>The registered servlet may be further configured via the returned
+ * {@link ServletRegistration} object.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * ServletRegistration for a servlet with the given <tt>servletName</tt>,
+ * it will be completed (by assigning the given <tt>jspFile</tt> to it)
+ * and returned.
+ *
+ * @param servletName the name of the servlet
+ * @param jspFile the full path to a JSP file within the web application
+ * beginning with a `/'.
+ *
+ * @return a ServletRegistration object that may be used to further
+ * configure the registered servlet, or <tt>null</tt> if this
+ * ServletContext already contains a complete ServletRegistration for
+ * a servlet with the given <tt>servletName</tt>
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws IllegalArgumentException if <code>servletName</code> is null
+ * or an empty String
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public ServletRegistration.Dynamic addJspFile(
+ String servletName, String jspFile);
+
+
+ /**
+ * Instantiates the given Servlet class.
+ *
+ * <p>The returned Servlet instance may be further customized before it
+ * is registered with this ServletContext via a call to
+ * {@link #addServlet(String,Servlet)}.
+ *
+ * <p>The given Servlet class must define a zero argument constructor,
+ * which is used to instantiate it.
+ *
+ * <p>This method introspects the given <tt>clazz</tt> for
+ * the following annotations:
+ * {@link javax.servlet.annotation.ServletSecurity},
+ * {@link javax.servlet.annotation.MultipartConfig},
+ * <tt>javax.annotation.security.RunAs</tt>, and
+ * <tt>javax.annotation.security.DeclareRoles</tt>.
+ * In addition, this method supports resource injection if the
+ * given <tt>clazz</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param <T> the class of the Servlet to create
+ * @param clazz the Servlet class to instantiate
+ *
+ * @return the new Servlet instance
+ *
+ * @throws ServletException if the given <tt>clazz</tt> fails to be
+ * instantiated
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public <T extends Servlet> T createServlet(Class<T> clazz)
+ throws ServletException;
+
+
+ /**
+ * Gets the ServletRegistration corresponding to the servlet with the
+ * given <tt>servletName</tt>.
+ *
+ * @return the (complete or preliminary) ServletRegistration for the
+ * servlet with the given <tt>servletName</tt>, or null if no
+ * ServletRegistration exists under that name
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @param servletName the name of a servlet
+ * @since Servlet 3.0
+ */
+ public ServletRegistration getServletRegistration(String servletName);
+
+
+ /**
+ * Gets a (possibly empty) Map of the ServletRegistration
+ * objects (keyed by servlet name) corresponding to all servlets
+ * registered with this ServletContext.
+ *
+ * <p>The returned Map includes the ServletRegistration objects
+ * corresponding to all declared and annotated servlets, as well as the
+ * ServletRegistration objects corresponding to all servlets that have
+ * been added via one of the <tt>addServlet</tt> and <tt>addJspFile</tt>
+ * methods.
+ *
+ * <p>If permitted, any changes to the returned Map must not affect this
+ * ServletContext.
+ *
+ * @return Map of the (complete and preliminary) ServletRegistration
+ * objects corresponding to all servlets currently registered with this
+ * ServletContext
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public Map<String, ? extends ServletRegistration> getServletRegistrations();
+
+
+ /**
+ * Adds the filter with the given name and class name to this servlet
+ * context.
+ *
+ * <p>The registered filter may be further configured via the returned
+ * {@link FilterRegistration} object.
+ *
+ * <p>The specified <tt>className</tt> will be loaded using the
+ * classloader associated with the application represented by this
+ * ServletContext.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * FilterRegistration for a filter with the given <tt>filterName</tt>,
+ * it will be completed (by assigning the given <tt>className</tt> to it)
+ * and returned.
+ *
+ * <p>This method supports resource injection if the class with the
+ * given <tt>className</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param filterName the name of the filter
+ * @param className the fully qualified class name of the filter
+ *
+ * @return a FilterRegistration object that may be used to further
+ * configure the registered filter, or <tt>null</tt> if this
+ * ServletContext already contains a complete FilterRegistration for
+ * a filter with the given <tt>filterName</tt>
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws IllegalArgumentException if <code>filterName</code> is null or
+ * an empty String
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public FilterRegistration.Dynamic addFilter(
+ String filterName, String className);
+
+
+ /**
+ * Registers the given filter instance with this ServletContext
+ * under the given <tt>filterName</tt>.
+ *
+ * <p>The registered filter may be further configured via the returned
+ * {@link FilterRegistration} object.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * FilterRegistration for a filter with the given <tt>filterName</tt>,
+ * it will be completed (by assigning the class name of the given filter
+ * instance to it) and returned.
+ *
+ * @param filterName the name of the filter
+ * @param filter the filter instance to register
+ *
+ * @return a FilterRegistration object that may be used to further
+ * configure the given filter, or <tt>null</tt> if this
+ * ServletContext already contains a complete FilterRegistration for a
+ * filter with the given <tt>filterName</tt> or if the same filter
+ * instance has already been registered with this or another
+ * ServletContext in the same container
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws IllegalArgumentException if <code>filterName</code> is null or
+ * an empty String
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public FilterRegistration.Dynamic addFilter(
+ String filterName, Filter filter);
+
+
+ /**
+ * Adds the filter with the given name and class type to this servlet
+ * context.
+ *
+ * <p>The registered filter may be further configured via the returned
+ * {@link FilterRegistration} object.
+ *
+ * <p>If this ServletContext already contains a preliminary
+ * FilterRegistration for a filter with the given <tt>filterName</tt>,
+ * it will be completed (by assigning the name of the given
+ * <tt>filterClass</tt> to it) and returned.
+ *
+ * <p>This method supports resource injection if the given
+ * <tt>filterClass</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param filterName the name of the filter
+ * @param filterClass the class object from which the filter will be
+ * instantiated
+ *
+ * @return a FilterRegistration object that may be used to further
+ * configure the registered filter, or <tt>null</tt> if this
+ * ServletContext already contains a complete FilterRegistration for a
+ * filter with the given <tt>filterName</tt>
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws IllegalArgumentException if <code>filterName</code> is null or
+ * an empty String
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public FilterRegistration.Dynamic addFilter(String filterName,
+ Class <? extends Filter> filterClass);
+
+
+ /**
+ * Instantiates the given Filter class.
+ *
+ * <p>The returned Filter instance may be further customized before it
+ * is registered with this ServletContext via a call to
+ * {@link #addFilter(String,Filter)}.
+ *
+ * <p>The given Filter class must define a zero argument constructor,
+ * which is used to instantiate it.
+ *
+ * <p>This method supports resource injection if the given
+ * <tt>clazz</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param <T> the class of the Filter to create
+ * @param clazz the Filter class to instantiate
+ *
+ * @return the new Filter instance
+ *
+ * @throws ServletException if the given <tt>clazz</tt> fails to be
+ * instantiated
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public <T extends Filter> T createFilter(Class<T> clazz)
+ throws ServletException;
+
+
+ /**
+ * Gets the FilterRegistration corresponding to the filter with the
+ * given <tt>filterName</tt>.
+ *
+ * @param filterName the name of a filter
+ * @return the (complete or preliminary) FilterRegistration for the
+ * filter with the given <tt>filterName</tt>, or null if no
+ * FilterRegistration exists under that name
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public FilterRegistration getFilterRegistration(String filterName);
+
+
+ /**
+ * Gets a (possibly empty) Map of the FilterRegistration
+ * objects (keyed by filter name) corresponding to all filters
+ * registered with this ServletContext.
+ *
+ * <p>The returned Map includes the FilterRegistration objects
+ * corresponding to all declared and annotated filters, as well as the
+ * FilterRegistration objects corresponding to all filters that have
+ * been added via one of the <tt>addFilter</tt> methods.
+ *
+ * <p>Any changes to the returned Map must not affect this
+ * ServletContext.
+ *
+ * @return Map of the (complete and preliminary) FilterRegistration
+ * objects corresponding to all filters currently registered with this
+ * ServletContext
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations();
+
+
+ /**
+ * Gets the {@link SessionCookieConfig} object through which various
+ * properties of the session tracking cookies created on behalf of this
+ * <tt>ServletContext</tt> may be configured.
+ *
+ * <p>Repeated invocations of this method will return the same
+ * <tt>SessionCookieConfig</tt> instance.
+ *
+ * @return the <tt>SessionCookieConfig</tt> object through which
+ * various properties of the session tracking cookies created on
+ * behalf of this <tt>ServletContext</tt> may be configured
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public SessionCookieConfig getSessionCookieConfig();
+
+
+ /**
+ * Sets the session tracking modes that are to become effective for this
+ * <tt>ServletContext</tt>.
+ *
+ * <p>The given <tt>sessionTrackingModes</tt> replaces any
+ * session tracking modes set by a previous invocation of this
+ * method on this <tt>ServletContext</tt>.
+ *
+ * @param sessionTrackingModes the set of session tracking modes to
+ * become effective for this <tt>ServletContext</tt>
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @throws IllegalArgumentException if <tt>sessionTrackingModes</tt>
+ * specifies a combination of <tt>SessionTrackingMode.SSL</tt> with a
+ * session tracking mode other than <tt>SessionTrackingMode.SSL</tt>,
+ * or if <tt>sessionTrackingModes</tt> specifies a session tracking mode
+ * that is not supported by the servlet container
+ *
+ * @since Servlet 3.0
+ */
+ public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes);
+
+
+ /**
+ * Gets the session tracking modes that are supported by default for this
+ * <tt>ServletContext</tt>.
+ *
+ * <p>The returned set is not backed by the {@code ServletContext} object,
+ * so changes in the returned set are not reflected in the
+ * {@code ServletContext} object, and vice-versa.</p>
+ *
+ * @return set of the session tracking modes supported by default for
+ * this <tt>ServletContext</tt>
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public Set<SessionTrackingMode> getDefaultSessionTrackingModes();
+
+
+ /**
+ * Gets the session tracking modes that are in effect for this
+ * <tt>ServletContext</tt>.
+ *
+ * <p>The session tracking modes in effect are those provided to
+ * {@link #setSessionTrackingModes setSessionTrackingModes}.
+ *
+ * <p>The returned set is not backed by the {@code ServletContext} object,
+ * so changes in the returned set are not reflected in the
+ * {@code ServletContext} object, and vice-versa.</p>
+ *
+ * @return set of the session tracking modes in effect for this
+ * <tt>ServletContext</tt>
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes();
+
+
+ /**
+ * Adds the listener with the given class name to this ServletContext.
+ *
+ * <p>The class with the given name will be loaded using the
+ * classloader associated with the application represented by this
+ * ServletContext, and must implement one or more of the following
+ * interfaces:
+ * <ul>
+ * <li>{@link ServletContextAttributeListener}
+ * <li>{@link ServletRequestListener}
+ * <li>{@link ServletRequestAttributeListener}
+ * <li>{@link javax.servlet.http.HttpSessionAttributeListener}
+ * <li>{@link javax.servlet.http.HttpSessionIdListener}
+ * <li>{@link javax.servlet.http.HttpSessionListener}
+ * </ul>
+ *
+ * <p>If this ServletContext was passed to
+ * {@link ServletContainerInitializer#onStartup}, then the class with
+ * the given name may also implement {@link ServletContextListener},
+ * in addition to the interfaces listed above.
+ *
+ * <p>As part of this method call, the container must load the class
+ * with the specified class name to ensure that it implements one of
+ * the required interfaces.
+ *
+ * <p>If the class with the given name implements a listener interface
+ * whose invocation order corresponds to the declaration order (i.e.,
+ * if it implements {@link ServletRequestListener},
+ * {@link ServletContextListener}, or
+ * {@link javax.servlet.http.HttpSessionListener}),
+ * then the new listener will be added to the end of the ordered list of
+ * listeners of that interface.
+ *
+ * <p>This method supports resource injection if the class with the
+ * given <tt>className</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param className the fully qualified class name of the listener
+ *
+ * @throws IllegalArgumentException if the class with the given name
+ * does not implement any of the above interfaces, or if it implements
+ * {@link ServletContextListener} and this ServletContext was not
+ * passed to {@link ServletContainerInitializer#onStartup}
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public void addListener(String className);
+
+
+ /**
+ * Adds the given listener to this ServletContext.
+ *
+ * <p>The given listener must be an instance of one or more of the
+ * following interfaces:
+ * <ul>
+ * <li>{@link ServletContextAttributeListener}
+ * <li>{@link ServletRequestListener}
+ * <li>{@link ServletRequestAttributeListener}
+ * <li>{@link javax.servlet.http.HttpSessionAttributeListener}
+ * <li>{@link javax.servlet.http.HttpSessionIdListener}
+ * <li>{@link javax.servlet.http.HttpSessionListener}
+ * </ul>
+ *
+ * <p>If this ServletContext was passed to
+ * {@link ServletContainerInitializer#onStartup}, then the given
+ * listener may also be an instance of {@link ServletContextListener},
+ * in addition to the interfaces listed above.
+ *
+ * <p>If the given listener is an instance of a listener interface whose
+ * invocation order corresponds to the declaration order (i.e., if it
+ * is an instance of {@link ServletRequestListener},
+ * {@link ServletContextListener}, or
+ * {@link javax.servlet.http.HttpSessionListener}),
+ * then the listener will be added to the end of the ordered list of
+ * listeners of that interface.
+ *
+ * @param <T> the class of the EventListener to add
+ * @param t the listener to be added
+ *
+ * @throws IllegalArgumentException if the given listener is not
+ * an instance of any of the above interfaces, or if it is an instance
+ * of {@link ServletContextListener} and this ServletContext was not
+ * passed to {@link ServletContainerInitializer#onStartup}
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public <T extends EventListener> void addListener(T t);
+
+
+ /**
+ * Adds a listener of the given class type to this ServletContext.
+ *
+ * <p>The given <tt>listenerClass</tt> must implement one or more of the
+ * following interfaces:
+ * <ul>
+ * <li>{@link ServletContextAttributeListener}
+ * <li>{@link ServletRequestListener}
+ * <li>{@link ServletRequestAttributeListener}
+ * <li>{@link javax.servlet.http.HttpSessionAttributeListener}
+ * <li>{@link javax.servlet.http.HttpSessionIdListener}
+ * <li>{@link javax.servlet.http.HttpSessionListener}
+ * </ul>
+ *
+ * <p>If this ServletContext was passed to
+ * {@link ServletContainerInitializer#onStartup}, then the given
+ * <tt>listenerClass</tt> may also implement
+ * {@link ServletContextListener}, in addition to the interfaces listed
+ * above.
+ *
+ * <p>If the given <tt>listenerClass</tt> implements a listener
+ * interface whose invocation order corresponds to the declaration order
+ * (i.e., if it implements {@link ServletRequestListener},
+ * {@link ServletContextListener}, or
+ * {@link javax.servlet.http.HttpSessionListener}),
+ * then the new listener will be added to the end of the ordered list
+ * of listeners of that interface.
+ *
+ * <p>This method supports resource injection if the given
+ * <tt>listenerClass</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param listenerClass the listener class to be instantiated
+ *
+ * @throws IllegalArgumentException if the given <tt>listenerClass</tt>
+ * does not implement any of the above interfaces, or if it implements
+ * {@link ServletContextListener} and this ServletContext was not passed
+ * to {@link ServletContainerInitializer#onStartup}
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.0
+ */
+ public void addListener(Class <? extends EventListener> listenerClass);
+
+
+ /**
+ * Instantiates the given EventListener class.
+ *
+ * <p>The specified EventListener class must implement at least one of
+ * the {@link ServletContextListener},
+ * {@link ServletContextAttributeListener},
+ * {@link ServletRequestListener},
+ * {@link ServletRequestAttributeListener},
+ * {@link javax.servlet.http.HttpSessionAttributeListener},
+ * {@link javax.servlet.http.HttpSessionIdListener}, or
+ * {@link javax.servlet.http.HttpSessionListener}
+ * interfaces.
+ *
+ * <p>The returned EventListener instance may be further customized
+ * before it is registered with this ServletContext via a call to
+ * {@link #addListener(EventListener)}.
+ *
+ * <p>The given EventListener class must define a zero argument
+ * constructor, which is used to instantiate it.
+ *
+ * <p>This method supports resource injection if the given
+ * <tt>clazz</tt> represents a Managed Bean.
+ * See the Java EE platform and JSR 299 specifications for additional
+ * details about Managed Beans and resource injection.
+ *
+ * @param <T> the class of the EventListener to create
+ * @param clazz the EventListener class to instantiate
+ *
+ * @return the new EventListener instance
+ *
+ * @throws ServletException if the given <tt>clazz</tt> fails to be
+ * instantiated
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @throws IllegalArgumentException if the specified EventListener class
+ * does not implement any of the
+ * {@link ServletContextListener},
+ * {@link ServletContextAttributeListener},
+ * {@link ServletRequestListener},
+ * {@link ServletRequestAttributeListener},
+ * {@link javax.servlet.http.HttpSessionAttributeListener},
+ * {@link javax.servlet.http.HttpSessionIdListener}, or
+ * {@link javax.servlet.http.HttpSessionListener}
+ * interfaces.
+ *
+ * @since Servlet 3.0
+ */
+ public <T extends EventListener> T createListener(Class<T> clazz)
+ throws ServletException;
+
+
+ /**
+ * Gets the <code><jsp-config></code> related configuration
+ * that was aggregated from the <code>web.xml</code> and
+ * <code>web-fragment.xml</code> descriptor files of the web application
+ * represented by this ServletContext.
+ *
+ * @return the <code><jsp-config></code> related configuration
+ * that was aggregated from the <code>web.xml</code> and
+ * <code>web-fragment.xml</code> descriptor files of the web application
+ * represented by this ServletContext, or null if no such configuration
+ * exists
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @see javax.servlet.descriptor.JspConfigDescriptor
+ *
+ * @since Servlet 3.0
+ */
+ public JspConfigDescriptor getJspConfigDescriptor();
+
+
+ /**
+ * Gets the class loader of the web application represented by this
+ * ServletContext.
+ *
+ * <p>If a security manager exists, and the caller's class loader
+ * is not the same as, or an ancestor of the requested class loader,
+ * then the security manager's <code>checkPermission</code> method is
+ * called with a <code>RuntimePermission("getClassLoader")</code>
+ * permission to check whether access to the requested class loader
+ * should be granted.
+ *
+ * @return the class loader of the web application represented by this
+ * ServletContext
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @throws SecurityException if a security manager denies access to
+ * the requested class loader
+ *
+ * @since Servlet 3.0
+ */
+ public ClassLoader getClassLoader();
+
+
+ /**
+ * Declares role names that are tested using <code>isUserInRole</code>.
+ *
+ * <p>Roles that are implicitly declared as a result of their use within
+ * the {@link ServletRegistration.Dynamic#setServletSecurity
+ * setServletSecurity} or {@link ServletRegistration.Dynamic#setRunAsRole
+ * setRunAsRole} methods of the {@link ServletRegistration} interface need
+ * not be declared.
+ *
+ * @param roleNames the role names being declared
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @throws IllegalArgumentException if any of the argument roleNames is
+ * null or the empty string
+ *
+ * @throws IllegalStateException if the ServletContext has already
+ * been initialized
+ *
+ * @since Servlet 3.0
+ */
+ public void declareRoles(String... roleNames);
+
+
+ /**
+ * Returns the configuration name of the logical host on which the
+ * ServletContext is deployed.
+ *
+ * Servlet containers may support multiple logical hosts. This method must
+ * return the same name for all the servlet contexts deployed on a logical
+ * host, and the name returned by this method must be distinct, stable per
+ * logical host, and suitable for use in associating server configuration
+ * information with the logical host. The returned value is NOT expected
+ * or required to be equivalent to a network address or hostname of the
+ * logical host.
+ *
+ * @return a <code>String</code> containing the configuration name of the
+ * logical host on which the servlet context is deployed.
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 3.1
+ */
+ public String getVirtualServerName();
+
+
+ /**
+ * Gets the session timeout in minutes that are supported by default for
+ * this <tt>ServletContext</tt>.
+ *
+ * @return the session timeout in minutes that are supported by default for
+ * this <tt>ServletContext</tt>
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public int getSessionTimeout();
+
+
+ /**
+ * Sets the session timeout in minutes for this ServletContext.
+ *
+ * @param sessionTimeout session timeout in minutes
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public void setSessionTimeout(int sessionTimeout);
+
+
+ /**
+ * Gets the request character encoding that are supported by default for
+ * this <tt>ServletContext</tt>. This method returns null if no request
+ * encoding character encoding has been specified in deployment descriptor
+ * or container specific configuration (for all web applications in the
+ * container).
+ *
+ * @return the request character encoding that are supported by default for
+ * this <tt>ServletContext</tt>
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public String getRequestCharacterEncoding();
+
+
+ /**
+ * Sets the request character encoding for this ServletContext.
+ *
+ * @param encoding request character encoding
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public void setRequestCharacterEncoding(String encoding);
+
+
+ /**
+ * Gets the response character encoding that are supported by default for
+ * this <tt>ServletContext</tt>. This method returns null if no response
+ * encoding character encoding has been specified in deployment descriptor
+ * or container specific configuration (for all web applications in the
+ * container).
+ *
+ * @return the request character encoding that are supported by default for
+ * this <tt>ServletContext</tt>
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public String getResponseCharacterEncoding();
+
+
+ /**
+ * Sets the response character encoding for this ServletContext.
+ *
+ * @param encoding response character encoding
+ *
+ * @throws IllegalStateException if this ServletContext has already
+ * been initialized
+ *
+ * @throws UnsupportedOperationException if this ServletContext was
+ * passed to the {@link ServletContextListener#contextInitialized} method
+ * of a {@link ServletContextListener} that was neither declared in
+ * <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated
+ * with {@link javax.servlet.annotation.WebListener}
+ *
+ * @since Servlet 4.0
+ */
+ public void setResponseCharacterEncoding(String encoding);
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextAttributeEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextAttributeEvent.java
new file mode 100644
index 0000000..8ebc5fd
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextAttributeEvent.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+/**
+ * Event class for notifications about changes to the attributes of
+ * the ServletContext of a web application.
+ *
+ * @see ServletContextAttributeListener
+ *
+ * @since Servlet 2.3
+ */
+
+public class ServletContextAttributeEvent extends ServletContextEvent {
+
+ private static final long serialVersionUID = -5804680734245618303L;
+
+ private String name;
+ private Object value;
+
+ /**
+ * Constructs a ServletContextAttributeEvent from the given
+ * ServletContext, attribute name, and attribute value.
+ *
+ * @param source the ServletContext whose attribute changed
+ * @param name the name of the ServletContext attribute that changed
+ * @param value the value of the ServletContext attribute that changed
+ */
+ public ServletContextAttributeEvent(ServletContext source,
+ String name, Object value) {
+ super(source);
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Gets the name of the ServletContext attribute that changed.
+ *
+ * @return the name of the ServletContext attribute that changed
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Gets the value of the ServletContext attribute that changed.
+ *
+ * <p>If the attribute was added, this is the value of the attribute.
+ * If the attribute was removed, this is the value of the removed
+ * attribute. If the attribute was replaced, this is the old value of
+ * the attribute.
+ *
+ * @return the value of the ServletContext attribute that changed
+ */
+ public Object getValue() {
+ return this.value;
+ }
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextAttributeListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextAttributeListener.java
new file mode 100644
index 0000000..2e10f8e
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextAttributeListener.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about ServletContext
+ * attribute changes.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link ServletContext}.
+ *
+ * <p>The order in which implementations of this interface are invoked is
+ * unspecified.
+ *
+ * @see ServletContextAttributeEvent
+ *
+ * @since Servlet 2.3
+ */
+
+public interface ServletContextAttributeListener extends EventListener {
+
+ /**
+ * Receives notification that an attribute has been added to the
+ * ServletContext.
+ *
+ * @param event the ServletContextAttributeEvent containing the
+ * ServletContext to which the attribute was added, along with the
+ * attribute name and value
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void attributeAdded(ServletContextAttributeEvent event) {}
+
+ /**
+ * Receives notification that an attribute has been removed
+ * from the ServletContext.
+ *
+ * @param event the ServletContextAttributeEvent containing the
+ * ServletContext from which the attribute was removed, along with
+ * the attribute name and value
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void attributeRemoved(ServletContextAttributeEvent event) {}
+
+ /*
+ * Receives notification that an attribute has been replaced
+ * in the ServletContext.
+ *
+ * @param event the ServletContextAttributeEvent containing the
+ * ServletContext in which the attribute was replaced, along with
+ * the attribute name and its old value
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void attributeReplaced(ServletContextAttributeEvent event) {}
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextEvent.java
new file mode 100644
index 0000000..8e3eca2
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextEvent.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+/**
+ * This is the event class for notifications about changes to
+ * the servlet context of a web application.
+ * @see ServletContextListener
+ *
+ * @since Servlet 2.3
+ */
+
+public class ServletContextEvent extends java.util.EventObject {
+
+ private static final long serialVersionUID = -7501701636134222423L;
+
+ /** Construct a ServletContextEvent from the given context.
+ *
+ * @param source - the ServletContext that is sending the event.
+ */
+ public ServletContextEvent(ServletContext source) {
+ super(source);
+ }
+
+ /**
+ * Return the ServletContext that changed.
+ *
+ * @return the ServletContext that sent the event.
+ */
+ public ServletContext getServletContext () {
+ return (ServletContext) super.getSource();
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextListener.java
new file mode 100644
index 0000000..d37e58d
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletContextListener.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about ServletContext
+ * lifecycle changes.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link ServletContext}.
+ *
+ * <p>Implementations of this interface are invoked at their
+ * {@link #contextInitialized} method in the order in which they have been
+ * declared, and at their {@link #contextDestroyed} method in reverse
+ * order.
+ *
+ * @see ServletContextEvent
+ *
+ * @since Servlet 2.3
+ */
+public interface ServletContextListener extends EventListener {
+
+ /**
+ * Receives notification that the web application initialization
+ * process is starting.
+ *
+ * <p>All ServletContextListeners are notified of context
+ * initialization before any filters or servlets in the web
+ * application are initialized.
+ *
+ * @param sce the ServletContextEvent containing the ServletContext
+ * that is being initialized
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void contextInitialized(ServletContextEvent sce) {}
+
+ /**
+ * Receives notification that the ServletContext is about to be
+ * shut down.
+ *
+ * <p>All servlets and filters will have been destroyed before any
+ * ServletContextListeners are notified of context
+ * destruction.
+ *
+ * @param sce the ServletContextEvent containing the ServletContext
+ * that is being destroyed
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void contextDestroyed(ServletContextEvent sce) {}
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletException.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletException.java
new file mode 100644
index 0000000..375bb29
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletException.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+
+/**
+ * Defines a general exception a servlet can throw when it
+ * encounters difficulty.
+ *
+ * @author Various
+ */
+
+
+public class ServletException extends Exception {
+
+ private Throwable rootCause;
+
+
+
+
+
+ /**
+ * Constructs a new servlet exception.
+ *
+ */
+
+ public ServletException() {
+ super();
+ }
+
+
+
+
+
+ /**
+ * Constructs a new servlet exception with the
+ * specified message. The message can be written
+ * to the server log and/or displayed for the user.
+ *
+ * @param message a <code>String</code>
+ * specifying the text of
+ * the exception message
+ *
+ */
+
+ public ServletException(String message) {
+ super(message);
+ }
+
+
+
+
+
+ /**
+ * Constructs a new servlet exception when the servlet
+ * needs to throw an exception and include a message
+ * about the "root cause" exception that interfered with its
+ * normal operation, including a description message.
+ *
+ *
+ * @param message a <code>String</code> containing
+ * the text of the exception message
+ *
+ * @param rootCause the <code>Throwable</code> exception
+ * that interfered with the servlet's
+ * normal operation, making this servlet
+ * exception necessary
+ *
+ */
+
+ public ServletException(String message, Throwable rootCause) {
+ super(message, rootCause);
+ this.rootCause = rootCause;
+ }
+
+
+
+
+
+ /**
+ * Constructs a new servlet exception when the servlet
+ * needs to throw an exception and include a message
+ * about the "root cause" exception that interfered with its
+ * normal operation. The exception's message is based on the localized
+ * message of the underlying exception.
+ *
+ * <p>This method calls the <code>getLocalizedMessage</code> method
+ * on the <code>Throwable</code> exception to get a localized exception
+ * message. When subclassing <code>ServletException</code>,
+ * this method can be overridden to create an exception message
+ * designed for a specific locale.
+ *
+ * @param rootCause the <code>Throwable</code> exception
+ * that interfered with the servlet's
+ * normal operation, making the servlet exception
+ * necessary
+ *
+ */
+
+ public ServletException(Throwable rootCause) {
+ super(rootCause);
+ this.rootCause = rootCause;
+ }
+
+
+
+
+
+ /**
+ * Returns the exception that caused this servlet exception.
+ *
+ *
+ * @return the <code>Throwable</code>
+ * that caused this servlet exception
+ *
+ */
+
+ public Throwable getRootCause() {
+ return rootCause;
+ }
+}
+
+
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletInputStream.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletInputStream.java
new file mode 100644
index 0000000..a0369ab
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletInputStream.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ *
+ * Provides an input stream for reading binary data from a client
+ * request, including an efficient <code>readLine</code> method
+ * for reading data one line at a time. With some protocols, such
+ * as HTTP POST and PUT, a <code>ServletInputStream</code>
+ * object can be used to read data sent from the client.
+ *
+ * <p>A <code>ServletInputStream</code> object is normally retrieved via
+ * the {@link ServletRequest#getInputStream} method.
+ *
+ *
+ * <p>This is an abstract class that a servlet container implements.
+ * Subclasses of this class
+ * must implement the <code>java.io.InputStream.read()</code> method.
+ *
+ *
+ * @author Various
+ *
+ * @see ServletRequest
+ *
+ */
+
+public abstract class ServletInputStream extends InputStream {
+
+
+
+ /**
+ * Does nothing, because this is an abstract class.
+ *
+ */
+
+ protected ServletInputStream() { }
+
+
+
+
+ /**
+ *
+ * Reads the input stream, one line at a time. Starting at an
+ * offset, reads bytes into an array, until it reads a certain number
+ * of bytes or reaches a newline character, which it reads into the
+ * array as well.
+ *
+ * <p>This method returns -1 if it reaches the end of the input
+ * stream before reading the maximum number of bytes.
+ *
+ *
+ *
+ * @param b an array of bytes into which data is read
+ *
+ * @param off an integer specifying the character at which
+ * this method begins reading
+ *
+ * @param len an integer specifying the maximum number of
+ * bytes to read
+ *
+ * @return an integer specifying the actual number of bytes
+ * read, or -1 if the end of the stream is reached
+ *
+ * @exception IOException if an input or output exception has occurred
+ *
+ */
+ public int readLine(byte[] b, int off, int len) throws IOException {
+
+ if (len <= 0) {
+ return 0;
+ }
+ int count = 0, c;
+
+ while ((c = read()) != -1) {
+ b[off++] = (byte)c;
+ count++;
+ if (c == '\n' || count == len) {
+ break;
+ }
+ }
+ return count > 0 ? count : -1;
+ }
+
+
+ /**
+ * Returns true when all the data from the stream has been read else
+ * it returns false.
+ *
+ * @return <code>true</code> when all data for this particular request
+ * has been read, otherwise returns <code>false</code>.
+ *
+ * @since Servlet 3.1
+ */
+ public abstract boolean isFinished();
+
+ /**
+ * Returns true if data can be read without blocking else returns
+ * false.
+ *
+ * @return <code>true</code> if data can be obtained without blocking,
+ * otherwise returns <code>false</code>.
+ *
+ * @since Servlet 3.1
+ */
+ public abstract boolean isReady();
+
+ /**
+ * Instructs the <code>ServletInputStream</code> to invoke the provided
+ * {@link ReadListener} when it is possible to read
+ *
+ * @param readListener the {@link ReadListener} that should be notified
+ * when it's possible to read.
+ *
+ * @exception IllegalStateException if one of the following conditions is true
+ * <ul>
+ * <li>the associated request is neither upgraded nor the async started
+ * <li>setReadListener is called more than once within the scope of the same request.
+ * </ul>
+ *
+ * @throws NullPointerException if readListener is null
+ *
+ * @since Servlet 3.1
+
+ */
+ public abstract void setReadListener(ReadListener readListener);
+}
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletOutputStream.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletOutputStream.java
new file mode 100644
index 0000000..efcd1e5
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletOutputStream.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.CharConversionException;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ * Provides an output stream for sending binary data to the
+ * client. A <code>ServletOutputStream</code> object is normally retrieved
+ * via the {@link ServletResponse#getOutputStream} method.
+ *
+ * <p>This is an abstract class that the servlet container implements.
+ * Subclasses of this class
+ * must implement the <code>java.io.OutputStream.write(int)</code>
+ * method.
+ *
+ *
+ * @author Various
+ *
+ * @see ServletResponse
+ *
+ */
+
+public abstract class ServletOutputStream extends OutputStream {
+
+ private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+
+
+ /**
+ *
+ * Does nothing, because this is an abstract class.
+ *
+ */
+
+ protected ServletOutputStream() { }
+
+
+ /**
+ * Writes a <code>String</code> to the client,
+ * without a carriage return-line feed (CRLF)
+ * character at the end.
+ *
+ *
+ * @param s the <code>String</code> to send to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void print(String s) throws IOException {
+ if (s==null) s="null";
+ int len = s.length();
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt (i);
+
+ //
+ // XXX NOTE: This is clearly incorrect for many strings,
+ // but is the only consistent approach within the current
+ // servlet framework. It must suffice until servlet output
+ // streams properly encode their output.
+ //
+ if ((c & 0xff00) != 0) { // high order byte must be zero
+ String errMsg = lStrings.getString("err.not_iso8859_1");
+ Object[] errArgs = new Object[1];
+ errArgs[0] = Character.valueOf(c);
+ errMsg = MessageFormat.format(errMsg, errArgs);
+ throw new CharConversionException(errMsg);
+ }
+ write (c);
+ }
+ }
+
+
+
+ /**
+ * Writes a <code>boolean</code> value to the client,
+ * with no carriage return-line feed (CRLF)
+ * character at the end.
+ *
+ * @param b the <code>boolean</code> value
+ * to send to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void print(boolean b) throws IOException {
+ String msg;
+ if (b) {
+ msg = lStrings.getString("value.true");
+ } else {
+ msg = lStrings.getString("value.false");
+ }
+ print(msg);
+ }
+
+
+
+ /**
+ * Writes a character to the client,
+ * with no carriage return-line feed (CRLF)
+ * at the end.
+ *
+ * @param c the character to send to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void print(char c) throws IOException {
+ print(String.valueOf(c));
+ }
+
+
+
+
+ /**
+ *
+ * Writes an int to the client,
+ * with no carriage return-line feed (CRLF)
+ * at the end.
+ *
+ * @param i the int to send to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void print(int i) throws IOException {
+ print(String.valueOf(i));
+ }
+
+
+
+
+ /**
+ *
+ * Writes a <code>long</code> value to the client,
+ * with no carriage return-line feed (CRLF) at the end.
+ *
+ * @param l the <code>long</code> value
+ * to send to the client
+ *
+ * @exception IOException if an input or output exception
+ * occurred
+ *
+ */
+
+ public void print(long l) throws IOException {
+ print(String.valueOf(l));
+ }
+
+
+
+ /**
+ *
+ * Writes a <code>float</code> value to the client,
+ * with no carriage return-line feed (CRLF) at the end.
+ *
+ * @param f the <code>float</code> value
+ * to send to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ *
+ */
+
+ public void print(float f) throws IOException {
+ print(String.valueOf(f));
+ }
+
+
+
+ /**
+ *
+ * Writes a <code>double</code> value to the client,
+ * with no carriage return-line feed (CRLF) at the end.
+ *
+ * @param d the <code>double</code> value
+ * to send to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void print(double d) throws IOException {
+ print(String.valueOf(d));
+ }
+
+
+
+ /**
+ * Writes a carriage return-line feed (CRLF)
+ * to the client.
+ *
+ *
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println() throws IOException {
+ print("\r\n");
+ }
+
+
+
+ /**
+ * Writes a <code>String</code> to the client,
+ * followed by a carriage return-line feed (CRLF).
+ *
+ *
+ * @param s the <code>String</code> to write to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println(String s) throws IOException {
+ print(s);
+ println();
+ }
+
+
+
+
+ /**
+ *
+ * Writes a <code>boolean</code> value to the client,
+ * followed by a
+ * carriage return-line feed (CRLF).
+ *
+ *
+ * @param b the <code>boolean</code> value
+ * to write to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println(boolean b) throws IOException {
+ print(b);
+ println();
+ }
+
+
+
+ /**
+ *
+ * Writes a character to the client, followed by a carriage
+ * return-line feed (CRLF).
+ *
+ * @param c the character to write to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println(char c) throws IOException {
+ print(c);
+ println();
+ }
+
+
+
+ /**
+ *
+ * Writes an int to the client, followed by a
+ * carriage return-line feed (CRLF) character.
+ *
+ *
+ * @param i the int to write to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println(int i) throws IOException {
+ print(i);
+ println();
+ }
+
+
+
+ /**
+ *
+ * Writes a <code>long</code> value to the client, followed by a
+ * carriage return-line feed (CRLF).
+ *
+ *
+ * @param l the <code>long</code> value to write to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println(long l) throws IOException {
+ print(l);
+ println();
+ }
+
+
+
+ /**
+ *
+ * Writes a <code>float</code> value to the client,
+ * followed by a carriage return-line feed (CRLF).
+ *
+ * @param f the <code>float</code> value
+ * to write to the client
+ *
+ *
+ * @exception IOException if an input or output exception
+ * occurred
+ *
+ */
+
+ public void println(float f) throws IOException {
+ print(f);
+ println();
+ }
+
+
+
+ /**
+ *
+ * Writes a <code>double</code> value to the client,
+ * followed by a carriage return-line feed (CRLF).
+ *
+ *
+ * @param d the <code>double</code> value
+ * to write to the client
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ */
+
+ public void println(double d) throws IOException {
+ print(d);
+ println();
+ }
+
+ /**
+ * This method can be used to determine if data can be written without blocking.
+ *
+ * @return <code>true</code> if a write to this <code>ServletOutputStream</code>
+ * will succeed, otherwise returns <code>false</code>.
+ *
+ * @since Servlet 3.1
+ */
+ public abstract boolean isReady();
+
+ /**
+ * Instructs the <code>ServletOutputStream</code> to invoke the provided
+ * {@link WriteListener} when it is possible to write
+ *
+ *
+ * @param writeListener the {@link WriteListener} that should be notified
+ * when it's possible to write
+ *
+ * @exception IllegalStateException if one of the following conditions is true
+ * <ul>
+ * <li>the associated request is neither upgraded nor the async started
+ * <li>setWriteListener is called more than once within the scope of the same request.
+ * </ul>
+ *
+ * @throws NullPointerException if writeListener is null
+ *
+ * @since Servlet 3.1
+ */
+ public abstract void setWriteListener(WriteListener writeListener);
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRegistration.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRegistration.java
new file mode 100644
index 0000000..26037e3
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRegistration.java
@@ -0,0 +1,220 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.util.*;
+
+/**
+ * Interface through which a {@link Servlet} may be further configured.
+ *
+ * @since Servlet 3.0
+ */
+public interface ServletRegistration extends Registration {
+
+ /**
+ * Adds a servlet mapping with the given URL patterns for the Servlet
+ * represented by this ServletRegistration.
+ *
+ * <p>If any of the specified URL patterns are already mapped to a
+ * different Servlet, no updates will be performed.
+ *
+ * <p>If this method is called multiple times, each successive call
+ * adds to the effects of the former.
+ *
+ * <p>The returned set is not backed by the {@code ServletRegistration}
+ * object, so changes in the returned set are not reflected in the
+ * {@code ServletRegistration} object, and vice-versa.</p>
+ *
+ * @param urlPatterns the URL patterns of the servlet mapping
+ *
+ * @return the (possibly empty) Set of URL patterns that are already
+ * mapped to a different Servlet
+ *
+ * @throws IllegalArgumentException if <tt>urlPatterns</tt> is null
+ * or empty
+ * @throws IllegalStateException if the ServletContext from which this
+ * ServletRegistration was obtained has already been initialized
+ */
+ public Set<String> addMapping(String... urlPatterns);
+
+ /**
+ * Gets the currently available mappings of the
+ * Servlet represented by this <code>ServletRegistration</code>.
+ *
+ * <p>If permitted, any changes to the returned <code>Collection</code> must not
+ * affect this <code>ServletRegistration</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the currently
+ * available mappings of the Servlet represented by this
+ * <code>ServletRegistration</code>
+ */
+ public Collection<String> getMappings();
+
+ /**
+ * Gets the name of the runAs role of the Servlet represented by this
+ * <code>ServletRegistration</code>.
+ *
+ * @return the name of the runAs role, or null if the Servlet is
+ * configured to run as its caller
+ */
+ public String getRunAsRole();
+
+ /**
+ * Interface through which a {@link Servlet} registered via one of the
+ * <tt>addServlet</tt> methods on {@link ServletContext} may be further
+ * configured.
+ */
+ interface Dynamic extends ServletRegistration, Registration.Dynamic {
+
+ /**
+ * Sets the <code>loadOnStartup</code> priority on the Servlet
+ * represented by this dynamic ServletRegistration.
+ *
+ * <p>A <tt>loadOnStartup</tt> value of greater than or equal to
+ * zero indicates to the container the initialization priority of
+ * the Servlet. In this case, the container must instantiate and
+ * initialize the Servlet during the initialization phase of the
+ * ServletContext, that is, after it has invoked all of the
+ * ServletContextListener objects configured for the ServletContext
+ * at their {@link ServletContextListener#contextInitialized}
+ * method.
+ *
+ * <p>If <tt>loadOnStartup</tt> is a negative integer, the container
+ * is free to instantiate and initialize the Servlet lazily.
+ *
+ * <p>The default value for <tt>loadOnStartup</tt> is <code>-1</code>.
+ *
+ * <p>A call to this method overrides any previous setting.
+ *
+ * @param loadOnStartup the initialization priority of the Servlet
+ *
+ * @throws IllegalStateException if the ServletContext from which
+ * this ServletRegistration was obtained has already been initialized
+ */
+ public void setLoadOnStartup(int loadOnStartup);
+
+ /**
+ * Sets the {@link ServletSecurityElement} to be applied to the
+ * mappings defined for this <code>ServletRegistration</code>.
+ *
+ * <p>This method applies to all mappings added to this
+ * <code>ServletRegistration</code> up until the point that the
+ * <code>ServletContext</code> from which it was obtained has been
+ * initialized.
+ *
+ * <p>If a URL pattern of this ServletRegistration is an exact target
+ * of a <code>security-constraint</code> that was established via
+ * the portable deployment descriptor, then this method does not
+ * change the <code>security-constraint</code> for that pattern,
+ * and the pattern will be included in the return value.
+ *
+ * <p>If a URL pattern of this ServletRegistration is an exact
+ * target of a security constraint that was established via the
+ * {@link javax.servlet.annotation.ServletSecurity} annotation
+ * or a previous call to this method, then this method replaces
+ * the security constraint for that pattern.
+ *
+ * <p>If a URL pattern of this ServletRegistration is neither the
+ * exact target of a security constraint that was established via
+ * the {@link javax.servlet.annotation.ServletSecurity} annotation
+ * or a previous call to this method, nor the exact target of a
+ * <code>security-constraint</code> in the portable deployment
+ * descriptor, then this method establishes the security constraint
+ * for that pattern from the argument
+ * <code>ServletSecurityElement</code>.
+ *
+ * <p>The returned set is not backed by the {@code Dynamic} object,
+ * so changes in the returned set are not reflected in the
+ * {@code Dynamic} object, and vice-versa.</p>
+ *
+ * @param constraint the {@link ServletSecurityElement} to be applied
+ * to the patterns mapped to this ServletRegistration
+ *
+ * @return the (possibly empty) Set of URL patterns that were already
+ * the exact target of a <code>security-constraint</code> that was
+ * established via the portable deployment descriptor. This method
+ * has no effect on the patterns included in the returned set
+ *
+ * @throws IllegalArgumentException if <tt>constraint</tt> is null
+ *
+ * @throws IllegalStateException if the {@link ServletContext} from
+ * which this <code>ServletRegistration</code> was obtained has
+ * already been initialized
+ */
+ public Set<String> setServletSecurity(ServletSecurityElement constraint);
+
+ /**
+ * Sets the {@link MultipartConfigElement} to be applied to the
+ * mappings defined for this <code>ServletRegistration</code>. If this
+ * method is called multiple times, each successive call overrides the
+ * effects of the former.
+ *
+ * @param multipartConfig the {@link MultipartConfigElement} to be
+ * applied to the patterns mapped to the registration
+ *
+ * @throws IllegalArgumentException if <tt>multipartConfig</tt> is
+ * null
+ *
+ * @throws IllegalStateException if the {@link ServletContext} from
+ * which this ServletRegistration was obtained has already been
+ * initialized
+ */
+ public void setMultipartConfig(
+ MultipartConfigElement multipartConfig);
+
+ /**
+ * Sets the name of the <code>runAs</code> role for this
+ * <code>ServletRegistration</code>.
+ *
+ * @param roleName the name of the <code>runAs</code> role
+ *
+ * @throws IllegalArgumentException if <tt>roleName</tt> is null
+ *
+ * @throws IllegalStateException if the {@link ServletContext} from
+ * which this ServletRegistration was obtained has already been
+ * initialized
+ */
+ public void setRunAsRole(String roleName);
+
+ }
+
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequest.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequest.java
new file mode 100644
index 0000000..979898e
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequest.java
@@ -0,0 +1,687 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Defines an object to provide client request information to a servlet. The
+ * servlet container creates a <code>ServletRequest</code> object and passes
+ * it as an argument to the servlet's <code>service</code> method.
+ *
+ * <p>A <code>ServletRequest</code> object provides data including
+ * parameter name and values, attributes, and an input stream.
+ * Interfaces that extend <code>ServletRequest</code> can provide
+ * additional protocol-specific data (for example, HTTP data is
+ * provided by {@link javax.servlet.http.HttpServletRequest}.
+ *
+ * @author Various
+ *
+ * @see javax.servlet.http.HttpServletRequest
+ *
+ */
+public interface ServletRequest {
+
+ /**
+ * Returns the value of the named attribute as an <code>Object</code>,
+ * or <code>null</code> if no attribute of the given name exists.
+ *
+ * <p> Attributes can be set two ways. The servlet container may set
+ * attributes to make available custom information about a request.
+ * For example, for requests made using HTTPS, the attribute
+ * <code>javax.servlet.request.X509Certificate</code> can be used to
+ * retrieve information on the certificate of the client. Attributes
+ * can also be set programatically using
+ * {@link ServletRequest#setAttribute}. This allows information to be
+ * embedded into a request before a {@link RequestDispatcher} call.
+ *
+ * <p>Attribute names should follow the same conventions as package
+ * names. This specification reserves names matching <code>java.*</code>,
+ * <code>javax.*</code>, and <code>sun.*</code>.
+ *
+ * @param name a <code>String</code> specifying the name of the attribute
+ *
+ * @return an <code>Object</code> containing the value of the attribute,
+ * or <code>null</code> if the attribute does not exist
+ */
+ public Object getAttribute(String name);
+
+ /**
+ * Returns an <code>Enumeration</code> containing the
+ * names of the attributes available to this request.
+ * This method returns an empty <code>Enumeration</code>
+ * if the request has no attributes available to it.
+ *
+ * @return an <code>Enumeration</code> of strings containing the names
+ * of the request's attributes
+ */
+ public Enumeration<String> getAttributeNames();
+
+ /**
+ * Returns the name of the character encoding used in the body of this
+ * request. This method returns <code>null</code> if no request encoding
+ * character encoding has been specified. The following methods for
+ * specifying the request character encoding are consulted, in decreasing
+ * order of priority: per request, per web app (using
+ * {@link ServletContext#setRequestCharacterEncoding}, deployment
+ * descriptor), and per container (for all web applications deployed in
+ * that container, using vendor specific configuration).
+ *
+ * @return a <code>String</code> containing the name of the character
+ * encoding, or <code>null</code> if the request does not specify a
+ * character encoding
+ */
+ public String getCharacterEncoding();
+
+ /**
+ * Overrides the name of the character encoding used in the body of this
+ * request. This method must be called prior to reading request parameters
+ * or reading input using getReader(). Otherwise, it has no effect.
+ *
+ * @param env <code>String</code> containing the name of
+ * the character encoding.
+ *
+ * @throws UnsupportedEncodingException if this ServletRequest is still
+ * in a state where a character encoding may be set,
+ * but the specified encoding is invalid
+ */
+ public void setCharacterEncoding(String env) throws UnsupportedEncodingException;
+
+ /**
+ * Returns the length, in bytes, of the request body and made available by
+ * the input stream, or -1 if the length is not known ir is greater than
+ * Integer.MAX_VALUE. For HTTP servlets,
+ * same as the value of the CGI variable CONTENT_LENGTH.
+ *
+ * @return an integer containing the length of the request body or -1 if
+ * the length is not known or is greater than Integer.MAX_VALUE.
+ */
+ public int getContentLength();
+
+ /**
+ * Returns the length, in bytes, of the request body and made available by
+ * the input stream, or -1 if the length is not known. For HTTP servlets,
+ * same as the value of the CGI variable CONTENT_LENGTH.
+ *
+ * @return a long containing the length of the request body or -1L if
+ * the length is not known
+ *
+ * @since Servlet 3.1
+ */
+ public long getContentLengthLong();
+
+ /**
+ * Returns the MIME type of the body of the request, or
+ * <code>null</code> if the type is not known. For HTTP servlets,
+ * same as the value of the CGI variable CONTENT_TYPE.
+ *
+ * @return a <code>String</code> containing the name of the MIME type
+ * of the request, or null if the type is not known
+ */
+ public String getContentType();
+
+ /**
+ * Retrieves the body of the request as binary data using
+ * a {@link ServletInputStream}. Either this method or
+ * {@link #getReader} may be called to read the body, not both.
+ *
+ * @return a {@link ServletInputStream} object containing
+ * the body of the request
+ *
+ * @exception IllegalStateException if the {@link #getReader} method
+ * has already been called for this request
+ *
+ * @exception IOException if an input or output exception occurred
+ */
+ public ServletInputStream getInputStream() throws IOException;
+
+ /**
+ * Returns the value of a request parameter as a <code>String</code>,
+ * or <code>null</code> if the parameter does not exist. Request parameters
+ * are extra information sent with the request. For HTTP servlets,
+ * parameters are contained in the query string or posted form data.
+ *
+ * <p>You should only use this method when you are sure the
+ * parameter has only one value. If the parameter might have
+ * more than one value, use {@link #getParameterValues}.
+ *
+ * <p>If you use this method with a multivalued
+ * parameter, the value returned is equal to the first value
+ * in the array returned by <code>getParameterValues</code>.
+ *
+ * <p>If the parameter data was sent in the request body, such as occurs
+ * with an HTTP POST request, then reading the body directly via {@link
+ * #getInputStream} or {@link #getReader} can interfere
+ * with the execution of this method.
+ *
+ * @param name a <code>String</code> specifying the name of the parameter
+ *
+ * @return a <code>String</code> representing the single value of
+ * the parameter
+ *
+ * @see #getParameterValues
+ */
+ public String getParameter(String name);
+
+ /**
+ *
+ * Returns an <code>Enumeration</code> of <code>String</code>
+ * objects containing the names of the parameters contained
+ * in this request. If the request has
+ * no parameters, the method returns an empty <code>Enumeration</code>.
+ *
+ * @return an <code>Enumeration</code> of <code>String</code>
+ * objects, each <code>String</code> containing the name of
+ * a request parameter; or an empty <code>Enumeration</code>
+ * if the request has no parameters
+ */
+ public Enumeration<String> getParameterNames();
+
+ /**
+ * Returns an array of <code>String</code> objects containing
+ * all of the values the given request parameter has, or
+ * <code>null</code> if the parameter does not exist.
+ *
+ * <p>If the parameter has a single value, the array has a length
+ * of 1.
+ *
+ * @param name a <code>String</code> containing the name of
+ * the parameter whose value is requested
+ *
+ * @return an array of <code>String</code> objects
+ * containing the parameter's values
+ *
+ * @see #getParameter
+ */
+ public String[] getParameterValues(String name);
+
+ /**
+ * Returns a java.util.Map of the parameters of this request.
+ *
+ * <p>Request parameters are extra information sent with the request.
+ * For HTTP servlets, parameters are contained in the query string or
+ * posted form data.
+ *
+ * @return an immutable java.util.Map containing parameter names as
+ * keys and parameter values as map values. The keys in the parameter
+ * map are of type String. The values in the parameter map are of type
+ * String array.
+ */
+ public Map<String, String[]> getParameterMap();
+
+ /**
+ * Returns the name and version of the protocol the request uses
+ * in the form <i>protocol/majorVersion.minorVersion</i>, for
+ * example, HTTP/1.1. For HTTP servlets, the value
+ * returned is the same as the value of the CGI variable
+ * <code>SERVER_PROTOCOL</code>.
+ *
+ * @return a <code>String</code> containing the protocol
+ * name and version number
+ */
+ public String getProtocol();
+
+ /**
+ * Returns the name of the scheme used to make this request,
+ * for example,
+ * <code>http</code>, <code>https</code>, or <code>ftp</code>.
+ * Different schemes have different rules for constructing URLs,
+ * as noted in RFC 1738.
+ *
+ * @return a <code>String</code> containing the name
+ * of the scheme used to make this request
+ */
+ public String getScheme();
+
+ /**
+ * Returns the host name of the server to which the request was sent.
+ * It is the value of the part before ":" in the <code>Host</code>
+ * header value, if any, or the resolved server name, or the server IP
+ * address.
+ *
+ * @return a <code>String</code> containing the name of the server
+ */
+ public String getServerName();
+
+ /**
+ * Returns the port number to which the request was sent.
+ * It is the value of the part after ":" in the <code>Host</code>
+ * header value, if any, or the server port where the client connection
+ * was accepted on.
+ *
+ * @return an integer specifying the port number
+ */
+ public int getServerPort();
+
+ /**
+ * Retrieves the body of the request as character data using
+ * a <code>BufferedReader</code>. The reader translates the character
+ * data according to the character encoding used on the body.
+ * Either this method or {@link #getInputStream} may be called to read the
+ * body, not both.
+ *
+ * @return a <code>BufferedReader</code> containing the body of the request
+ *
+ * @exception UnsupportedEncodingException if the character set encoding
+ * used is not supported and the text cannot be decoded
+ *
+ * @exception IllegalStateException if {@link #getInputStream} method
+ * has been called on this request
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ * @see #getInputStream
+ */
+ public BufferedReader getReader() throws IOException;
+
+ /**
+ * Returns the Internet Protocol (IP) address of the client
+ * or last proxy that sent the request.
+ * For HTTP servlets, same as the value of the
+ * CGI variable <code>REMOTE_ADDR</code>.
+ *
+ * @return a <code>String</code> containing the
+ * IP address of the client that sent the request
+ */
+ public String getRemoteAddr();
+
+ /**
+ * Returns the fully qualified name of the client
+ * or the last proxy that sent the request.
+ * If the engine cannot or chooses not to resolve the hostname
+ * (to improve performance), this method returns the dotted-string form of
+ * the IP address. For HTTP servlets, same as the value of the CGI variable
+ * <code>REMOTE_HOST</code>.
+ *
+ * @return a <code>String</code> containing the fully
+ * qualified name of the client
+ */
+ public String getRemoteHost();
+
+ /**
+ * Stores an attribute in this request.
+ * Attributes are reset between requests. This method is most
+ * often used in conjunction with {@link RequestDispatcher}.
+ *
+ * <p>Attribute names should follow the same conventions as
+ * package names. Names beginning with <code>java.*</code>,
+ * <code>javax.*</code>, and <code>com.sun.*</code>, are
+ * reserved for use by Sun Microsystems.
+ *<br> If the object passed in is null, the effect is the same as
+ * calling {@link #removeAttribute}.
+ * <br> It is warned that when the request is dispatched from the
+ * servlet resides in a different web application by
+ * <code>RequestDispatcher</code>, the object set by this method
+ * may not be correctly retrieved in the caller servlet.
+ *
+ * @param name a <code>String</code> specifying
+ * the name of the attribute
+ *
+ * @param o the <code>Object</code> to be stored
+ *
+ */
+ public void setAttribute(String name, Object o);
+
+ /**
+ *
+ * Removes an attribute from this request. This method is not
+ * generally needed as attributes only persist as long as the request
+ * is being handled.
+ *
+ * <p>Attribute names should follow the same conventions as
+ * package names. Names beginning with <code>java.*</code>,
+ * <code>javax.*</code>, and <code>com.sun.*</code>, are
+ * reserved for use by Sun Microsystems.
+ *
+ * @param name a <code>String</code> specifying
+ * the name of the attribute to remove
+ */
+ public void removeAttribute(String name);
+
+ /**
+ * Returns the preferred <code>Locale</code> that the client will
+ * accept content in, based on the Accept-Language header.
+ * If the client request doesn't provide an Accept-Language header,
+ * this method returns the default locale for the server.
+ *
+ * @return the preferred <code>Locale</code> for the client
+ */
+ public Locale getLocale();
+
+ /**
+ * Returns an <code>Enumeration</code> of <code>Locale</code> objects
+ * indicating, in decreasing order starting with the preferred locale, the
+ * locales that are acceptable to the client based on the Accept-Language
+ * header.
+ * If the client request doesn't provide an Accept-Language header,
+ * this method returns an <code>Enumeration</code> containing one
+ * <code>Locale</code>, the default locale for the server.
+ *
+ * @return an <code>Enumeration</code> of preferred
+ * <code>Locale</code> objects for the client
+ */
+ public Enumeration<Locale> getLocales();
+
+ /**
+ *
+ * Returns a boolean indicating whether this request was made using a
+ * secure channel, such as HTTPS.
+ *
+ * @return a boolean indicating if the request was made using a
+ * secure channel
+ */
+ public boolean isSecure();
+
+ /**
+ *
+ * Returns a {@link RequestDispatcher} object that acts as a wrapper for
+ * the resource located at the given path.
+ * A <code>RequestDispatcher</code> object can be used to forward
+ * a request to the resource or to include the resource in a response.
+ * The resource can be dynamic or static.
+ *
+ * <p>The pathname specified may be relative, although it cannot extend
+ * outside the current servlet context. If the path begins with
+ * a "/" it is interpreted as relative to the current context root.
+ * This method returns <code>null</code> if the servlet container
+ * cannot return a <code>RequestDispatcher</code>.
+ *
+ * <p>The difference between this method and {@link
+ * ServletContext#getRequestDispatcher} is that this method can take a
+ * relative path.
+ *
+ * @param path a <code>String</code> specifying the pathname
+ * to the resource. If it is relative, it must be
+ * relative against the current servlet.
+ *
+ * @return a <code>RequestDispatcher</code> object that acts as a
+ * wrapper for the resource at the specified path,
+ * or <code>null</code> if the servlet container cannot
+ * return a <code>RequestDispatcher</code>
+ *
+ * @see RequestDispatcher
+ * @see ServletContext#getRequestDispatcher
+ */
+ public RequestDispatcher getRequestDispatcher(String path);
+
+ /**
+ * @param path the path for which the real path is to be returned.
+
+ * @return the <i>real</i> path, or <tt>null</tt> if the
+ * translation cannot be performed.
+
+ * @deprecated As of Version 2.1 of the Java Servlet API,
+ * use {@link ServletContext#getRealPath} instead.
+ */
+ public String getRealPath(String path);
+
+ /**
+ * Returns the Internet Protocol (IP) source port of the client
+ * or last proxy that sent the request.
+ *
+ * @return an integer specifying the port number
+ *
+ * @since Servlet 2.4
+ */
+ public int getRemotePort();
+
+ /**
+ * Returns the host name of the Internet Protocol (IP) interface on
+ * which the request was received.
+ *
+ * @return a <code>String</code> containing the host
+ * name of the IP on which the request was received.
+ *
+ * @since Servlet 2.4
+ */
+ public String getLocalName();
+
+ /**
+ * Returns the Internet Protocol (IP) address of the interface on
+ * which the request was received.
+ *
+ * @return a <code>String</code> containing the
+ * IP address on which the request was received.
+ *
+ * @since Servlet 2.4
+ */
+ public String getLocalAddr();
+
+ /**
+ * Returns the Internet Protocol (IP) port number of the interface
+ * on which the request was received.
+ *
+ * @return an integer specifying the port number
+ *
+ * @since Servlet 2.4
+ */
+ public int getLocalPort();
+
+ /**
+ * Gets the servlet context to which this ServletRequest was last
+ * dispatched.
+ *
+ * @return the servlet context to which this ServletRequest was last
+ * dispatched
+ *
+ * @since Servlet 3.0
+ */
+ public ServletContext getServletContext();
+
+ /**
+ * Puts this request into asynchronous mode, and initializes its
+ * {@link AsyncContext} with the original (unwrapped) ServletRequest
+ * and ServletResponse objects.
+ *
+ * <p>Calling this method will cause committal of the associated
+ * response to be delayed until {@link AsyncContext#complete} is
+ * called on the returned {@link AsyncContext}, or the asynchronous
+ * operation has timed out.
+ *
+ * <p>Calling {@link AsyncContext#hasOriginalRequestAndResponse()} on
+ * the returned AsyncContext will return <code>true</code>. Any filters
+ * invoked in the <i>outbound</i> direction after this request was put
+ * into asynchronous mode may use this as an indication that any request
+ * and/or response wrappers that they added during their <i>inbound</i>
+ * invocation need not stay around for the duration of the asynchronous
+ * operation, and therefore any of their associated resources may be
+ * released.
+ *
+ * <p>This method clears the list of {@link AsyncListener} instances
+ * (if any) that were registered with the AsyncContext returned by the
+ * previous call to one of the startAsync methods, after calling each
+ * AsyncListener at its {@link AsyncListener#onStartAsync onStartAsync}
+ * method.
+ *
+ * <p>Subsequent invocations of this method, or its overloaded
+ * variant, will return the same AsyncContext instance, reinitialized
+ * as appropriate.
+ *
+ * @return the (re)initialized AsyncContext
+ *
+ * @throws IllegalStateException if this request is within the scope of
+ * a filter or servlet that does not support asynchronous operations
+ * (that is, {@link #isAsyncSupported} returns false),
+ * or if this method is called again without any asynchronous dispatch
+ * (resulting from one of the {@link AsyncContext#dispatch} methods),
+ * is called outside the scope of any such dispatch, or is called again
+ * within the scope of the same dispatch, or if the response has
+ * already been closed
+ *
+ * @see AsyncContext#dispatch()
+ * @since Servlet 3.0
+ */
+ public AsyncContext startAsync() throws IllegalStateException;
+
+ /**
+ * Puts this request into asynchronous mode, and initializes its
+ * {@link AsyncContext} with the given request and response objects.
+ *
+ * <p>The ServletRequest and ServletResponse arguments must be
+ * the same instances, or instances of {@link ServletRequestWrapper} and
+ * {@link ServletResponseWrapper} that wrap them, that were passed to the
+ * {@link Servlet#service service} method of the Servlet or the
+ * {@link Filter#doFilter doFilter} method of the Filter, respectively,
+ * in whose scope this method is being called.
+ *
+ * <p>Calling this method will cause committal of the associated
+ * response to be delayed until {@link AsyncContext#complete} is
+ * called on the returned {@link AsyncContext}, or the asynchronous
+ * operation has timed out.
+ *
+ * <p>Calling {@link AsyncContext#hasOriginalRequestAndResponse()} on
+ * the returned AsyncContext will return <code>false</code>,
+ * unless the passed in ServletRequest and ServletResponse arguments
+ * are the original ones or do not carry any application-provided wrappers.
+ * Any filters invoked in the <i>outbound</i> direction after this
+ * request was put into asynchronous mode may use this as an indication
+ * that some of the request and/or response wrappers that they added
+ * during their <i>inbound</i> invocation may need to stay in place for
+ * the duration of the asynchronous operation, and their associated
+ * resources may not be released.
+ * A ServletRequestWrapper applied during the <i>inbound</i>
+ * invocation of a filter may be released by the <i>outbound</i>
+ * invocation of the filter only if the given <code>servletRequest</code>,
+ * which is used to initialize the AsyncContext and will be returned by
+ * a call to {@link AsyncContext#getRequest()}, does not contain said
+ * ServletRequestWrapper. The same holds true for ServletResponseWrapper
+ * instances.
+ *
+ * <p>This method clears the list of {@link AsyncListener} instances
+ * (if any) that were registered with the AsyncContext returned by the
+ * previous call to one of the startAsync methods, after calling each
+ * AsyncListener at its {@link AsyncListener#onStartAsync onStartAsync}
+ * method.
+ *
+ * <p>Subsequent invocations of this method, or its zero-argument
+ * variant, will return the same AsyncContext instance, reinitialized
+ * as appropriate. If a call to this method is followed by a call to its
+ * zero-argument variant, the specified (and possibly wrapped) request
+ * and response objects will remain <i>locked in</i> on the returned
+ * AsyncContext.
+ *
+ * @param servletRequest the ServletRequest used to initialize the
+ * AsyncContext
+ * @param servletResponse the ServletResponse used to initialize the
+ * AsyncContext
+ *
+ * @return the (re)initialized AsyncContext
+ *
+ * @throws IllegalStateException if this request is within the scope of
+ * a filter or servlet that does not support asynchronous operations
+ * (that is, {@link #isAsyncSupported} returns false),
+ * or if this method is called again without any asynchronous dispatch
+ * (resulting from one of the {@link AsyncContext#dispatch} methods),
+ * is called outside the scope of any such dispatch, or is called again
+ * within the scope of the same dispatch, or if the response has
+ * already been closed
+ *
+ * @since Servlet 3.0
+ */
+ public AsyncContext startAsync(ServletRequest servletRequest,
+ ServletResponse servletResponse)
+ throws IllegalStateException;
+
+ /**
+ * Checks if this request has been put into asynchronous mode.
+ *
+ * <p>A ServletRequest is put into asynchronous mode by calling
+ * {@link #startAsync} or
+ * {@link #startAsync(ServletRequest,ServletResponse)} on it.
+ *
+ * <p>This method returns <tt>false</tt> if this request was
+ * put into asynchronous mode, but has since been dispatched using
+ * one of the {@link AsyncContext#dispatch} methods or released
+ * from asynchronous mode via a call to {@link AsyncContext#complete}.
+ *
+ * @return true if this request has been put into asynchronous mode,
+ * false otherwise
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isAsyncStarted();
+
+ /**
+ * Checks if this request supports asynchronous operation.
+ *
+ * <p>Asynchronous operation is disabled for this request if this request
+ * is within the scope of a filter or servlet that has not been annotated
+ * or flagged in the deployment descriptor as being able to support
+ * asynchronous handling.
+ *
+ * @return true if this request supports asynchronous operation, false
+ * otherwise
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isAsyncSupported();
+
+ /**
+ * Gets the AsyncContext that was created or reinitialized by the
+ * most recent invocation of {@link #startAsync} or
+ * {@link #startAsync(ServletRequest,ServletResponse)} on this request.
+ *
+ * @return the AsyncContext that was created or reinitialized by the
+ * most recent invocation of {@link #startAsync} or
+ * {@link #startAsync(ServletRequest,ServletResponse)} on
+ * this request
+ *
+ * @throws IllegalStateException if this request has not been put
+ * into asynchronous mode, i.e., if neither {@link #startAsync} nor
+ * {@link #startAsync(ServletRequest,ServletResponse)} has been called
+ *
+ * @since Servlet 3.0
+ */
+ public AsyncContext getAsyncContext();
+
+ /**
+ * Gets the dispatcher type of this request.
+ *
+ * <p>The dispatcher type of a request is used by the container
+ * to select the filters that need to be applied to the request:
+ * Only filters with matching dispatcher type and url patterns will
+ * be applied.
+ *
+ * <p>Allowing a filter that has been configured for multiple
+ * dispatcher types to query a request for its dispatcher type
+ * allows the filter to process the request differently depending on
+ * its dispatcher type.
+ *
+ * <p>The initial dispatcher type of a request is defined as
+ * <code>DispatcherType.REQUEST</code>. The dispatcher type of a request
+ * dispatched via {@link RequestDispatcher#forward(ServletRequest,
+ * ServletResponse)} or {@link RequestDispatcher#include(ServletRequest,
+ * ServletResponse)} is given as <code>DispatcherType.FORWARD</code> or
+ * <code>DispatcherType.INCLUDE</code>, respectively, while the
+ * dispatcher type of an asynchronous request dispatched via
+ * one of the {@link AsyncContext#dispatch} methods is given as
+ * <code>DispatcherType.ASYNC</code>. Finally, the dispatcher type of a
+ * request dispatched to an error page by the container's error handling
+ * mechanism is given as <code>DispatcherType.ERROR</code>.
+ *
+ * @return the dispatcher type of this request
+ *
+ * @see DispatcherType
+ *
+ * @since Servlet 3.0
+ */
+ public DispatcherType getDispatcherType();
+
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestAttributeEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestAttributeEvent.java
new file mode 100644
index 0000000..1f59887
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestAttributeEvent.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+
+ /**
+ * This is the event class for notifications of changes to the
+ * attributes of the servlet request in an application.
+ * @see ServletRequestAttributeListener
+ * @since Servlet 2.4
+ */
+
+public class ServletRequestAttributeEvent extends ServletRequestEvent {
+
+ private static final long serialVersionUID = -1466635426192317793L;
+
+ private String name;
+ private Object value;
+
+ /** Construct a ServletRequestAttributeEvent giving the servlet context
+ * of this web application, the ServletRequest whose attributes are
+ * changing and the name and value of the attribute.
+ *
+ * @param sc the ServletContext that is sending the event.
+ * @param request the ServletRequest that is sending the event.
+ * @param name the name of the request attribute.
+ * @param value the value of the request attribute.
+ */
+ public ServletRequestAttributeEvent(ServletContext sc, ServletRequest request, String name, Object value) {
+ super(sc, request);
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Return the name of the attribute that changed on the ServletRequest.
+ *
+ * @return the name of the changed request attribute
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Returns the value of the attribute that has been added, removed or
+ * replaced. If the attribute was added, this is the value of the
+ * attribute. If the attribute was removed, this is the value of the
+ * removed attribute. If the attribute was replaced, this is the old
+ * value of the attribute.
+ *
+ * @return the value of the changed request attribute
+ */
+ public Object getValue() {
+ return this.value;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestAttributeListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestAttributeListener.java
new file mode 100644
index 0000000..f17ab03
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestAttributeListener.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about ServletRequest
+ * attribute changes.
+ *
+ * <p>Notifications will be generated while the request
+ * is within the scope of the web application. A ServletRequest
+ * is defined as coming into scope of a web application when it
+ * is about to enter the first servlet or filter of the web
+ * application, and as going out of scope when it exits the last
+ * servlet or the first filter in the chain.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link ServletContext}.
+ *
+ * <p>The order in which implementations of this interface are invoked is
+ * unspecified.
+ *
+ * @since Servlet 2.4
+ */
+
+public interface ServletRequestAttributeListener extends EventListener {
+
+ /**
+ * Receives notification that an attribute has been added to the
+ * ServletRequest.
+ *
+ * @param srae the ServletRequestAttributeEvent containing the
+ * ServletRequest and the name and value of the attribute that was
+ * added
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void attributeAdded(ServletRequestAttributeEvent srae) {}
+
+ /**
+ * Receives notification that an attribute has been removed from the
+ * ServletRequest.
+ *
+ * @param srae the ServletRequestAttributeEvent containing the
+ * ServletRequest and the name and value of the attribute that was
+ * removed
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void attributeRemoved(ServletRequestAttributeEvent srae) {}
+
+ /**
+ * Receives notification that an attribute has been replaced on the
+ * ServletRequest.
+ *
+ * @param srae the ServletRequestAttributeEvent containing the
+ * ServletRequest and the name and (old) value of the attribute
+ * that was replaced
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void attributeReplaced(ServletRequestAttributeEvent srae) {}
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestEvent.java
new file mode 100644
index 0000000..c4db8fa
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestEvent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+/**
+ * Events of this kind indicate lifecycle events for a ServletRequest.
+ * The source of the event is the ServletContext of this web application.
+ *
+ * @see ServletRequestListener
+ * @since Servlet 2.4
+ */
+public class ServletRequestEvent extends java.util.EventObject {
+
+ private static final long serialVersionUID = -7467864054698729101L;
+
+ private final transient ServletRequest request;
+
+ /** Construct a ServletRequestEvent for the given ServletContext
+ * and ServletRequest.
+ *
+ * @param sc the ServletContext of the web application.
+ * @param request the ServletRequest that is sending the event.
+ */
+ public ServletRequestEvent(ServletContext sc, ServletRequest request) {
+ super(sc);
+ this.request = request;
+ }
+
+ /**
+ * Returns the ServletRequest that is changing.
+
+ * @return the {@link ServletRequest} corresponding to this event.
+ */
+ public ServletRequest getServletRequest () {
+ return this.request;
+ }
+
+ /**
+ * Returns the ServletContext of this web application.
+ *
+ * @return the {@link ServletContext} for this web application.
+ */
+ public ServletContext getServletContext () {
+ return (ServletContext) super.getSource();
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestListener.java
new file mode 100644
index 0000000..d65edf9
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestListener.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about requests coming
+ * into and going out of scope of a web application.
+ *
+ * <p>A ServletRequest is defined as coming into scope of a web
+ * application when it is about to enter the first servlet or filter
+ * of the web application, and as going out of scope as it exits
+ * the last servlet or the first filter in the chain.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link ServletContext}.
+ *
+ * <p>Implementations of this interface are invoked at their
+ * {@link #requestInitialized} method in the order in which they have been
+ * declared, and at their {@link #requestDestroyed} method in reverse
+ * order.
+ *
+ * @since Servlet 2.4
+ */
+
+public interface ServletRequestListener extends EventListener {
+
+ /**
+ * Receives notification that a ServletRequest is about to go out
+ * of scope of the web application.
+ *
+ * @param sre the ServletRequestEvent containing the ServletRequest
+ * and the ServletContext representing the web application
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void requestDestroyed(ServletRequestEvent sre) {}
+
+ /**
+ * Receives notification that a ServletRequest is about to come
+ * into scope of the web application.
+ *
+ * @param sre the ServletRequestEvent containing the ServletRequest
+ * and the ServletContext representing the web application
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ */
+ default public void requestInitialized(ServletRequestEvent sre) {}
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestWrapper.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestWrapper.java
new file mode 100644
index 0000000..bf8c95b
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletRequestWrapper.java
@@ -0,0 +1,558 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Provides a convenient implementation of the ServletRequest interface that
+ * can be subclassed by developers wishing to adapt the request to a Servlet.
+ * This class implements the Wrapper or Decorator pattern. Methods default to
+ * calling through to the wrapped request object.
+ *
+ * @see javax.servlet.ServletRequest
+ *
+ * @since Servlet 2.3
+ */
+
+public class ServletRequestWrapper implements ServletRequest {
+
+ private ServletRequest request;
+
+ /**
+ * Creates a ServletRequest adaptor wrapping the given request object.
+ * @throws java.lang.IllegalArgumentException if the request is null
+ *
+ * @param request the {@link ServletRequest} to be wrapped
+ */
+ public ServletRequestWrapper(ServletRequest request) {
+ if (request == null) {
+ throw new IllegalArgumentException("Request cannot be null");
+ }
+ this.request = request;
+ }
+
+
+ /**
+ * Return the wrapped request object.
+ *
+ * @return the wrapped {@link ServletRequest}
+ */
+ public ServletRequest getRequest() {
+ return this.request;
+ }
+
+
+ /**
+ * Sets the request object being wrapped.
+ *
+ * @param request the {@link ServletRequest} to be installed
+ *
+ * @throws java.lang.IllegalArgumentException if the request is null.
+ *
+ */
+ public void setRequest(ServletRequest request) {
+ if (request == null) {
+ throw new IllegalArgumentException("Request cannot be null");
+ }
+ this.request = request;
+ }
+
+
+ /**
+ * The default behavior of this method is to call getAttribute(String name)
+ * on the wrapped request object.
+ */
+ public Object getAttribute(String name) {
+ return this.request.getAttribute(name);
+ }
+
+
+ /**
+ * The default behavior of this method is to return getAttributeNames()
+ * on the wrapped request object.
+ */
+ public Enumeration<String> getAttributeNames() {
+ return this.request.getAttributeNames();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getCharacterEncoding()
+ * on the wrapped request object.
+ */
+ public String getCharacterEncoding() {
+ return this.request.getCharacterEncoding();
+ }
+
+
+ /**
+ * The default behavior of this method is to set the character encoding
+ * on the wrapped request object.
+ */
+ public void setCharacterEncoding(String enc)
+ throws UnsupportedEncodingException {
+ this.request.setCharacterEncoding(enc);
+ }
+
+
+ /**
+ * The default behavior of this method is to return getContentLength()
+ * on the wrapped request object.
+ */
+ public int getContentLength() {
+ return this.request.getContentLength();
+ }
+
+ /**
+ * The default behavior of this method is to return getContentLengthLong()
+ * on the wrapped request object.
+ *
+ * @since Servlet 3.1
+ */
+ public long getContentLengthLong() {
+ return this.request.getContentLengthLong();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getContentType()
+ * on the wrapped request object.
+ */
+ public String getContentType() {
+ return this.request.getContentType();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getInputStream()
+ * on the wrapped request object.
+ */
+ public ServletInputStream getInputStream() throws IOException {
+ return this.request.getInputStream();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getParameter(String name) on the wrapped request object.
+ */
+ public String getParameter(String name) {
+ return this.request.getParameter(name);
+ }
+
+
+ /**
+ * The default behavior of this method is to return getParameterMap()
+ * on the wrapped request object.
+ */
+ public Map<String, String[]> getParameterMap() {
+ return this.request.getParameterMap();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getParameterNames()
+ * on the wrapped request object.
+ */
+ public Enumeration<String> getParameterNames() {
+ return this.request.getParameterNames();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getParameterValues(String name) on the wrapped request object.
+ */
+ public String[] getParameterValues(String name) {
+ return this.request.getParameterValues(name);
+ }
+
+
+ /**
+ * The default behavior of this method is to return getProtocol()
+ * on the wrapped request object.
+ */
+ public String getProtocol() {
+ return this.request.getProtocol();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getScheme()
+ * on the wrapped request object.
+ */
+ public String getScheme() {
+ return this.request.getScheme();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getServerName()
+ * on the wrapped request object.
+ */
+ public String getServerName() {
+ return this.request.getServerName();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getServerPort()
+ * on the wrapped request object.
+ */
+ public int getServerPort() {
+ return this.request.getServerPort();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getReader()
+ * on the wrapped request object.
+ */
+ public BufferedReader getReader() throws IOException {
+ return this.request.getReader();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getRemoteAddr()
+ * on the wrapped request object.
+ */
+ public String getRemoteAddr() {
+ return this.request.getRemoteAddr();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getRemoteHost()
+ * on the wrapped request object.
+ */
+ public String getRemoteHost() {
+ return this.request.getRemoteHost();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * setAttribute(String name, Object o) on the wrapped request object.
+ */
+ public void setAttribute(String name, Object o) {
+ this.request.setAttribute(name, o);
+ }
+
+
+ /**
+ * The default behavior of this method is to call
+ * removeAttribute(String name) on the wrapped request object.
+ */
+ public void removeAttribute(String name) {
+ this.request.removeAttribute(name);
+ }
+
+
+ /**
+ * The default behavior of this method is to return getLocale()
+ * on the wrapped request object.
+ */
+ public Locale getLocale() {
+ return this.request.getLocale();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getLocales()
+ * on the wrapped request object.
+ */
+ public Enumeration<Locale> getLocales() {
+ return this.request.getLocales();
+ }
+
+
+ /**
+ * The default behavior of this method is to return isSecure()
+ * on the wrapped request object.
+ */
+ public boolean isSecure() {
+ return this.request.isSecure();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getRequestDispatcher(String path) on the wrapped request object.
+ */
+ public RequestDispatcher getRequestDispatcher(String path) {
+ return this.request.getRequestDispatcher(path);
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getRealPath(String path) on the wrapped request object.
+ *
+ * @deprecated As of Version 2.1 of the Java Servlet API,
+ * use {@link ServletContext#getRealPath} instead
+ */
+ @Deprecated
+ public String getRealPath(String path) {
+ return this.request.getRealPath(path);
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getRemotePort() on the wrapped request object.
+ *
+ * @since Servlet 2.4
+ */
+ public int getRemotePort(){
+ return this.request.getRemotePort();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getLocalName() on the wrapped request object.
+ *
+ * @since Servlet 2.4
+ */
+ public String getLocalName(){
+ return this.request.getLocalName();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getLocalAddr() on the wrapped request object.
+ *
+ * @since Servlet 2.4
+ */
+ public String getLocalAddr(){
+ return this.request.getLocalAddr();
+ }
+
+
+ /**
+ * The default behavior of this method is to return
+ * getLocalPort() on the wrapped request object.
+ *
+ * @since Servlet 2.4
+ */
+ public int getLocalPort(){
+ return this.request.getLocalPort();
+ }
+
+
+ /**
+ * Gets the servlet context to which the wrapped servlet request was last
+ * dispatched.
+ *
+ * @return the servlet context to which the wrapped servlet request was
+ * last dispatched
+ *
+ * @since Servlet 3.0
+ */
+ public ServletContext getServletContext() {
+ return request.getServletContext();
+ }
+
+
+ /**
+ * The default behavior of this method is to invoke
+ * {@link ServletRequest#startAsync} on the wrapped request object.
+ *
+ * @return the (re)initialized AsyncContext
+ *
+ * @throws IllegalStateException if the request is within the scope of
+ * a filter or servlet that does not support asynchronous operations
+ * (that is, {@link #isAsyncSupported} returns false),
+ * or if this method is called again without any asynchronous dispatch
+ * (resulting from one of the {@link AsyncContext#dispatch} methods),
+ * is called outside the scope of any such dispatch, or is called again
+ * within the scope of the same dispatch, or if the response has
+ * already been closed
+ *
+ * @see ServletRequest#startAsync
+ *
+ * @since Servlet 3.0
+ */
+ public AsyncContext startAsync() throws IllegalStateException {
+ return request.startAsync();
+ }
+
+
+ /**
+ * The default behavior of this method is to invoke
+ * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}
+ * on the wrapped request object.
+ *
+ * @param servletRequest the ServletRequest used to initialize the
+ * AsyncContext
+ * @param servletResponse the ServletResponse used to initialize the
+ * AsyncContext
+ *
+ * @return the (re)initialized AsyncContext
+ *
+ * @throws IllegalStateException if the request is within the scope of
+ * a filter or servlet that does not support asynchronous operations
+ * (that is, {@link #isAsyncSupported} returns false),
+ * or if this method is called again without any asynchronous dispatch
+ * (resulting from one of the {@link AsyncContext#dispatch} methods),
+ * is called outside the scope of any such dispatch, or is called again
+ * within the scope of the same dispatch, or if the response has
+ * already been closed
+ *
+ * @see ServletRequest#startAsync(ServletRequest, ServletResponse)
+ *
+ * @since Servlet 3.0
+ */
+ public AsyncContext startAsync(ServletRequest servletRequest,
+ ServletResponse servletResponse)
+ throws IllegalStateException {
+ return request.startAsync(servletRequest, servletResponse);
+ }
+
+
+ /**
+ * Checks if the wrapped request has been put into asynchronous mode.
+ *
+ * @return true if this request has been put into asynchronous mode,
+ * false otherwise
+ *
+ * @see ServletRequest#isAsyncStarted
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isAsyncStarted() {
+ return request.isAsyncStarted();
+ }
+
+
+ /**
+ * Checks if the wrapped request supports asynchronous operation.
+ *
+ * @return true if this request supports asynchronous operation, false
+ * otherwise
+ *
+ * @see ServletRequest#isAsyncSupported
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isAsyncSupported() {
+ return request.isAsyncSupported();
+ }
+
+
+ /**
+ * Gets the AsyncContext that was created or reinitialized by the
+ * most recent invocation of {@link #startAsync} or
+ * {@link #startAsync(ServletRequest,ServletResponse)} on the wrapped
+ * request.
+ *
+ * @return the AsyncContext that was created or reinitialized by the
+ * most recent invocation of {@link #startAsync} or
+ * {@link #startAsync(ServletRequest,ServletResponse)} on
+ * the wrapped request
+ *
+ * @throws IllegalStateException if this request has not been put
+ * into asynchronous mode, i.e., if neither {@link #startAsync} nor
+ * {@link #startAsync(ServletRequest,ServletResponse)} has been called
+ *
+ * @see ServletRequest#getAsyncContext
+ *
+ * @since Servlet 3.0
+ */
+ public AsyncContext getAsyncContext() {
+ return request.getAsyncContext();
+ }
+
+
+ /**
+ * Checks (recursively) if this ServletRequestWrapper wraps the given
+ * {@link ServletRequest} instance.
+ *
+ * @param wrapped the ServletRequest instance to search for
+ *
+ * @return true if this ServletRequestWrapper wraps the
+ * given ServletRequest instance, false otherwise
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isWrapperFor(ServletRequest wrapped) {
+ if (request == wrapped) {
+ return true;
+ } else if (request instanceof ServletRequestWrapper) {
+ return ((ServletRequestWrapper) request).isWrapperFor(wrapped);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Checks (recursively) if this ServletRequestWrapper wraps a
+ * {@link ServletRequest} of the given class type.
+ *
+ * @param wrappedType the ServletRequest class type to
+ * search for
+ *
+ * @return true if this ServletRequestWrapper wraps a
+ * ServletRequest of the given class type, false otherwise
+ *
+ * @throws IllegalArgumentException if the given class does not
+ * implement {@link ServletRequest}
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isWrapperFor(Class<?> wrappedType) {
+ if (!ServletRequest.class.isAssignableFrom(wrappedType)) {
+ throw new IllegalArgumentException("Given class " +
+ wrappedType.getName() + " not a subinterface of " +
+ ServletRequest.class.getName());
+ }
+ if (wrappedType.isAssignableFrom(request.getClass())) {
+ return true;
+ } else if (request instanceof ServletRequestWrapper) {
+ return ((ServletRequestWrapper) request).isWrapperFor(wrappedType);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Gets the dispatcher type of the wrapped request.
+ *
+ * @return the dispatcher type of the wrapped request
+ *
+ * @see ServletRequest#getDispatcherType
+ *
+ * @since Servlet 3.0
+ */
+ public DispatcherType getDispatcherType() {
+ return request.getDispatcherType();
+ }
+
+
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletResponse.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletResponse.java
new file mode 100644
index 0000000..7b1c38d
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletResponse.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+
+/**
+ * Defines an object to assist a servlet in sending a response to the client.
+ * The servlet container creates a <code>ServletResponse</code> object and
+ * passes it as an argument to the servlet's <code>service</code> method.
+ *
+ * <p>To send binary data in a MIME body response, use
+ * the {@link ServletOutputStream} returned by {@link #getOutputStream}.
+ * To send character data, use the <code>PrintWriter</code> object
+ * returned by {@link #getWriter}. To mix binary and text data,
+ * for example, to create a multipart response, use a
+ * <code>ServletOutputStream</code> and manage the character sections
+ * manually.
+ *
+ * <p>The charset for the MIME body response can be specified explicitly
+ * using any of the following techniques: per request, per web-app (using
+ * {@link ServletContext#setRequestCharacterEncoding}, deployment descriptor),
+ * and per container (for all web applications deployed in that container,
+ * using vendor specific configuration).
+ * If multiple of the preceding techniques have been employed, the priority is
+ * the order listed.
+ * For per request, the charset for the response can be specified explicitly
+ * using the {@link #setCharacterEncoding} and {@link #setContentType} methods,
+ * or implicitly using the {@link #setLocale} method.
+ * Explicit specifications take precedence over implicit specifications.
+ * If no charset is explicitly specified, ISO-8859-1 will be used.
+ * The <code>setCharacterEncoding</code>,
+ * <code>setContentType</code>, or <code>setLocale</code> method must
+ * be called before <code>getWriter</code> and before committing
+ * the response for the character encoding to be used.
+ *
+ * <p>See the Internet RFCs such as
+ * <a href="http://www.ietf.org/rfc/rfc2045.txt">
+ * RFC 2045</a> for more information on MIME. Protocols such as SMTP
+ * and HTTP define profiles of MIME, and those standards
+ * are still evolving.
+ *
+ * @author Various
+ *
+ * @see ServletOutputStream
+ */
+
+public interface ServletResponse {
+
+ /**
+ * Returns the name of the character encoding (MIME charset)
+ * used for the body sent in this response.
+ * The following methods for specifying the response character encoding are
+ * consulted, in decreasing order of priority: per request, perweb-app
+ * (using {@link ServletContext#setResponseCharacterEncoding}, deployment
+ * descriptor), and per container (for all web applications deployed in
+ * that container, using vendor specific configuration).
+ * The first one of these methods that yields a result is returned.
+ * Per-request, the charset for the response can be specified explicitly
+ * using the {@link setCharacterEncoding} and {@link setContentType}
+ * methods, or implicitly using the setLocale(java.util.Locale) method.
+ * Explicit specifications take precedence over implicit specifications.
+ * Calls made to these methods after <code>getWriter</code> has been
+ * called or after the response has been committed have no
+ * effect on the character encoding. If no character encoding
+ * has been specified, <code>ISO-8859-1</code> is returned.
+ * <p>See RFC 2047 (http://www.ietf.org/rfc/rfc2047.txt)
+ * for more information about character encoding and MIME.
+ *
+ * @return a <code>String</code> specifying the name of
+ * the character encoding, for example, <code>UTF-8</code>
+ */
+ public String getCharacterEncoding();
+
+ /**
+ * Returns the content type used for the MIME body
+ * sent in this response. The content type proper must
+ * have been specified using {@link #setContentType}
+ * before the response is committed. If no content type
+ * has been specified, this method returns null.
+ * If a content type has been specified, and a
+ * character encoding has been explicitly or implicitly
+ * specified as described in {@link #getCharacterEncoding}
+ * or {@link #getWriter} has been called,
+ * the charset parameter is included in the string returned.
+ * If no character encoding has been specified, the
+ * charset parameter is omitted.
+ *
+ * @return a <code>String</code> specifying the content type,
+ * for example, <code>text/html; charset=UTF-8</code>, or null
+ *
+ * @since Servlet 2.4
+ */
+ public String getContentType();
+
+
+
+ /**
+ * Returns a {@link ServletOutputStream} suitable for writing binary
+ * data in the response. The servlet container does not encode the
+ * binary data.
+ *
+ * <p> Calling flush() on the ServletOutputStream commits the response.
+ *
+ * Either this method or {@link #getWriter} may
+ * be called to write the body, not both, except when {@link #reset}
+ * has been called.
+ *
+ * @return a {@link ServletOutputStream} for writing binary data
+ *
+ * @exception IllegalStateException if the <code>getWriter</code> method
+ * has been called on this response
+ *
+ * @exception IOException if an input or output exception occurred
+ *
+ * @see #getWriter
+ * @see #reset
+ */
+ public ServletOutputStream getOutputStream() throws IOException;
+
+ /**
+ * Returns a <code>PrintWriter</code> object that
+ * can send character text to the client.
+ * The <code>PrintWriter</code> uses the character
+ * encoding returned by {@link #getCharacterEncoding}.
+ * If the response's character encoding has not been
+ * specified as described in <code>getCharacterEncoding</code>
+ * (i.e., the method just returns the default value
+ * <code>ISO-8859-1</code>), <code>getWriter</code>
+ * updates it to <code>ISO-8859-1</code>.
+ * <p>Calling flush() on the <code>PrintWriter</code>
+ * commits the response.
+ * <p>Either this method or {@link #getOutputStream} may be called
+ * to write the body, not both, except when {@link #reset}
+ * has been called.
+ *
+ * @return a <code>PrintWriter</code> object that
+ * can return character data to the client
+ *
+ * @exception java.io.UnsupportedEncodingException
+ * if the character encoding returned
+ * by <code>getCharacterEncoding</code> cannot be used
+ *
+ * @exception IllegalStateException
+ * if the <code>getOutputStream</code>
+ * method has already been called for this response object
+ *
+ * @exception IOException
+ * if an input or output exception occurred
+ *
+ * @see #getOutputStream
+ * @see #setCharacterEncoding
+ * @see #reset
+ */
+ public PrintWriter getWriter() throws IOException;
+
+ /**
+ * Sets the character encoding (MIME charset) of the response
+ * being sent to the client, for example, to UTF-8.
+ * If the response character encoding has already been set by the
+ * {@link ServletContext#setResponseCharacterEncoding},
+ * deployment descriptor, or using the setContentType() or setLocale()
+ * methods, the value set in this method overrides any of those values.
+ * Calling {@link #setContentType} with the <code>String</code>
+ * of <code>text/html</code> and calling
+ * this method with the <code>String</code> of <code>UTF-8</code>
+ * is equivalent with calling
+ * <code>setContentType</code> with the <code>String</code> of
+ * <code>text/html; charset=UTF-8</code>.
+ * <p>This method can be called repeatedly to change the character
+ * encoding.
+ * This method has no effect if it is called after
+ * <code>getWriter</code> has been
+ * called or after the response has been committed.
+ * <p>Containers must communicate the character encoding used for
+ * the servlet response's writer to the client if the protocol
+ * provides a way for doing so. In the case of HTTP, the character
+ * encoding is communicated as part of the <code>Content-Type</code>
+ * header for text media types. Note that the character encoding
+ * cannot be communicated via HTTP headers if the servlet does not
+ * specify a content type; however, it is still used to encode text
+ * written via the servlet response's writer.
+ *
+ * @param charset a String specifying only the character set
+ * defined by IANA Character Sets
+ * (http://www.iana.org/assignments/character-sets)
+ *
+ * @see #setContentType
+ * @see #setLocale
+ *
+ * @since Servlet 2.4
+ */
+ public void setCharacterEncoding(String charset);
+
+ /**
+ * Sets the length of the content body in the response
+ * In HTTP servlets, this method sets the HTTP Content-Length header.
+ *
+ * @param len an integer specifying the length of the
+ * content being returned to the client; sets the Content-Length header
+ */
+ public void setContentLength(int len);
+
+ /**
+ * Sets the length of the content body in the response
+ * In HTTP servlets, this method sets the HTTP Content-Length header.
+ *
+ * @param len a long specifying the length of the
+ * content being returned to the client; sets the Content-Length header
+ *
+ * @since Servlet 3.1
+ */
+ public void setContentLengthLong(long len);
+
+ /**
+ * Sets the content type of the response being sent to
+ * the client, if the response has not been committed yet.
+ * The given content type may include a character encoding
+ * specification, for example, <code>text/html;charset=UTF-8</code>.
+ * The response's character encoding is only set from the given
+ * content type if this method is called before <code>getWriter</code>
+ * is called.
+ * <p>This method may be called repeatedly to change content type and
+ * character encoding.
+ * This method has no effect if called after the response
+ * has been committed. It does not set the response's character
+ * encoding if it is called after <code>getWriter</code>
+ * has been called or after the response has been committed.
+ * <p>Containers must communicate the content type and the character
+ * encoding used for the servlet response's writer to the client if
+ * the protocol provides a way for doing so. In the case of HTTP,
+ * the <code>Content-Type</code> header is used.
+ *
+ * @param type a <code>String</code> specifying the MIME
+ * type of the content
+ *
+ * @see #setLocale
+ * @see #setCharacterEncoding
+ * @see #getOutputStream
+ * @see #getWriter
+ *
+ */
+
+ public void setContentType(String type);
+
+
+ /**
+ * Sets the preferred buffer size for the body of the response.
+ * The servlet container will use a buffer at least as large as
+ * the size requested. The actual buffer size used can be found
+ * using <code>getBufferSize</code>.
+ *
+ * <p>A larger buffer allows more content to be written before anything is
+ * actually sent, thus providing the servlet with more time to set
+ * appropriate status codes and headers. A smaller buffer decreases
+ * server memory load and allows the client to start receiving data more
+ * quickly.
+ *
+ * <p>This method must be called before any response body content is
+ * written; if content has been written or the response object has
+ * been committed, this method throws an
+ * <code>IllegalStateException</code>.
+ *
+ * @param size the preferred buffer size
+ *
+ * @exception IllegalStateException if this method is called after
+ * content has been written
+ *
+ * @see #getBufferSize
+ * @see #flushBuffer
+ * @see #isCommitted
+ * @see #reset
+ */
+ public void setBufferSize(int size);
+
+ /**
+ * Returns the actual buffer size used for the response. If no buffering
+ * is used, this method returns 0.
+ *
+ * @return the actual buffer size used
+ *
+ * @see #setBufferSize
+ * @see #flushBuffer
+ * @see #isCommitted
+ * @see #reset
+ */
+ public int getBufferSize();
+
+ /**
+ * Forces any content in the buffer to be written to the client. A call
+ * to this method automatically commits the response, meaning the status
+ * code and headers will be written.
+ *
+ * @see #setBufferSize
+ * @see #getBufferSize
+ * @see #isCommitted
+ * @see #reset
+
+ * @throws IOException if the act of flushing the buffer cannot be
+ * completed.
+ *
+ */
+ public void flushBuffer() throws IOException;
+
+ /**
+ * Clears the content of the underlying buffer in the response without
+ * clearing headers or status code. If the
+ * response has been committed, this method throws an
+ * <code>IllegalStateException</code>.
+ *
+ * @see #setBufferSize
+ * @see #getBufferSize
+ * @see #isCommitted
+ * @see #reset
+ *
+ * @since Servlet 2.3
+ */
+
+ public void resetBuffer();
+
+ /**
+ * Returns a boolean indicating if the response has been
+ * committed. A committed response has already had its status
+ * code and headers written.
+ *
+ * @return a boolean indicating if the response has been
+ * committed
+ *
+ * @see #setBufferSize
+ * @see #getBufferSize
+ * @see #flushBuffer
+ * @see #reset
+ *
+ */
+ public boolean isCommitted();
+
+ /**
+ * Clears any data that exists in the buffer as well as the status code,
+ * headers. The state of calling {@link #getWriter} or
+ * {@link #getOutputStream} is also cleared. It is legal, for instance,
+ * to call {@link #getWriter}, {@link #reset} and then
+ * {@link #getOutputStream}. If {@link #getWriter} or
+ * {@link #getOutputStream} have been called before this method,
+ * then the corrresponding returned Writer or OutputStream will be
+ * staled and the behavior of using the stale object is undefined.
+ * If the response has been committed, this method throws an
+ * <code>IllegalStateException</code>.
+ *
+ * @exception IllegalStateException if the response has already been
+ * committed
+ *
+ * @see #setBufferSize
+ * @see #getBufferSize
+ * @see #flushBuffer
+ * @see #isCommitted
+ */
+ public void reset();
+
+ /**
+ * Sets the locale of the response, if the response has not been
+ * committed yet. It also sets the response's character encoding
+ * appropriately for the locale, if the character encoding has not
+ * been explicitly set using {@link #setContentType} or
+ * {@link #setCharacterEncoding}, <code>getWriter</code> hasn't
+ * been called yet, and the response hasn't been committed yet.
+ * If the deployment descriptor contains a
+ * <code>locale-encoding-mapping-list</code> element, and that
+ * element provides a mapping for the given locale, that mapping
+ * is used. Otherwise, the mapping from locale to character
+ * encoding is container dependent.
+ * <p>This method may be called repeatedly to change locale and
+ * character encoding. The method has no effect if called after the
+ * response has been committed. It does not set the response's
+ * character encoding if it is called after {@link #setContentType}
+ * has been called with a charset specification, after
+ * {@link #setCharacterEncoding} has been called, after
+ * <code>getWriter</code> has been called, or after the response
+ * has been committed.
+ * <p>Containers must communicate the locale and the character encoding
+ * used for the servlet response's writer to the client if the protocol
+ * provides a way for doing so. In the case of HTTP, the locale is
+ * communicated via the <code>Content-Language</code> header,
+ * the character encoding as part of the <code>Content-Type</code>
+ * header for text media types. Note that the character encoding
+ * cannot be communicated via HTTP headers if the servlet does not
+ * specify a content type; however, it is still used to encode text
+ * written via the servlet response's writer.
+ *
+ * @param loc the locale of the response
+ *
+ * @see #getLocale
+ * @see #setContentType
+ * @see #setCharacterEncoding
+ */
+ public void setLocale(Locale loc);
+
+ /**
+ * Returns the locale specified for this response
+ * using the {@link #setLocale} method. Calls made to
+ * <code>setLocale</code> after the response is committed
+ * have no effect. If no locale has been specified,
+ * the container's default locale is returned.
+ *
+ * @return the Locale for this response.
+ *
+ * @see #setLocale
+ */
+ public Locale getLocale();
+
+}
+
+
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletResponseWrapper.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletResponseWrapper.java
new file mode 100644
index 0000000..b861f84
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletResponseWrapper.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+/**
+ *
+ * Provides a convenient implementation of the ServletResponse interface that
+ * can be subclassed by developers wishing to adapt the response from a Servlet.
+ * This class implements the Wrapper or Decorator pattern. Methods default to
+ * calling through to the wrapped response object.
+ *
+ * @author Various
+ * @since Servlet 2.3
+ *
+ * @see javax.servlet.ServletResponse
+ */
+
+
+public class ServletResponseWrapper implements ServletResponse {
+ private ServletResponse response;
+ /**
+ * Creates a ServletResponse adaptor wrapping the given response object.
+ * @throws java.lang.IllegalArgumentException if the response is null.
+ * @param response the {@link ServletResponse} to be wrapped
+ *
+ */
+
+
+ public ServletResponseWrapper(ServletResponse response) {
+ if (response == null) {
+ throw new IllegalArgumentException("Response cannot be null");
+ }
+ this.response = response;
+ }
+
+ /**
+ * Return the wrapped ServletResponse object.
+ *
+ * @return the wrapped {@link ServletResponse}
+ */
+
+ public ServletResponse getResponse() {
+ return this.response;
+ }
+
+
+ /**
+ * Sets the response being wrapped.
+ * @throws java.lang.IllegalArgumentException if the response is null.
+ *
+ * @param response the {@link ServletResponse} to be installed
+ */
+
+ public void setResponse(ServletResponse response) {
+ if (response == null) {
+ throw new IllegalArgumentException("Response cannot be null");
+ }
+ this.response = response;
+ }
+
+ /**
+ * The default behavior of this method is to call setCharacterEncoding(String charset)
+ * on the wrapped response object.
+ *
+ * @since Servlet 2.4
+ */
+
+ public void setCharacterEncoding(String charset) {
+ this.response.setCharacterEncoding(charset);
+ }
+
+ /**
+ * The default behavior of this method is to return getCharacterEncoding()
+ * on the wrapped response object.
+ */
+
+ public String getCharacterEncoding() {
+ return this.response.getCharacterEncoding();
+ }
+
+
+ /**
+ * The default behavior of this method is to return getOutputStream()
+ * on the wrapped response object.
+ */
+
+ public ServletOutputStream getOutputStream() throws IOException {
+ return this.response.getOutputStream();
+ }
+
+ /**
+ * The default behavior of this method is to return getWriter()
+ * on the wrapped response object.
+ */
+
+
+ public PrintWriter getWriter() throws IOException {
+ return this.response.getWriter();
+ }
+
+ /**
+ * The default behavior of this method is to call setContentLength(int len)
+ * on the wrapped response object.
+ */
+
+ public void setContentLength(int len) {
+ this.response.setContentLength(len);
+ }
+
+ /**
+ * The default behavior of this method is to call setContentLengthLong(long len)
+ * on the wrapped response object.
+ */
+
+ public void setContentLengthLong(long len) {
+ this.response.setContentLengthLong(len);
+ }
+
+ /**
+ * The default behavior of this method is to call setContentType(String type)
+ * on the wrapped response object.
+ */
+
+ public void setContentType(String type) {
+ this.response.setContentType(type);
+ }
+
+ /**
+ * The default behavior of this method is to return getContentType()
+ * on the wrapped response object.
+ *
+ * @since Servlet 2.4
+ */
+
+ public String getContentType() {
+ return this.response.getContentType();
+ }
+
+ /**
+ * The default behavior of this method is to call setBufferSize(int size)
+ * on the wrapped response object.
+ */
+ public void setBufferSize(int size) {
+ this.response.setBufferSize(size);
+ }
+
+ /**
+ * The default behavior of this method is to return getBufferSize()
+ * on the wrapped response object.
+ */
+ public int getBufferSize() {
+ return this.response.getBufferSize();
+ }
+
+ /**
+ * The default behavior of this method is to call flushBuffer()
+ * on the wrapped response object.
+ */
+
+ public void flushBuffer() throws IOException {
+ this.response.flushBuffer();
+ }
+
+ /**
+ * The default behavior of this method is to return isCommitted()
+ * on the wrapped response object.
+ */
+ public boolean isCommitted() {
+ return this.response.isCommitted();
+ }
+
+ /**
+ * The default behavior of this method is to call reset()
+ * on the wrapped response object.
+ */
+
+ public void reset() {
+ this.response.reset();
+ }
+
+ /**
+ * The default behavior of this method is to call resetBuffer()
+ * on the wrapped response object.
+ */
+
+ public void resetBuffer() {
+ this.response.resetBuffer();
+ }
+
+ /**
+ * The default behavior of this method is to call setLocale(Locale loc)
+ * on the wrapped response object.
+ */
+
+ public void setLocale(Locale loc) {
+ this.response.setLocale(loc);
+ }
+
+ /**
+ * The default behavior of this method is to return getLocale()
+ * on the wrapped response object.
+ */
+ public Locale getLocale() {
+ return this.response.getLocale();
+ }
+
+
+ /**
+ * Checks (recursively) if this ServletResponseWrapper wraps the given
+ * {@link ServletResponse} instance.
+ *
+ * @param wrapped the ServletResponse instance to search for
+ *
+ * @return true if this ServletResponseWrapper wraps the
+ * given ServletResponse instance, false otherwise
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isWrapperFor(ServletResponse wrapped) {
+ if (response == wrapped) {
+ return true;
+ } else if (response instanceof ServletResponseWrapper) {
+ return ((ServletResponseWrapper) response).isWrapperFor(wrapped);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Checks (recursively) if this ServletResponseWrapper wraps a
+ * {@link ServletResponse} of the given class type.
+ *
+ * @param wrappedType the ServletResponse class type to
+ * search for
+ *
+ * @return true if this ServletResponseWrapper wraps a
+ * ServletResponse of the given class type, false otherwise
+ *
+ * @throws IllegalArgumentException if the given class does not
+ * implement {@link ServletResponse}
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isWrapperFor(Class<?> wrappedType) {
+ if (!ServletResponse.class.isAssignableFrom(wrappedType)) {
+ throw new IllegalArgumentException("Given class " +
+ wrappedType.getName() + " not a subinterface of " +
+ ServletResponse.class.getName());
+ }
+ if (wrappedType.isAssignableFrom(response.getClass())) {
+ return true;
+ } else if (response instanceof ServletResponseWrapper) {
+ return ((ServletResponseWrapper) response).isWrapperFor(wrappedType);
+ } else {
+ return false;
+ }
+ }
+
+}
+
+
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/ServletSecurityElement.java b/third_party/servlet-spec/src/main/java/javax/servlet/ServletSecurityElement.java
new file mode 100644
index 0000000..13950ef
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/ServletSecurityElement.java
@@ -0,0 +1,202 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.util.*;
+import javax.servlet.annotation.HttpMethodConstraint;
+import javax.servlet.annotation.ServletSecurity;
+
+/**
+ * Java Class representation of a {@link ServletSecurity} annotation value.
+ *
+ * @since Servlet 3.0
+ */
+public class ServletSecurityElement extends HttpConstraintElement {
+
+ private Collection<String> methodNames;
+ private Collection<HttpMethodConstraintElement> methodConstraints;
+
+ /**
+ * Constructs an instance using the default
+ * <code>HttpConstraintElement</code> value as the default Constraint
+ * element and with no HTTP Method specific constraint elements.
+ */
+ public ServletSecurityElement() {
+ methodConstraints = new HashSet<HttpMethodConstraintElement>();
+ methodNames = Collections.emptySet();
+ }
+
+ /**
+ * Constructs an instance with a default Constraint element
+ * and with no HTTP Method specific constraint elements.
+ *
+ * @param constraint the HttpConstraintElement to be
+ * applied to all HTTP methods other than those represented in the
+ * <tt>methodConstraints</tt>
+ */
+ public ServletSecurityElement(HttpConstraintElement constraint) {
+ super(constraint.getEmptyRoleSemantic(),
+ constraint.getTransportGuarantee(),
+ constraint.getRolesAllowed());
+ methodConstraints = new HashSet<HttpMethodConstraintElement>();
+ methodNames = Collections.emptySet();
+ }
+
+ /**
+ * Constructs an instance using the default
+ * <code>HttpConstraintElement</code> value as the default Constraint
+ * element and with a collection of HTTP Method specific constraint
+ * elements.
+ *
+ * @param methodConstraints the collection of HTTP method specific
+ * constraint elements
+ *
+ * @throws IllegalArgumentException if duplicate method names are
+ * detected
+ */
+ public ServletSecurityElement(
+ Collection<HttpMethodConstraintElement> methodConstraints) {
+ this.methodConstraints = (methodConstraints == null ?
+ new HashSet<HttpMethodConstraintElement>() : methodConstraints);
+ methodNames = checkMethodNames(this.methodConstraints);
+ }
+
+ /**
+ * Constructs an instance with a default Constraint element
+ * and with a collection of HTTP Method specific constraint elements.
+ *
+ * @param constraint the HttpConstraintElement to be
+ * applied to all HTTP methods other than those represented in the
+ * <tt>methodConstraints</tt>
+ * @param methodConstraints the collection of HTTP method specific
+ * constraint elements.
+ *
+ * @throws IllegalArgumentException if duplicate method names are
+ * detected
+ */
+ public ServletSecurityElement(HttpConstraintElement constraint,
+ Collection<HttpMethodConstraintElement> methodConstraints) {
+ super(constraint.getEmptyRoleSemantic(),
+ constraint.getTransportGuarantee(),
+ constraint.getRolesAllowed());
+ this.methodConstraints = (methodConstraints == null ?
+ new HashSet<HttpMethodConstraintElement>() : methodConstraints);
+ methodNames = checkMethodNames(this.methodConstraints);
+ }
+
+ /**
+ * Constructs an instance from a {@link ServletSecurity} annotation value.
+ *
+ * @param annotation the annotation value
+ *
+ * @throws IllegalArgumentException if duplicate method names are
+ * detected
+ */
+ public ServletSecurityElement(ServletSecurity annotation) {
+ super(annotation.value().value(),
+ annotation.value().transportGuarantee(),
+ annotation.value().rolesAllowed());
+ this.methodConstraints = new HashSet<HttpMethodConstraintElement>();
+ for (HttpMethodConstraint constraint :
+ annotation.httpMethodConstraints()) {
+ this.methodConstraints.add(
+ new HttpMethodConstraintElement(
+ constraint.value(),
+ new HttpConstraintElement(constraint.emptyRoleSemantic(),
+ constraint.transportGuarantee(),
+ constraint.rolesAllowed())));
+ }
+ methodNames = checkMethodNames(this.methodConstraints);
+ }
+
+ /**
+ * Gets the (possibly empty) collection of HTTP Method specific
+ * constraint elements.
+ *
+ * <p>If permitted, any changes to the returned <code>Collection</code> must not
+ * affect this <code>ServletSecurityElement</code>.
+ *
+ *
+ * @return the (possibly empty) collection of HttpMethodConstraintElement
+ * objects
+ */
+ public Collection<HttpMethodConstraintElement> getHttpMethodConstraints() {
+ return Collections.unmodifiableCollection(methodConstraints);
+ }
+
+ /**
+ * Gets the set of HTTP method names named by the HttpMethodConstraints.
+ *
+ * <p>If permitted, any changes to the returned <code>Collection</code> must not
+ * affect this <code>ServletSecurityElement</code>.
+ *
+
+ *
+ * @return the collection String method names
+ */
+ public Collection<String> getMethodNames() {
+ return Collections.unmodifiableCollection(methodNames);
+ }
+
+ /**
+ * Checks for duplicate method names in methodConstraints.
+ *
+ * @param methodConstraints
+ *
+ * @retrun Set of method names
+ *
+ * @throws IllegalArgumentException if duplicate method names are
+ * detected
+ */
+ private Collection<String> checkMethodNames(
+ Collection<HttpMethodConstraintElement> methodConstraints) {
+ Collection<String> methodNames = new HashSet<String>();
+ for (HttpMethodConstraintElement methodConstraint :
+ methodConstraints) {
+ String methodName = methodConstraint.getMethodName();
+ if (!methodNames.add(methodName)) {
+ throw new IllegalArgumentException(
+ "Duplicate HTTP method name: " + methodName);
+ }
+ }
+ return methodNames;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/SessionCookieConfig.java b/third_party/servlet-spec/src/main/java/javax/servlet/SessionCookieConfig.java
new file mode 100644
index 0000000..2dd82f3
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/SessionCookieConfig.java
@@ -0,0 +1,322 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+/**
+ * Class that may be used to configure various properties of cookies
+ * used for session tracking purposes.
+ *
+ * <p>An instance of this class is acquired by a call to
+ * {@link ServletContext#getSessionCookieConfig}.
+ *
+ * @since Servlet 3.0
+ */
+public interface SessionCookieConfig {
+
+ /**
+ * Sets the name that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * <p>NOTE: Changing the name of session tracking cookies may break
+ * other tiers (for example, a load balancing frontend) that assume
+ * the cookie name to be equal to the default <tt>JSESSIONID</tt>,
+ * and therefore should only be done cautiously.
+ *
+ * @param name the cookie name to use
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ */
+ public void setName(String name);
+
+
+ /**
+ * Gets the name that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * <p>By default, <tt>JSESSIONID</tt> will be used as the cookie name.
+ *
+ * @return the cookie name set via {@link #setName}, or
+ * <tt>null</tt> if {@link #setName} was never called
+ *
+ * @see javax.servlet.http.Cookie#getName()
+ */
+ public String getName();
+
+
+ /**
+ * Sets the domain name that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * @param domain the cookie domain to use
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ *
+ * @see javax.servlet.http.Cookie#setDomain(String)
+ */
+ public void setDomain(String domain);
+
+
+ /**
+ * Gets the domain name that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * @return the cookie domain set via {@link #setDomain}, or
+ * <tt>null</tt> if {@link #setDomain} was never called
+ *
+ * @see javax.servlet.http.Cookie#getDomain()
+ */
+ public String getDomain();
+
+
+ /**
+ * Sets the path that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * @param path the cookie path to use
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ *
+ * @see javax.servlet.http.Cookie#setPath(String)
+ */
+ public void setPath(String path);
+
+
+ /**
+ * Gets the path that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * <p>By default, the context path of the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired will
+ * be used.
+ *
+ * @return the cookie path set via {@link #setPath}, or <tt>null</tt>
+ * if {@link #setPath} was never called
+ *
+ * @see javax.servlet.http.Cookie#getPath()
+ */
+ public String getPath();
+
+
+ /**
+ * Sets the comment that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * <p>As a side effect of this call, the session tracking cookies
+ * will be marked with a <code>Version</code> attribute equal to
+ * <code>1</code>.
+ *
+ * @param comment the cookie comment to use
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ *
+ * @see javax.servlet.http.Cookie#setComment(String)
+ * @see javax.servlet.http.Cookie#getVersion
+ */
+ public void setComment(String comment);
+
+
+ /**
+ * Gets the comment that will be assigned to any session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * @return the cookie comment set via {@link #setComment}, or
+ * <tt>null</tt> if {@link #setComment} was never called
+ *
+ * @see javax.servlet.http.Cookie#getComment()
+ */
+ public String getComment();
+
+
+ /**
+ * Marks or unmarks the session tracking cookies created on behalf
+ * of the application represented by the <tt>ServletContext</tt> from
+ * which this <tt>SessionCookieConfig</tt> was acquired as
+ * <i>HttpOnly</i>.
+ *
+ * <p>A cookie is marked as <tt>HttpOnly</tt> by adding the
+ * <tt>HttpOnly</tt> attribute to it. <i>HttpOnly</i> cookies are
+ * not supposed to be exposed to client-side scripting code, and may
+ * therefore help mitigate certain kinds of cross-site scripting
+ * attacks.
+ *
+ * @param httpOnly true if the session tracking cookies created
+ * on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired shall be marked as <i>HttpOnly</i>, false otherwise
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ *
+ * @see javax.servlet.http.Cookie#setHttpOnly(boolean)
+ */
+ public void setHttpOnly(boolean httpOnly);
+
+
+ /**
+ * Checks if the session tracking cookies created on behalf of the
+ * application represented by the <tt>ServletContext</tt> from which
+ * this <tt>SessionCookieConfig</tt> was acquired will be marked as
+ * <i>HttpOnly</i>.
+ *
+ * @return true if the session tracking cookies created on behalf of
+ * the application represented by the <tt>ServletContext</tt> from
+ * which this <tt>SessionCookieConfig</tt> was acquired will be marked
+ * as <i>HttpOnly</i>, false otherwise
+ *
+ * @see javax.servlet.http.Cookie#isHttpOnly()
+ */
+ public boolean isHttpOnly();
+
+
+ /**
+ * Marks or unmarks the session tracking cookies created on behalf of
+ * the application represented by the <tt>ServletContext</tt> from which
+ * this <tt>SessionCookieConfig</tt> was acquired as <i>secure</i>.
+ *
+ * <p>One use case for marking a session tracking cookie as
+ * <tt>secure</tt>, even though the request that initiated the session
+ * came over HTTP, is to support a topology where the web container is
+ * front-ended by an SSL offloading load balancer.
+ * In this case, the traffic between the client and the load balancer
+ * will be over HTTPS, whereas the traffic between the load balancer
+ * and the web container will be over HTTP.
+ *
+ * @param secure true if the session tracking cookies created on
+ * behalf of the application represented by the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired shall be
+ * marked as <i>secure</i> even if the request that initiated the
+ * corresponding session is using plain HTTP instead of HTTPS, and false
+ * if they shall be marked as <i>secure</i> only if the request that
+ * initiated the corresponding session was also secure
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ *
+ * @see javax.servlet.http.Cookie#setSecure(boolean)
+ * @see ServletRequest#isSecure()
+ */
+ public void setSecure(boolean secure);
+
+
+ /**
+ * Checks if the session tracking cookies created on behalf of the
+ * application represented by the <tt>ServletContext</tt> from which
+ * this <tt>SessionCookieConfig</tt> was acquired will be marked as
+ * <i>secure</i> even if the request that initiated the corresponding
+ * session is using plain HTTP instead of HTTPS.
+ *
+ * @return true if the session tracking cookies created on behalf of the
+ * application represented by the <tt>ServletContext</tt> from which
+ * this <tt>SessionCookieConfig</tt> was acquired will be marked as
+ * <i>secure</i> even if the request that initiated the corresponding
+ * session is using plain HTTP instead of HTTPS, and false if they will
+ * be marked as <i>secure</i> only if the request that initiated the
+ * corresponding session was also secure
+ *
+ * @see javax.servlet.http.Cookie#getSecure()
+ * @see ServletRequest#isSecure()
+ */
+ public boolean isSecure();
+
+
+ /**
+ * Sets the lifetime (in seconds) for the session tracking cookies
+ * created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * @param maxAge the lifetime (in seconds) of the session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * @throws IllegalStateException if the <tt>ServletContext</tt>
+ * from which this <tt>SessionCookieConfig</tt> was acquired has
+ * already been initialized
+ *
+ * @see javax.servlet.http.Cookie#setMaxAge
+ */
+ public void setMaxAge(int maxAge);
+
+
+ /**
+ * Gets the lifetime (in seconds) of the session tracking cookies
+ * created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired.
+ *
+ * <p>By default, <tt>-1</tt> is returned.
+ *
+ * @return the lifetime (in seconds) of the session tracking
+ * cookies created on behalf of the application represented by the
+ * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
+ * was acquired, or <tt>-1</tt> (the default)
+ *
+ * @see javax.servlet.http.Cookie#getMaxAge
+ */
+ public int getMaxAge();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/SessionTrackingMode.java b/third_party/servlet-spec/src/main/java/javax/servlet/SessionTrackingMode.java
new file mode 100644
index 0000000..9c3a855
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/SessionTrackingMode.java
@@ -0,0 +1,52 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+/**
+ * Enumeration of session tracking modes.
+ *
+ * @since Servlet 3.0
+ */
+public enum SessionTrackingMode {
+ COOKIE,
+ URL,
+ SSL
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/SingleThreadModel.java b/third_party/servlet-spec/src/main/java/javax/servlet/SingleThreadModel.java
new file mode 100644
index 0000000..2572d3f
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/SingleThreadModel.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+/**
+ * Ensures that servlets handle
+ * only one request at a time. This interface has no methods.
+ *
+ * <p>If a servlet implements this interface, you are <i>guaranteed</i>
+ * that no two threads will execute concurrently in the
+ * servlet's <code>service</code> method. The servlet container
+ * can make this guarantee by synchronizing access to a single
+ * instance of the servlet, or by maintaining a pool of servlet
+ * instances and dispatching each new request to a free servlet.
+ *
+ * <p>Note that SingleThreadModel does not solve all thread safety
+ * issues. For example, session attributes and static variables can
+ * still be accessed by multiple requests on multiple threads
+ * at the same time, even when SingleThreadModel servlets are used.
+ * It is recommended that a developer take other means to resolve
+ * those issues instead of implementing this interface, such as
+ * avoiding the usage of an instance variable or synchronizing
+ * the block of the code accessing those resources.
+ * This interface is deprecated in Servlet API version 2.4.
+ *
+ *
+ * @author Various
+ *
+ * @deprecated As of Java Servlet API 2.4, with no direct
+ * replacement.
+ */
+@Deprecated
+public interface SingleThreadModel {
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/UnavailableException.java b/third_party/servlet-spec/src/main/java/javax/servlet/UnavailableException.java
new file mode 100644
index 0000000..f529aaf
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/UnavailableException.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet;
+
+
+/**
+ * Defines an exception that a servlet or filter throws to indicate
+ * that it is permanently or temporarily unavailable.
+ *
+ * <p>When a servlet or filter is permanently unavailable, something is wrong
+ * with it, and it cannot handle
+ * requests until some action is taken. For example, a servlet
+ * might be configured incorrectly, or a filter's state may be corrupted.
+ * The component should log both the error and the corrective action
+ * that is needed.
+ *
+ * <p>A servlet or filter is temporarily unavailable if it cannot handle
+ * requests momentarily due to some system-wide problem. For example,
+ * a third-tier server might not be accessible, or there may be
+ * insufficient memory or disk storage to handle requests. A system
+ * administrator may need to take corrective action.
+ *
+ * <p>Servlet containers can safely treat both types of unavailable
+ * exceptions in the same way. However, treating temporary unavailability
+ * effectively makes the servlet container more robust. Specifically,
+ * the servlet container might block requests to the servlet or filter for a period
+ * of time suggested by the exception, rather than rejecting them until
+ * the servlet container restarts.
+ *
+ *
+ * @author Various
+ *
+ */
+
+public class UnavailableException
+extends ServletException {
+
+ private Servlet servlet; // what's unavailable
+ private boolean permanent; // needs admin action?
+ private int seconds; // unavailability estimate
+
+ /**
+ *
+ * @deprecated As of Java Servlet API 2.2, use {@link
+ * #UnavailableException(String)} instead.
+ *
+ * @param servlet the <code>Servlet</code> instance that is
+ * unavailable
+ *
+ * @param msg a <code>String</code> specifying the
+ * descriptive message
+ *
+ */
+ @Deprecated
+ public UnavailableException(Servlet servlet, String msg) {
+ super(msg);
+ this.servlet = servlet;
+ permanent = true;
+ }
+
+ /**
+ * @deprecated As of Java Servlet API 2.2, use {@link
+ * #UnavailableException(String, int)} instead.
+ *
+ * @param seconds an integer specifying the number of seconds
+ * the servlet expects to be unavailable; if
+ * zero or negative, indicates that the servlet
+ * can't make an estimate
+ *
+ * @param servlet the <code>Servlet</code> that is unavailable
+ *
+ * @param msg a <code>String</code> specifying the descriptive
+ * message, which can be written to a log file or
+ * displayed for the user.
+ *
+ */
+ @Deprecated
+ public UnavailableException(int seconds, Servlet servlet, String msg) {
+ super(msg);
+ this.servlet = servlet;
+ if (seconds <= 0)
+ this.seconds = -1;
+ else
+ this.seconds = seconds;
+ permanent = false;
+ }
+
+ /**
+ *
+ * Constructs a new exception with a descriptive
+ * message indicating that the servlet is permanently
+ * unavailable.
+ *
+ * @param msg a <code>String</code> specifying the
+ * descriptive message
+ *
+ */
+
+ public UnavailableException(String msg) {
+ super(msg);
+
+ permanent = true;
+ }
+
+ /**
+ * Constructs a new exception with a descriptive message
+ * indicating that the servlet is temporarily unavailable
+ * and giving an estimate of how long it will be unavailable.
+ *
+ * <p>In some cases, the servlet cannot make an estimate. For
+ * example, the servlet might know that a server it needs is
+ * not running, but not be able to report how long it will take
+ * to be restored to functionality. This can be indicated with
+ * a negative or zero value for the <code>seconds</code> argument.
+ *
+ * @param msg a <code>String</code> specifying the
+ * descriptive message, which can be written
+ * to a log file or displayed for the user.
+ *
+ * @param seconds an integer specifying the number of seconds
+ * the servlet expects to be unavailable; if
+ * zero or negative, indicates that the servlet
+ * can't make an estimate
+ *
+ */
+
+ public UnavailableException(String msg, int seconds) {
+ super(msg);
+
+ if (seconds <= 0)
+ this.seconds = -1;
+ else
+ this.seconds = seconds;
+
+ permanent = false;
+ }
+
+ /**
+ *
+ * Returns a <code>boolean</code> indicating
+ * whether the servlet is permanently unavailable.
+ * If so, something is wrong with the servlet, and the
+ * system administrator must take some corrective action.
+ *
+ * @return <code>true</code> if the servlet is
+ * permanently unavailable; <code>false</code>
+ * if the servlet is available or temporarily
+ * unavailable
+ *
+ */
+
+ public boolean isPermanent() {
+ return permanent;
+ }
+
+ /**
+ * @deprecated As of Java Servlet API 2.2, with no replacement.
+ *
+ * Returns the servlet that is reporting its unavailability.
+ *
+ * @return the <code>Servlet</code> object that is
+ * throwing the <code>UnavailableException</code>
+ *
+ */
+ @Deprecated
+ public Servlet getServlet() {
+ return servlet;
+ }
+
+ /**
+ * Returns the number of seconds the servlet expects to
+ * be temporarily unavailable.
+ *
+ * <p>If this method returns a negative number, the servlet
+ * is permanently unavailable or cannot provide an estimate of
+ * how long it will be unavailable. No effort is
+ * made to correct for the time elapsed since the exception was
+ * first reported.
+ *
+ * @return an integer specifying the number of seconds
+ * the servlet will be temporarily unavailable,
+ * or a negative number if the servlet is permanently
+ * unavailable or cannot make an estimate
+ *
+ */
+
+ public int getUnavailableSeconds() {
+ return permanent ? -1 : seconds;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/WriteListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/WriteListener.java
new file mode 100644
index 0000000..6d50ecf
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/WriteListener.java
@@ -0,0 +1,74 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet;
+
+import java.io.IOException;
+import java.util.EventListener;
+
+/**
+ *
+ * Callback notification mechanism that signals to the developer it's possible
+ * to write content without blocking.
+ *
+ * @since Servlet 3.1
+ */
+public interface WriteListener extends EventListener {
+
+ /**
+ * When an instance of the WriteListener is registered with a {@link ServletOutputStream},
+ * this method will be invoked by the container the first time when it is possible
+ * to write data. Subsequently the container will invoke this method if and only
+ * if the {@link javax.servlet.ServletOutputStream#isReady()} method
+ * has been called and has returned a value of <code>false</code> and a write
+ * operation has subsequently become possible.
+ *
+ * @throws IOException if an I/O related error has occurred during processing
+ */
+ public void onWritePossible() throws IOException;
+
+ /**
+ * Invoked when an error occurs writing data using the non-blocking APIs.
+ *
+ * @param t the throwable to indicate why the write operation failed
+ */
+ public void onError(final Throwable t);
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HandlesTypes.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HandlesTypes.java
new file mode 100644
index 0000000..2be3cdb
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HandlesTypes.java
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation is used to declare the class types that a
+ * {@link javax.servlet.ServletContainerInitializer
+ * ServletContainerInitializer} can handle.
+ *
+ * @see javax.servlet.ServletContainerInitializer
+ *
+ * @since Servlet 3.0
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HandlesTypes {
+
+ /**
+ * The classes in which a {@link javax.servlet.ServletContainerInitializer
+ * ServletContainerInitializer} has expressed interest.
+ *
+ * <p>If an implementation of <tt>ServletContainerInitializer</tt>
+ * specifies this annotation, the Servlet container must pass the
+ * <tt>Set</tt> of application classes that extend, implement, or have
+ * been annotated with the class types listed by this annotation to
+ * the {@link javax.servlet.ServletContainerInitializer#onStartup}
+ * method of the ServletContainerInitializer (if no matching classes
+ * are found, <tt>null</tt> must be passed instead)
+ *
+ * @return the classes in which {@link javax.servlet.ServletContainerInitializer
+ * ServletContainerInitializer} has expressed interest
+ */
+ Class<?>[] value();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HttpConstraint.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HttpConstraint.java
new file mode 100644
index 0000000..093090f
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HttpConstraint.java
@@ -0,0 +1,113 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
+import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
+
+/**
+ * This annotation is used within the {@link ServletSecurity} annotation to
+ * represent the security constraints to be applied to all HTTP protocol
+ * methods for which a corresponding {@link HttpMethodConstraint} element does
+ * NOT occur within the {@link ServletSecurity} annotation.
+ *
+ * <p>For the special case where an <code>@HttpConstraint</code> that returns
+ * all default values occurs in combination with at least one
+ * {@link HttpMethodConstraint} that returns other than all default values, the
+ * <code>@HttpConstraint</code> represents that no security constraint is to be
+ * applied to any of the HTTP protocol methods to which a security constraint
+ * would otherwise apply. This exception is made to ensure that such
+ * potentially non-specific uses of <code>@HttpConstraint</code> do not yield
+ * constraints that will explicitly establish unprotected access for such
+ * methods; given that they would not otherwise be covered by a constraint.
+ *
+ * @since Servlet 3.0
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HttpConstraint {
+
+ /**
+ * The default authorization semantic.
+ * This value is insignificant when <code>rolesAllowed</code> returns a
+ * non-empty array, and should not be specified when a non-empty
+ * array is specified for <tt>rolesAllowed</tt>.
+ *
+ * @return the {@link EmptyRoleSemantic} to be applied when
+ * <code>rolesAllowed</code> returns an empty (that is, zero-length) array.
+ */
+ EmptyRoleSemantic value() default EmptyRoleSemantic.PERMIT;
+
+ /**
+ * The data protection requirements (i.e., whether or not SSL/TLS is
+ * required) that must be satisfied by the connections on which requests
+ * arrive.
+ *
+ * @return the {@link TransportGuarantee}
+ * indicating the data protection that must be provided by the connection.
+ */
+ TransportGuarantee transportGuarantee() default TransportGuarantee.NONE;
+
+ /**
+ * The names of the authorized roles.
+ *
+ * Duplicate role names appearing in rolesAllowed are insignificant and
+ * may be discarded during runtime processing of the annotation. The String
+ * <tt>"*"</tt> has no special meaning as a role name (should it occur in
+ * rolesAllowed).
+ *
+ * @return an array of zero or more role names. When the array contains
+ * zero elements, its meaning depends on the <code>EmptyRoleSemantic</code>
+ * returned by the <code>value</code> method. If <code>value</code> returns
+ * <tt>DENY</tt>, and <code>rolesAllowed</code> returns a zero length array,
+ * access is to be denied independent of authentication state and identity.
+ * Conversely, if <code>value</code> returns <code>PERMIT</code>, it
+ * indicates that access is to be allowed independent of authentication
+ * state and identity. When the array contains the names of one or more
+ * roles, it indicates that access is contingent on membership in at
+ * least one of the named roles (independent of the
+ * <code>EmptyRoleSemantic</code> returned by the <code>value</code> method).
+ */
+ String[] rolesAllowed() default {};
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HttpMethodConstraint.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HttpMethodConstraint.java
new file mode 100644
index 0000000..e221835
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/HttpMethodConstraint.java
@@ -0,0 +1,110 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
+import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
+
+/**
+ * This annotation is used within the {@link ServletSecurity} annotation to
+ * represent security constraints on specific HTTP protocol messages.
+ *
+ * @since Servlet 3.0
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HttpMethodConstraint {
+
+ /**
+ * Http protocol method name
+ *
+ * @return the name of an HTTP protocol method. <code>value</code>
+ * may not be null, or the empty string, and must be a
+ * legitimate HTTP Method name as defined by RFC 2616.
+ */
+ String value();
+
+ /**
+ * The default authorization semantic.
+ * This value is insignificant when <code>rolesAllowed</code> returns a
+ * non-empty array, and should not be specified when a non-empty
+ * array is specified for <tt>rolesAllowed</tt>.
+ *
+ * @return the {@link EmptyRoleSemantic} to be applied when
+ * <code>rolesAllowed</code> returns an empty (that is, zero-length) array.
+ */
+ EmptyRoleSemantic emptyRoleSemantic() default EmptyRoleSemantic.PERMIT;
+
+ /**
+ * The data protection requirements (i.e., whether or not SSL/TLS is
+ * required) that must be satisfied by the connections on which requests
+ * arrive.
+ *
+ * @return the {@link TransportGuarantee}
+ * indicating the data protection that must be provided by the connection.
+ */
+ TransportGuarantee transportGuarantee() default TransportGuarantee.NONE;
+
+ /**
+ * The names of the authorized roles.
+ *
+ * Duplicate role names appearing in rolesAllowed are insignificant and
+ * may be discarded during runtime processing of the annotation. The String
+ * <tt>"*"</tt> has no special meaning as a role name (should it occur in
+ * rolesAllowed).
+ *
+ * @return an array of zero or more role names. When the array contains
+ * zero elements, its meaning depends on the value returned by
+ * <code>emptyRoleSemantic</code>. If <code>emptyRoleSemantic</code> returns
+ * <tt>DENY</tt>, and <code>rolesAllowed</code> returns a zero length array,
+ * access is to be denied independent of authentication state and identity.
+ * Conversely, if <code>emptyRoleSemantic</code> returns
+ * <code>PERMIT</code>, it indicates that access is to be allowed
+ * independent of authentication state and identity. When the array
+ * contains the names of one or more roles, it indicates that access is
+ * contingent on membership in at least one of the named roles (independent
+ * of the value returned by <code>emptyRoleSemantic</code>).
+ */
+ String[] rolesAllowed() default {};
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/MultipartConfig.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/MultipartConfig.java
new file mode 100644
index 0000000..c3287b5
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/MultipartConfig.java
@@ -0,0 +1,96 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotation that may be specified on a {@link javax.servlet.Servlet}
+ * class, indicating that instances of the <tt>Servlet</tt> expect requests
+ * that conform to the <tt>multipart/form-data</tt> MIME type.
+ *
+ * <p>Servlets annotated with <tt>MultipartConfig</tt> may retrieve the
+ * {@link javax.servlet.http.Part} components of a given
+ * <tt>multipart/form-data</tt> request by calling
+ * {@link javax.servlet.http.HttpServletRequest#getPart getPart} or
+ * {@link javax.servlet.http.HttpServletRequest#getParts getParts}.
+ */
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MultipartConfig {
+
+ /**
+ * The directory location where files will be stored
+ *
+ * @return the directory location where files will be stored
+ */
+ String location() default "";
+
+ /**
+ * The maximum size allowed for uploaded files.
+ *
+ * <p>The default is <tt>-1L</tt>, which means unlimited.
+ *
+ * @return the maximum size allowed for uploaded files
+ */
+ long maxFileSize() default -1L;
+
+ /**
+ * The maximum size allowed for <tt>multipart/form-data</tt>
+ * requests
+ *
+ * <p>The default is <tt>-1L</tt>, which means unlimited.
+ *
+ * @return the maximum size allowed for <tt>multipart/form-data</tt> requests
+ */
+ long maxRequestSize() default -1L;
+
+ /**
+ * The size threshold after which the file will be written to disk
+ *
+ * @return the size threshold after which the file will be written to disk
+ */
+ int fileSizeThreshold() default 0;
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/ServletSecurity.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/ServletSecurity.java
new file mode 100644
index 0000000..bbdf529
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/ServletSecurity.java
@@ -0,0 +1,121 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation is used on a Servlet implementation class to specify security
+ * constraints to be enforced by a Servlet container on HTTP protocol messages.
+ * The Servlet container will enforce these constraints on the url-patterns
+ * mapped to the servlets mapped to the annotated class.
+ *
+ * @since Servlet 3.0
+ */
+
+@Inherited
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ServletSecurity {
+
+ /**
+ * Defines the access semantic to be applied to an empty rolesAllowed array.
+ */
+ enum EmptyRoleSemantic {
+ /**
+ * access is to be permitted independent of authentication state and
+ * identity.
+ */
+ PERMIT,
+ /**
+ * access is to be denied independent of authentication state and
+ * identity.
+ */
+ DENY
+ }
+
+ /**
+ * Defines the data protection requirements that must be satisfied by
+ * the transport
+ */
+ enum TransportGuarantee {
+ /**
+ * no protection of user data must be performed by the transport.
+ */
+ NONE,
+ /**
+ * All user data must be encrypted by the transport (typically
+ * using SSL/TLS).
+ */
+ CONFIDENTIAL
+ }
+
+ /**
+ * Get the {@link HttpConstraint} that defines the protection
+ * that is to be applied to all HTTP methods that are NOT represented in
+ * the array returned by <tt>httpMethodConstraints</tt>.
+ *
+ * @return a <code>HttpConstraint</code> object.
+ */
+ HttpConstraint value() default @HttpConstraint;
+
+ /**
+ * Get the HTTP method specific constraints. Each
+ * {@link HttpMethodConstraint} names an HTTP protocol method
+ * and defines the protection to be applied to it.
+ *
+ * @return an array of {@link HttpMethodConstraint} elements each
+ * defining the protection to be applied to one HTTP protocol method. For
+ * any HTTP method name, there must be at most one corresponding element in
+ * the returned array. If the returned array is of zero length, it indicates
+ * that no HTTP method specific constraints are defined.
+ */
+
+
+ HttpMethodConstraint[] httpMethodConstraints() default {};
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebFilter.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebFilter.java
new file mode 100644
index 0000000..46c4d3e
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebFilter.java
@@ -0,0 +1,147 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+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 javax.servlet.DispatcherType;
+
+/**
+ * Annotation used to declare a servlet filter.
+ *
+ * <p>This annotation is processed by the container at deployment time,
+ * and the corresponding filter applied to the specified URL patterns,
+ * servlets, and dispatcher types.
+ *
+ * @see javax.servlet.Filter
+ *
+ * @since Servlet 3.0
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface WebFilter {
+
+ /**
+ * The description of the filter
+ *
+ * @return the description of the filter
+ */
+ String description() default "";
+
+ /**
+ * The display name of the filter
+ *
+ * @return the display name of the filter
+ */
+ String displayName() default "";
+
+ /**
+ * The init parameters of the filter
+ *
+ * @return the init parameters of the filter
+ */
+ WebInitParam[] initParams() default {};
+
+ /**
+ * The name of the filter
+ *
+ * @return the name of the filter
+ */
+ String filterName() default "";
+
+ /**
+ * The small-icon of the filter
+ *
+ * @return the small-icon of the filter
+ */
+ String smallIcon() default "";
+
+ /**
+ * The large-icon of the filter
+ *
+ * @return the large-icon of the filter
+ */
+ String largeIcon() default "";
+
+ /**
+ * The names of the servlets to which the filter applies.
+ *
+ * @return the names of the servlets to which the filter applies
+ */
+ String[] servletNames() default {};
+
+ /**
+ * The URL patterns to which the filter applies
+ * The default value is an empty array.
+ *
+ * @return the URL patterns to which the filter applies
+ */
+ String[] value() default {};
+
+ /**
+ * The URL patterns to which the filter applies
+ *
+ * @return the URL patterns to which the filter applies
+ */
+ String[] urlPatterns() default {};
+
+ /**
+ * The dispatcher types to which the filter applies
+ *
+ * @return the dispatcher types to which the filter applies
+ */
+ DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};
+
+ /**
+ * Declares whether the filter supports asynchronous operation mode.
+ *
+ * @return {@code true} if the filter supports asynchronous operation mode
+ * @see javax.servlet.ServletRequest#startAsync
+ * @see javax.servlet.ServletRequest#startAsync(ServletRequest,
+ * ServletResponse)
+ */
+ boolean asyncSupported() default false;
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebInitParam.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebInitParam.java
new file mode 100644
index 0000000..50586a1
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebInitParam.java
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.Documented;
+
+/**
+ * This annotation is used on a Servlet or Filter implementation class
+ * to specify an initialization parameter.
+ *
+ * @since Servlet 3.0
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface WebInitParam {
+
+ /**
+ * Name of the initialization parameter
+ *
+ * @return name of the initialization parameter
+ */
+ String name();
+
+ /**
+ * Value of the initialization parameter
+ *
+ * @return value of the initialization parameter
+ */
+ String value();
+
+ /**
+ * Description of the initialization parameter
+ *
+ * @return description of the initialization parameter
+ */
+ String description() default "";
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebListener.java
new file mode 100644
index 0000000..49acb19
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebListener.java
@@ -0,0 +1,73 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+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;
+
+/**
+ * This annotation is used to declare a WebListener.
+ *
+ * Any class annotated with WebListener must implement one or more of
+ * the {@link javax.servlet.ServletContextListener},
+ * {@link javax.servlet.ServletContextAttributeListener},
+ * {@link javax.servlet.ServletRequestListener},
+ * {@link javax.servlet.ServletRequestAttributeListener},
+ * {@link javax.servlet.http.HttpSessionListener}, or
+ * {@link javax.servlet.http.HttpSessionAttributeListener}, or
+ * {@link javax.servlet.http.HttpSessionIdListener} interfaces.
+ *
+ * @since Servlet 3.0
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface WebListener {
+ /**
+ * Description of the listener
+ *
+ * @return description of the listener
+ */
+ String value() default "";
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebServlet.java b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebServlet.java
new file mode 100644
index 0000000..aa32498
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/WebServlet.java
@@ -0,0 +1,138 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+
+/**
+ * Annotation used to declare a servlet.
+ *
+ * <p>This annotation is processed by the container at deployment time,
+ * and the corresponding servlet made available at the specified URL
+ * patterns.
+ *
+ * @see javax.servlet.Servlet
+ *
+ * @since Servlet 3.0
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface WebServlet {
+
+ /**
+ * The name of the servlet
+ *
+ * @return the name of the servlet
+ */
+ String name() default "";
+
+ /**
+ * The URL patterns of the servlet
+ *
+ * @return the URL patterns of the servlet
+ */
+ String[] value() default {};
+
+ /**
+ * The URL patterns of the servlet
+ *
+ * @return the URL patterns of the servlet
+ */
+ String[] urlPatterns() default {};
+
+ /**
+ * The load-on-startup order of the servlet
+ *
+ * @return the load-on-startup order of the servlet
+ */
+ int loadOnStartup() default -1;
+
+ /**
+ * The init parameters of the servlet
+ *
+ * @return the init parameters of the servlet
+ */
+ WebInitParam [] initParams() default {};
+
+ /**
+ * Declares whether the servlet supports asynchronous operation mode.
+ *
+ * @return {@code true} if the servlet supports asynchronous operation mode
+ * @see javax.servlet.ServletRequest#startAsync
+ * @see javax.servlet.ServletRequest#startAsync(ServletRequest,
+ * ServletResponse)
+ */
+ boolean asyncSupported() default false;
+
+ /**
+ * The small-icon of the servlet
+ *
+ * @return the small-icon of the servlet
+ */
+ String smallIcon() default "";
+
+ /**
+ * The large-icon of the servlet
+ *
+ * @return the large-icon of the servlet
+ */
+ String largeIcon() default "";
+
+ /**
+ * The description of the servlet
+ *
+ * @return the description of the servlet
+ */
+ String description() default "";
+
+ /**
+ * The display name of the servlet
+ *
+ * @return the display name of the servlet
+ */
+ String displayName() default "";
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/annotation/package.html b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/package.html
new file mode 100644
index 0000000..11b7bb2
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/annotation/package.html
@@ -0,0 +1,57 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2008-2017 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ or LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+
+
+</HEAD>
+<BODY BGCOLOR="white">
+
+The javax.servlet.annotation package contains a number of annotations
+that allow users to use annotations to declare servlets, filters,
+listeners and specify the metadata for the declared component.
+
+@since Servlet 3.0
+</BODY>
+</HTML>
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/JspConfigDescriptor.java b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/JspConfigDescriptor.java
new file mode 100644
index 0000000..ac8281c
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/JspConfigDescriptor.java
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.descriptor;
+
+import java.util.Collection;
+
+/**
+ * This interface provides access to the <code><jsp-config></code>
+ * related configuration of a web application.
+ *
+ * <p>The configuration is aggregated from the <code>web.xml</code> and
+ * <code>web-fragment.xml</code> descriptor files of the web application.
+ *
+ * @since Servlet 3.0
+ */
+public interface JspConfigDescriptor {
+
+ /**
+ * Gets the <code><taglib></code> child elements of the
+ * <code><jsp-config></code> element represented by this
+ * <code>JspConfigDescriptor</code>.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>JspConfigDescriptor</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the
+ * <code><taglib></code> child elements of the
+ * <code><jsp-config></code> element represented by this
+ * <code>JspConfigDescriptor</code>
+ */
+ public Collection<TaglibDescriptor> getTaglibs();
+
+ /**
+ * Gets the <code><jsp-property-group></code> child elements
+ * of the <code><jsp-config></code> element represented by this
+ * <code>JspConfigDescriptor</code>.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>JspConfigDescriptor</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the
+ * <code><jsp-property-group></code> child elements of the
+ * <code><jsp-config></code> element represented by this
+ * <code>JspConfigDescriptor</code>
+ */
+ public Collection<JspPropertyGroupDescriptor> getJspPropertyGroups();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/JspPropertyGroupDescriptor.java b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/JspPropertyGroupDescriptor.java
new file mode 100644
index 0000000..b088cfa
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/JspPropertyGroupDescriptor.java
@@ -0,0 +1,204 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.descriptor;
+
+import java.util.Collection;
+
+/**
+ * This interface provides access to the
+ * <code><jsp-property-group></code>
+ * related configuration of a web application.
+ *
+ * <p>The configuration is aggregated from the <code>web.xml</code> and
+ * <code>web-fragment.xml</code> descriptor files of the web application.
+ *
+ * @since Servlet 3.0
+ */
+public interface JspPropertyGroupDescriptor {
+
+ /**
+ * Gets the URL patterns of the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the URL
+ * patterns of the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>
+ */
+ public Collection<String> getUrlPatterns();
+
+ /**
+ * Gets the value of the <code>el-ignored</code> configuration, which
+ * specifies whether Expression Language (EL) evaluation is enabled for
+ * any JSP pages mapped to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>el-ignored</code> configuration, or
+ * null if unspecified
+ */
+ public String getElIgnored();
+
+ /**
+ * Gets the value of the <code>page-encoding</code> configuration,
+ * which specifies the default page encoding for any JSP pages mapped
+ * to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>page-encoding</code> configuration, or
+ * null if unspecified
+ */
+ public String getPageEncoding();
+
+ /**
+ * Gets the value of the <code>scripting-invalid</code> configuration,
+ * which specifies whether scripting is enabled for any JSP pages mapped
+ * to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>scripting-invalid</code> configuration,
+ * or null if unspecified
+ */
+ public String getScriptingInvalid();
+
+ /**
+ * Gets the value of the <code>is-xml</code> configuration, which
+ * specifies whether any JSP pages mapped to the JSP property group
+ * represented by this <code>JspPropertyGroupDescriptor</code> will
+ * be treated as JSP documents (XML syntax).
+ *
+ * @return the value of the <code>is-xml</code> configuration, or
+ * null if unspecified
+ */
+ public String getIsXml();
+
+ /**
+ * Gets the <code>include-prelude</code> configuration
+ * of the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the
+ * <code>include-prelude</code> configuration of
+ * the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>
+ */
+ public Collection<String> getIncludePreludes();
+
+ /**
+ * Gets the <code>include-coda</code> configuration
+ * of the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the
+ * <code>include-coda</code> configuration of
+ * the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>
+ */
+ public Collection<String> getIncludeCodas();
+
+ /**
+ * Gets the value of the
+ * <code>deferred-syntax-allowed-as-literal</code> configuration, which
+ * specifies whether the character sequence <code>"#{"</code>,
+ * which is normally reserved for Expression Language (EL) expressions,
+ * will cause a translation error if it appears as a String literal
+ * in any JSP pages mapped to the JSP property group represented by
+ * this <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the
+ * <code>deferred-syntax-allowed-as-literal</code> configuration, or
+ * null if unspecified
+ */
+ public String getDeferredSyntaxAllowedAsLiteral();
+
+ /**
+ * Gets the value of the <code>trim-directive-whitespaces</code>
+ * configuration, which specifies whether template text containing only
+ * whitespaces must be removed from the response output of any JSP
+ * pages mapped to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>trim-directive-whitespaces</code>
+ * configuration, or null if unspecified
+ */
+ public String getTrimDirectiveWhitespaces();
+
+ /**
+ * Gets the value of the <code>default-content-type</code> configuration,
+ * which specifies the default response content type for any JSP pages
+ * mapped to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>default-content-type</code>
+ * configuration, or null if unspecified
+ */
+ public String getDefaultContentType();
+
+ /**
+ * Gets the value of the <code>buffer</code> configuration, which
+ * specifies the default size of the response buffer for any JSP pages
+ * mapped to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>buffer</code> configuration, or
+ * null if unspecified
+ */
+ public String getBuffer();
+
+ /**
+ * Gets the value of the <code>error-on-undeclared-namespace</code>
+ * configuration, which specifies whether an error will be raised at
+ * translation time if tag with an undeclared namespace is used in
+ * any JSP pages mapped to the JSP property group represented by this
+ * <code>JspPropertyGroupDescriptor</code>.
+ *
+ * @return the value of the <code>error-on-undeclared-namespace</code>
+ * configuration, or null if unspecified
+ */
+ public String getErrorOnUndeclaredNamespace();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/TaglibDescriptor.java b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/TaglibDescriptor.java
new file mode 100644
index 0000000..19ee530
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/TaglibDescriptor.java
@@ -0,0 +1,71 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.descriptor;
+
+/**
+ * This interface provides access to the <code><taglib></code>
+ * related configuration of a web application.
+ *
+ * <p>The configuration is aggregated from the <code>web.xml</code> and
+ * <code>web-fragment.xml</code> descriptor files of the web application.
+ *
+ * @since Servlet 3.0
+ */
+public interface TaglibDescriptor {
+
+ /**
+ * Gets the unique identifier of the tag library represented by this
+ * TaglibDescriptor.
+ *
+ * @return the unique identifier of the tag library represented by this
+ * TaglibDescriptor
+ */
+ public String getTaglibURI();
+
+ /**
+ * Gets the location of the tag library represented by this
+ * TaglibDescriptor.
+ *
+ * @return the location of the tag library represented by this
+ * TaglibDescriptor
+ */
+ public String getTaglibLocation();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/package.html b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/package.html
new file mode 100644
index 0000000..d25c845
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/descriptor/package.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2009-2017 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ or LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+</head>
+<body bgcolor="white">
+
+Provides programmatic access to a web application's configuration information that was aggregated from the <code>web.xml</code> and <code>web-fragment.xml</code> descriptors.
+
+@since Servlet 3.0
+</body>
+</html>
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/Cookie.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/Cookie.java
new file mode 100644
index 0000000..cfd8582
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/Cookie.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely
+ * identify a client, so cookies are commonly used for session management.
+ *
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the
+ * optional attributes, so use them sparingly to improve the interoperability
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {@link HttpServletResponse#addCookie} method, which adds
+ * fields to HTTP response headers to send cookies to the
+ * browser, one at a time. The browser is expected to
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ *
+ * <p>The browser returns cookies to the servlet by adding
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {@link HttpServletRequest#getCookies} method.
+ * Several cookies might have the same name but different path attributes.
+ *
+ * <p>Cookies affect the caching of the Web pages that use them.
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ * @author Various
+ */
+public class Cookie implements Cloneable, Serializable {
+
+ private static final long serialVersionUID = -6454587001725327448L;
+
+ private static final String TSPECIALS;
+
+ private static final String LSTRING_FILE =
+ "javax.servlet.http.LocalStrings";
+
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+ static {
+ if (Boolean.valueOf(System.getProperty("org.glassfish.web.rfc2109_cookie_names_enforced", "true"))) {
+ TSPECIALS = "/()<>@,;:\\\"[]?={} \t";
+ } else {
+ TSPECIALS = ",; ";
+ }
+ }
+
+ //
+ // The value of the cookie itself.
+ //
+
+ private String name; // NAME= ... "$Name" style is reserved
+ private String value; // value of NAME
+
+ //
+ // Attributes encoded in the header's cookie fields.
+ //
+
+ private String comment; // ;Comment=VALUE ... describes cookie's use
+ // ;Discard ... implied by maxAge < 0
+ private String domain; // ;Domain=VALUE ... domain that sees cookie
+ private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire
+ private String path; // ;Path=VALUE ... URLs that see the cookie
+ private boolean secure; // ;Secure ... e.g. use SSL
+ private int version = 0; // ;Version=1 ... means RFC 2109++ style
+ private boolean isHttpOnly = false;
+
+ /**
+ * Constructs a cookie with the specified name and value.
+ *
+ * <p>The name must conform to RFC 2109. However, vendors may
+ * provide a configuration option that allows cookie names conforming
+ * to the original Netscape Cookie Specification to be accepted.
+ *
+ * <p>The name of a cookie cannot be changed once the cookie has
+ * been created.
+ *
+ * <p>The value can be anything the server chooses to send. Its
+ * value is probably of interest only to the server. The cookie's
+ * value can be changed after creation with the
+ * <code>setValue</code> method.
+ *
+ * <p>By default, cookies are created according to the Netscape
+ * cookie specification. The version can be changed with the
+ * <code>setVersion</code> method.
+ *
+ * @param name the name of the cookie
+ *
+ * @param value the value of the cookie
+ *
+ * @throws IllegalArgumentException if the cookie name is null or
+ * empty or contains any illegal characters (for example, a comma,
+ * space, or semicolon) or matches a token reserved for use by the
+ * cookie protocol
+ *
+ * @see #setValue
+ * @see #setVersion
+ */
+ public Cookie(String name, String value) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException(
+ lStrings.getString("err.cookie_name_blank"));
+ }
+ if (!isToken(name) ||
+ name.equalsIgnoreCase("Comment") || // rfc2019
+ name.equalsIgnoreCase("Discard") || // 2019++
+ name.equalsIgnoreCase("Domain") ||
+ name.equalsIgnoreCase("Expires") || // (old cookies)
+ name.equalsIgnoreCase("Max-Age") || // rfc2019
+ name.equalsIgnoreCase("Path") ||
+ name.equalsIgnoreCase("Secure") ||
+ name.equalsIgnoreCase("Version") ||
+ name.startsWith("$")) {
+ String errMsg = lStrings.getString("err.cookie_name_is_token");
+ Object[] errArgs = new Object[1];
+ errArgs[0] = name;
+ errMsg = MessageFormat.format(errMsg, errArgs);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Specifies a comment that describes a cookie's purpose.
+ * The comment is useful if the browser presents the cookie
+ * to the user. Comments
+ * are not supported by Netscape Version 0 cookies.
+ *
+ * @param purpose a <code>String</code> specifying the comment
+ * to display to the user
+ *
+ * @see #getComment
+ */
+ public void setComment(String purpose) {
+ comment = purpose;
+ }
+
+ /**
+ * Returns the comment describing the purpose of this cookie, or
+ * <code>null</code> if the cookie has no comment.
+ *
+ * @return the comment of the cookie, or <code>null</code> if unspecified
+ *
+ * @see #setComment
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ *
+ * Specifies the domain within which this cookie should be presented.
+ *
+ * <p>The form of the domain name is specified by RFC 2109. A domain
+ * name begins with a dot (<code>.foo.com</code>) and means that
+ * the cookie is visible to servers in a specified Domain Name System
+ * (DNS) zone (for example, <code>www.foo.com</code>, but not
+ * <code>a.b.foo.com</code>). By default, cookies are only returned
+ * to the server that sent them.
+ *
+ * @param domain the domain name within which this cookie is visible;
+ * form is according to RFC 2109
+ *
+ * @see #getDomain
+ */
+ public void setDomain(String domain) {
+ this.domain = domain.toLowerCase(Locale.ENGLISH); // IE allegedly needs this
+ }
+
+ /**
+ * Gets the domain name of this Cookie.
+ *
+ * <p>Domain names are formatted according to RFC 2109.
+ *
+ * @return the domain name of this Cookie
+ *
+ * @see #setDomain
+ */
+ public String getDomain() {
+ return domain;
+ }
+
+ /**
+ * Sets the maximum age in seconds for this Cookie.
+ *
+ * <p>A positive value indicates that the cookie will expire
+ * after that many seconds have passed. Note that the value is
+ * the <i>maximum</i> age when the cookie will expire, not the cookie's
+ * current age.
+ *
+ * <p>A negative value means
+ * that the cookie is not stored persistently and will be deleted
+ * when the Web browser exits. A zero value causes the cookie
+ * to be deleted.
+ *
+ * @param expiry an integer specifying the maximum age of the
+ * cookie in seconds; if negative, means
+ * the cookie is not stored; if zero, deletes
+ * the cookie
+ *
+ * @see #getMaxAge
+ */
+ public void setMaxAge(int expiry) {
+ maxAge = expiry;
+ }
+
+ /**
+ * Gets the maximum age in seconds of this Cookie.
+ *
+ * <p>By default, <code>-1</code> is returned, which indicates that
+ * the cookie will persist until browser shutdown.
+ *
+ * @return an integer specifying the maximum age of the
+ * cookie in seconds; if negative, means
+ * the cookie persists until browser shutdown
+ *
+ * @see #setMaxAge
+ */
+ public int getMaxAge() {
+ return maxAge;
+ }
+
+ /**
+ * Specifies a path for the cookie
+ * to which the client should return the cookie.
+ *
+ * <p>The cookie is visible to all the pages in the directory
+ * you specify, and all the pages in that directory's subdirectories.
+ * A cookie's path must include the servlet that set the cookie,
+ * for example, <i>/catalog</i>, which makes the cookie
+ * visible to all directories on the server under <i>/catalog</i>.
+ *
+ * <p>Consult RFC 2109 (available on the Internet) for more
+ * information on setting path names for cookies.
+ *
+ *
+ * @param uri a <code>String</code> specifying a path
+ *
+ * @see #getPath
+ */
+ public void setPath(String uri) {
+ path = uri;
+ }
+
+ /**
+ * Returns the path on the server
+ * to which the browser returns this cookie. The
+ * cookie is visible to all subpaths on the server.
+ *
+ * @return a <code>String</code> specifying a path that contains
+ * a servlet name, for example, <i>/catalog</i>
+ *
+ * @see #setPath
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Indicates to the browser whether the cookie should only be sent
+ * using a secure protocol, such as HTTPS or SSL.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * @param flag if <code>true</code>, sends the cookie from the browser
+ * to the server only when using a secure protocol; if <code>false</code>,
+ * sent on any protocol
+ *
+ * @see #getSecure
+ */
+ public void setSecure(boolean flag) {
+ secure = flag;
+ }
+
+ /**
+ * Returns <code>true</code> if the browser is sending cookies
+ * only over a secure protocol, or <code>false</code> if the
+ * browser can send cookies using any protocol.
+ *
+ * @return <code>true</code> if the browser uses a secure protocol,
+ * <code>false</code> otherwise
+ *
+ * @see #setSecure
+ */
+ public boolean getSecure() {
+ return secure;
+ }
+
+ /**
+ * Returns the name of the cookie. The name cannot be changed after
+ * creation.
+ *
+ * @return the name of the cookie
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Assigns a new value to this Cookie.
+ *
+ * <p>If you use a binary value, you may want to use BASE64 encoding.
+ *
+ * <p>With Version 0 cookies, values should not contain white
+ * space, brackets, parentheses, equals signs, commas,
+ * double quotes, slashes, question marks, at signs, colons,
+ * and semicolons. Empty values may not behave the same way
+ * on all browsers.
+ *
+ * @param newValue the new value of the cookie
+ *
+ * @see #getValue
+ */
+ public void setValue(String newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Gets the current value of this Cookie.
+ *
+ * @return the current value of this Cookie
+ *
+ * @see #setValue
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Returns the version of the protocol this cookie complies
+ * with. Version 1 complies with RFC 2109,
+ * and version 0 complies with the original
+ * cookie specification drafted by Netscape. Cookies provided
+ * by a browser use and identify the browser's cookie version.
+ *
+ * @return 0 if the cookie complies with the
+ * original Netscape specification; 1
+ * if the cookie complies with RFC 2109
+ *
+ * @see #setVersion
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the version of the cookie protocol that this Cookie complies
+ * with.
+ *
+ * <p>Version 0 complies with the original Netscape cookie
+ * specification. Version 1 complies with RFC 2109.
+ *
+ * <p>Since RFC 2109 is still somewhat new, consider
+ * version 1 as experimental; do not use it yet on production sites.
+ *
+ * @param v 0 if the cookie should comply with the original Netscape
+ * specification; 1 if the cookie should comply with RFC 2109
+ *
+ * @see #getVersion
+ */
+ public void setVersion(int v) {
+ version = v;
+ }
+
+ /*
+ * Tests a string and returns true if the string counts as a
+ * reserved token in the Java language.
+ *
+ * @param value the <code>String</code> to be tested
+ *
+ * @return <code>true</code> if the <code>String</code> is a reserved
+ * token; <code>false</code> otherwise
+ */
+ private boolean isToken(String value) {
+ int len = value.length();
+ for (int i = 0; i < len; i++) {
+ char c = value.charAt(i);
+ if (c < 0x20 || c >= 0x7f || TSPECIALS.indexOf(c) != -1) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Overrides the standard <code>java.lang.Object.clone</code>
+ * method to return a copy of this Cookie.
+ */
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ /**
+ * Marks or unmarks this Cookie as <i>HttpOnly</i>.
+ *
+ * <p>If <tt>isHttpOnly</tt> is set to <tt>true</tt>, this cookie is
+ * marked as <i>HttpOnly</i>, by adding the <tt>HttpOnly</tt> attribute
+ * to it.
+ *
+ * <p><i>HttpOnly</i> cookies are not supposed to be exposed to
+ * client-side scripting code, and may therefore help mitigate certain
+ * kinds of cross-site scripting attacks.
+ *
+ * @param isHttpOnly true if this cookie is to be marked as
+ * <i>HttpOnly</i>, false otherwise
+ *
+ * @since Servlet 3.0
+ */
+ public void setHttpOnly(boolean isHttpOnly) {
+ this.isHttpOnly = isHttpOnly;
+ }
+
+ /**
+ * Checks whether this Cookie has been marked as <i>HttpOnly</i>.
+ *
+ * @return true if this Cookie has been marked as <i>HttpOnly</i>,
+ * false otherwise
+ *
+ * @since Servlet 3.0
+ */
+ public boolean isHttpOnly() {
+ return isHttpOnly;
+ }
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpFilter.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpFilter.java
new file mode 100644
index 0000000..5b3635d
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpFilter.java
@@ -0,0 +1,164 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import javax.servlet.FilterChain;
+import javax.servlet.GenericFilter;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+
+/**
+ *
+ * <p>Provides an abstract class to be subclassed to create
+ * an HTTP filter suitable for a Web site. A subclass of
+ * <code>HttpFilter</code> should override {@link #doFilter(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain) }.</p>
+ *
+ * <p>Filters typically run on multithreaded servers,
+ * so be aware that a filter must handle concurrent
+ * requests and be careful to synchronize access to shared resources.
+ * Shared resources include in-memory data such as
+ * instance or class variables and external objects
+ * such as files, database connections, and network
+ * connections.
+ * See the
+ * <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/">
+ * Java Tutorial on Multithreaded Programming</a> for more
+ * information on handling multiple threads in a Java program.
+ *
+ * @author Various
+ *
+ * @since Servlet 4.0
+ */
+
+public abstract class HttpFilter extends GenericFilter
+{
+
+ /**
+ * <p>Does nothing, because this is an abstract class.</p>
+ *
+ * @since 4.0
+ */
+
+ public HttpFilter() { }
+
+ /**
+ *
+ * <p>The <code>doFilter</code> method of the Filter is called by the
+ * container each time a request/response pair is passed through the
+ * chain due to a client request for a resource at the end of the chain.
+ * The FilterChain passed in to this method allows the Filter to pass
+ * on the request and response to the next entity in the chain. There's no need to
+ * override this method.</p>
+ *
+ * <p>The default implementation inspects the incoming {@code req} and {@code res}
+ * objects to determine if they are instances of {@link HttpServletRequest}
+ * and {@link HttpServletResponse}, respectively. If not, a {@link ServletException} is thrown.
+ * Otherwise, the protected {@link #doFilter(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain)}
+ * method is called.</p>
+ *
+ * @param req a {@link ServletRequest} object that
+ * contains the request the client has made
+ * of the filter
+ *
+ * @param res a {@link ServletResponse} object that
+ * contains the response the filter sends
+ * to the client
+ *
+ * @param chain the <code>FilterChain</code> for invoking the next filter or the resource
+ *
+ * @throws IOException if an input or output error is
+ * detected when the filter handles
+ * the request
+ *
+ * @throws ServletException if the request for the could not be handled or
+ * either parameter is not an instance of the respective {@link HttpServletRequest}
+ * or {@link HttpServletResponse}.
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
+ if (!(req instanceof HttpServletRequest &&
+ res instanceof HttpServletResponse)) {
+ throw new ServletException("non-HTTP request or response");
+ }
+
+ this.doFilter((HttpServletRequest)req, (HttpServletResponse)res, chain);
+ }
+
+ /**
+ *
+ * <p>The <code>doFilter</code> method of the Filter is called by the
+ * container each time a request/response pair is passed through the
+ * chain due to a client request for a resource at the end of the chain.
+ * The FilterChain passed in to this method allows the Filter to pass
+ * on the request and response to the next entity in the chain.</p>
+ *
+ * <p>The default implementation simply calls {@link FilterChain#doFilter}</p>
+ *
+ * @param req a {@link HttpServletRequest} object that
+ * contains the request the client has made
+ * of the filter
+ *
+ * @param res a {@link HttpServletResponse} object that
+ * contains the response the filter sends
+ * to the client
+ *
+ * @param chain the <code>FilterChain</code> for invoking the next filter or the resource
+ *
+ * @throws IOException if an input or output error is
+ * detected when the filter handles
+ * the request
+ *
+ * @throws ServletException if the request for the could not be handled
+ *
+ * @since Servlet 4.0
+ */
+ protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
+ chain.doFilter(req, res);
+ }
+
+}
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServlet.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServlet.java
new file mode 100644
index 0000000..46f16f0
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServlet.java
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+
+import javax.servlet.*;
+
+
+/**
+ *
+ * Provides an abstract class to be subclassed to create
+ * an HTTP servlet suitable for a Web site. A subclass of
+ * <code>HttpServlet</code> must override at least
+ * one method, usually one of these:
+ *
+ * <ul>
+ * <li> <code>doGet</code>, if the servlet supports HTTP GET requests
+ * <li> <code>doPost</code>, for HTTP POST requests
+ * <li> <code>doPut</code>, for HTTP PUT requests
+ * <li> <code>doDelete</code>, for HTTP DELETE requests
+ * <li> <code>init</code> and <code>destroy</code>,
+ * to manage resources that are held for the life of the servlet
+ * <li> <code>getServletInfo</code>, which the servlet uses to
+ * provide information about itself
+ * </ul>
+ *
+ * <p>There's almost no reason to override the <code>service</code>
+ * method. <code>service</code> handles standard HTTP
+ * requests by dispatching them to the handler methods
+ * for each HTTP request type (the <code>do</code><i>XXX</i>
+ * methods listed above).
+ *
+ * <p>Likewise, there's almost no reason to override the
+ * <code>doOptions</code> and <code>doTrace</code> methods.
+ *
+ * <p>Servlets typically run on multithreaded servers,
+ * so be aware that a servlet must handle concurrent
+ * requests and be careful to synchronize access to shared resources.
+ * Shared resources include in-memory data such as
+ * instance or class variables and external objects
+ * such as files, database connections, and network
+ * connections.
+ * See the
+ * <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/">
+ * Java Tutorial on Multithreaded Programming</a> for more
+ * information on handling multiple threads in a Java program.
+ *
+ * @author Various
+ */
+
+public abstract class HttpServlet extends GenericServlet
+{
+ private static final String METHOD_DELETE = "DELETE";
+ private static final String METHOD_HEAD = "HEAD";
+ private static final String METHOD_GET = "GET";
+ private static final String METHOD_OPTIONS = "OPTIONS";
+ private static final String METHOD_POST = "POST";
+ private static final String METHOD_PUT = "PUT";
+ private static final String METHOD_TRACE = "TRACE";
+
+ private static final String HEADER_IFMODSINCE = "If-Modified-Since";
+ private static final String HEADER_LASTMOD = "Last-Modified";
+
+ private static final String LSTRING_FILE =
+ "javax.servlet.http.LocalStrings";
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+
+ /**
+ * Does nothing, because this is an abstract class.
+ *
+ */
+
+ public HttpServlet() { }
+
+
+ /**
+ *
+ * Called by the server (via the <code>service</code> method) to
+ * allow a servlet to handle a GET request.
+ *
+ * <p>Overriding this method to support a GET request also
+ * automatically supports an HTTP HEAD request. A HEAD
+ * request is a GET request that returns no body in the
+ * response, only the request header fields.
+ *
+ * <p>When overriding this method, read the request data,
+ * write the response headers, get the response's writer or
+ * output stream object, and finally, write the response data.
+ * It's best to include content type and encoding. When using
+ * a <code>PrintWriter</code> object to return the response,
+ * set the content type before accessing the
+ * <code>PrintWriter</code> object.
+ *
+ * <p>The servlet container must write the headers before
+ * committing the response, because in HTTP the headers must be sent
+ * before the response body.
+ *
+ * <p>Where possible, set the Content-Length header (with the
+ * {@link javax.servlet.ServletResponse#setContentLength} method),
+ * to allow the servlet container to use a persistent connection
+ * to return its response to the client, improving performance.
+ * The content length is automatically set if the entire response fits
+ * inside the response buffer.
+ *
+ * <p>When using HTTP 1.1 chunked encoding (which means that the response
+ * has a Transfer-Encoding header), do not set the Content-Length header.
+ *
+ * <p>The GET method should be safe, that is, without
+ * any side effects for which users are held responsible.
+ * For example, most form queries have no side effects.
+ * If a client request is intended to change stored data,
+ * the request should use some other HTTP method.
+ *
+ * <p>The GET method should also be idempotent, meaning
+ * that it can be safely repeated. Sometimes making a
+ * method safe also makes it idempotent. For example,
+ * repeating queries is both safe and idempotent, but
+ * buying a product online or modifying data is neither
+ * safe nor idempotent.
+ *
+ * <p>If the request is incorrectly formatted, <code>doGet</code>
+ * returns an HTTP "Bad Request" message.
+ *
+ * @param req an {@link HttpServletRequest} object that
+ * contains the request the client has made
+ * of the servlet
+ *
+ * @param resp an {@link HttpServletResponse} object that
+ * contains the response the servlet sends
+ * to the client
+ *
+ * @throws IOException if an input or output error is
+ * detected when the servlet handles
+ * the GET request
+ *
+ * @throws ServletException if the request for the GET
+ * could not be handled
+ *
+ * @see javax.servlet.ServletResponse#setContentType
+ */
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ String protocol = req.getProtocol();
+ String msg = lStrings.getString("http.method_get_not_supported");
+ if (protocol.endsWith("1.1")) {
+ resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+ }
+ }
+
+
+ /**
+ *
+ * Returns the time the <code>HttpServletRequest</code>
+ * object was last modified,
+ * in milliseconds since midnight January 1, 1970 GMT.
+ * If the time is unknown, this method returns a negative
+ * number (the default).
+ *
+ * <p>Servlets that support HTTP GET requests and can quickly determine
+ * their last modification time should override this method.
+ * This makes browser and proxy caches work more effectively,
+ * reducing the load on server and network resources.
+ *
+ * @param req the <code>HttpServletRequest</code>
+ * object that is sent to the servlet
+ *
+ * @return a <code>long</code> integer specifying
+ * the time the <code>HttpServletRequest</code>
+ * object was last modified, in milliseconds
+ * since midnight, January 1, 1970 GMT, or
+ * -1 if the time is not known
+ */
+
+ protected long getLastModified(HttpServletRequest req) {
+ return -1;
+ }
+
+
+ /**
+ *
+ *
+ * <p>Receives an HTTP HEAD request from the protected
+ * <code>service</code> method and handles the
+ * request.
+ * The client sends a HEAD request when it wants
+ * to see only the headers of a response, such as
+ * Content-Type or Content-Length. The HTTP HEAD
+ * method counts the output bytes in the response
+ * to set the Content-Length header accurately.
+ *
+ * <p>If you override this method, you can avoid computing
+ * the response body and just set the response headers
+ * directly to improve performance. Make sure that the
+ * <code>doHead</code> method you write is both safe
+ * and idempotent (that is, protects itself from being
+ * called multiple times for one HTTP HEAD request).
+ *
+ * <p>If the HTTP HEAD request is incorrectly formatted,
+ * <code>doHead</code> returns an HTTP "Bad Request"
+ * message.
+ *
+ * @param req the request object that is passed to the servlet
+ *
+ * @param resp the response object that the servlet
+ * uses to return the headers to the clien
+ *
+ * @throws IOException if an input or output error occurs
+ *
+ * @throws ServletException if the request for the HEAD
+ * could not be handled
+ */
+ protected void doHead(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ NoBodyResponse response = new NoBodyResponse(resp);
+
+ doGet(req, response);
+ response.setContentLength();
+ }
+
+
+ /**
+ *
+ * Called by the server (via the <code>service</code> method)
+ * to allow a servlet to handle a POST request.
+ *
+ * The HTTP POST method allows the client to send
+ * data of unlimited length to the Web server a single time
+ * and is useful when posting information such as
+ * credit card numbers.
+ *
+ * <p>When overriding this method, read the request data,
+ * write the response headers, get the response's writer or output
+ * stream object, and finally, write the response data. It's best
+ * to include content type and encoding. When using a
+ * <code>PrintWriter</code> object to return the response, set the
+ * content type before accessing the <code>PrintWriter</code> object.
+ *
+ * <p>The servlet container must write the headers before committing the
+ * response, because in HTTP the headers must be sent before the
+ * response body.
+ *
+ * <p>Where possible, set the Content-Length header (with the
+ * {@link javax.servlet.ServletResponse#setContentLength} method),
+ * to allow the servlet container to use a persistent connection
+ * to return its response to the client, improving performance.
+ * The content length is automatically set if the entire response fits
+ * inside the response buffer.
+ *
+ * <p>When using HTTP 1.1 chunked encoding (which means that the response
+ * has a Transfer-Encoding header), do not set the Content-Length header.
+ *
+ * <p>This method does not need to be either safe or idempotent.
+ * Operations requested through POST can have side effects for
+ * which the user can be held accountable, for example,
+ * updating stored data or buying items online.
+ *
+ * <p>If the HTTP POST request is incorrectly formatted,
+ * <code>doPost</code> returns an HTTP "Bad Request" message.
+ *
+ *
+ * @param req an {@link HttpServletRequest} object that
+ * contains the request the client has made
+ * of the servlet
+ *
+ * @param resp an {@link HttpServletResponse} object that
+ * contains the response the servlet sends
+ * to the client
+ *
+ * @throws IOException if an input or output error is
+ * detected when the servlet handles
+ * the request
+ *
+ * @throws ServletException if the request for the POST
+ * could not be handled
+ *
+ * @see javax.servlet.ServletOutputStream
+ * @see javax.servlet.ServletResponse#setContentType
+ */
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ String protocol = req.getProtocol();
+ String msg = lStrings.getString("http.method_post_not_supported");
+ if (protocol.endsWith("1.1")) {
+ resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+ }
+ }
+
+
+ /**
+ * Called by the server (via the <code>service</code> method)
+ * to allow a servlet to handle a PUT request.
+ *
+ * The PUT operation allows a client to
+ * place a file on the server and is similar to
+ * sending a file by FTP.
+ *
+ * <p>When overriding this method, leave intact
+ * any content headers sent with the request (including
+ * Content-Length, Content-Type, Content-Transfer-Encoding,
+ * Content-Encoding, Content-Base, Content-Language, Content-Location,
+ * Content-MD5, and Content-Range). If your method cannot
+ * handle a content header, it must issue an error message
+ * (HTTP 501 - Not Implemented) and discard the request.
+ * For more information on HTTP 1.1, see RFC 2616
+ * <a href="http://www.ietf.org/rfc/rfc2616.txt"></a>.
+ *
+ * <p>This method does not need to be either safe or idempotent.
+ * Operations that <code>doPut</code> performs can have side
+ * effects for which the user can be held accountable. When using
+ * this method, it may be useful to save a copy of the
+ * affected URL in temporary storage.
+ *
+ * <p>If the HTTP PUT request is incorrectly formatted,
+ * <code>doPut</code> returns an HTTP "Bad Request" message.
+ *
+ * @param req the {@link HttpServletRequest} object that
+ * contains the request the client made of
+ * the servlet
+ *
+ * @param resp the {@link HttpServletResponse} object that
+ * contains the response the servlet returns
+ * to the client
+ *
+ * @throws IOException if an input or output error occurs
+ * while the servlet is handling the
+ * PUT request
+ *
+ * @throws ServletException if the request for the PUT
+ * cannot be handled
+ */
+ protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ String protocol = req.getProtocol();
+ String msg = lStrings.getString("http.method_put_not_supported");
+ if (protocol.endsWith("1.1")) {
+ resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+ }
+ }
+
+
+ /**
+ * Called by the server (via the <code>service</code> method)
+ * to allow a servlet to handle a DELETE request.
+ *
+ * The DELETE operation allows a client to remove a document
+ * or Web page from the server.
+ *
+ * <p>This method does not need to be either safe
+ * or idempotent. Operations requested through
+ * DELETE can have side effects for which users
+ * can be held accountable. When using
+ * this method, it may be useful to save a copy of the
+ * affected URL in temporary storage.
+ *
+ * <p>If the HTTP DELETE request is incorrectly formatted,
+ * <code>doDelete</code> returns an HTTP "Bad Request"
+ * message.
+ *
+ * @param req the {@link HttpServletRequest} object that
+ * contains the request the client made of
+ * the servlet
+ *
+ * @param resp the {@link HttpServletResponse} object that
+ * contains the response the servlet returns
+ * to the client
+ *
+ * @throws IOException if an input or output error occurs
+ * while the servlet is handling the
+ * DELETE request
+ *
+ * @throws ServletException if the request for the
+ * DELETE cannot be handled
+ */
+ protected void doDelete(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ String protocol = req.getProtocol();
+ String msg = lStrings.getString("http.method_delete_not_supported");
+ if (protocol.endsWith("1.1")) {
+ resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+ }
+ }
+
+
+ private Method[] getAllDeclaredMethods(Class<? extends HttpServlet> c) {
+
+ Class<?> clazz = c;
+ Method[] allMethods = null;
+
+ while (!clazz.equals(HttpServlet.class)) {
+ Method[] thisMethods = clazz.getDeclaredMethods();
+ if (allMethods != null && allMethods.length > 0) {
+ Method[] subClassMethods = allMethods;
+ allMethods =
+ new Method[thisMethods.length + subClassMethods.length];
+ System.arraycopy(thisMethods, 0, allMethods, 0,
+ thisMethods.length);
+ System.arraycopy(subClassMethods, 0, allMethods, thisMethods.length,
+ subClassMethods.length);
+ } else {
+ allMethods = thisMethods;
+ }
+
+ clazz = clazz.getSuperclass();
+ }
+
+ return ((allMethods != null) ? allMethods : new Method[0]);
+ }
+
+
+ /**
+ * Called by the server (via the <code>service</code> method)
+ * to allow a servlet to handle a OPTIONS request.
+ *
+ * The OPTIONS request determines which HTTP methods
+ * the server supports and
+ * returns an appropriate header. For example, if a servlet
+ * overrides <code>doGet</code>, this method returns the
+ * following header:
+ *
+ * <p><code>Allow: GET, HEAD, TRACE, OPTIONS</code>
+ *
+ * <p>There's no need to override this method unless the
+ * servlet implements new HTTP methods, beyond those
+ * implemented by HTTP 1.1.
+ *
+ * @param req the {@link HttpServletRequest} object that
+ * contains the request the client made of
+ * the servlet
+ *
+ * @param resp the {@link HttpServletResponse} object that
+ * contains the response the servlet returns
+ * to the client
+ *
+ * @throws IOException if an input or output error occurs
+ * while the servlet is handling the
+ * OPTIONS request
+ *
+ * @throws ServletException if the request for the
+ * OPTIONS cannot be handled
+ */
+ protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ Method[] methods = getAllDeclaredMethods(this.getClass());
+
+ boolean ALLOW_GET = false;
+ boolean ALLOW_HEAD = false;
+ boolean ALLOW_POST = false;
+ boolean ALLOW_PUT = false;
+ boolean ALLOW_DELETE = false;
+ boolean ALLOW_TRACE = true;
+ boolean ALLOW_OPTIONS = true;
+
+ for (int i=0; i<methods.length; i++) {
+ String methodName = methods[i].getName();
+
+ if (methodName.equals("doGet")) {
+ ALLOW_GET = true;
+ ALLOW_HEAD = true;
+ } else if (methodName.equals("doPost")) {
+ ALLOW_POST = true;
+ } else if (methodName.equals("doPut")) {
+ ALLOW_PUT = true;
+ } else if (methodName.equals("doDelete")) {
+ ALLOW_DELETE = true;
+ }
+
+ }
+
+ // we know "allow" is not null as ALLOW_OPTIONS = true
+ // when this method is invoked
+ StringBuilder allow = new StringBuilder();
+ if (ALLOW_GET) {
+ allow.append(METHOD_GET);
+ }
+ if (ALLOW_HEAD) {
+ if (allow.length() > 0) {
+ allow.append(", ");
+ }
+ allow.append(METHOD_HEAD);
+ }
+ if (ALLOW_POST) {
+ if (allow.length() > 0) {
+ allow.append(", ");
+ }
+ allow.append(METHOD_POST);
+ }
+ if (ALLOW_PUT) {
+ if (allow.length() > 0) {
+ allow.append(", ");
+ }
+ allow.append(METHOD_PUT);
+ }
+ if (ALLOW_DELETE) {
+ if (allow.length() > 0) {
+ allow.append(", ");
+ }
+ allow.append(METHOD_DELETE);
+ }
+ if (ALLOW_TRACE) {
+ if (allow.length() > 0) {
+ allow.append(", ");
+ }
+ allow.append(METHOD_TRACE);
+ }
+ if (ALLOW_OPTIONS) {
+ if (allow.length() > 0) {
+ allow.append(", ");
+ }
+ allow.append(METHOD_OPTIONS);
+ }
+
+ resp.setHeader("Allow", allow.toString());
+ }
+
+
+ /**
+ * Called by the server (via the <code>service</code> method)
+ * to allow a servlet to handle a TRACE request.
+ *
+ * A TRACE returns the headers sent with the TRACE
+ * request to the client, so that they can be used in
+ * debugging. There's no need to override this method.
+ *
+ * @param req the {@link HttpServletRequest} object that
+ * contains the request the client made of
+ * the servlet
+ *
+ *
+ * @param resp the {@link HttpServletResponse} object that
+ * contains the response the servlet returns
+ * to the client
+ *
+ * @throws IOException if an input or output error occurs
+ * while the servlet is handling the
+ * TRACE request
+ *
+ * @throws ServletException if the request for the
+ * TRACE cannot be handled
+ */
+ protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+
+ int responseLength;
+
+ String CRLF = "\r\n";
+ StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI())
+ .append(" ").append(req.getProtocol());
+
+ Enumeration<String> reqHeaderEnum = req.getHeaderNames();
+
+ while( reqHeaderEnum.hasMoreElements() ) {
+ String headerName = reqHeaderEnum.nextElement();
+ buffer.append(CRLF).append(headerName).append(": ")
+ .append(req.getHeader(headerName));
+ }
+
+ buffer.append(CRLF);
+
+ responseLength = buffer.length();
+
+ resp.setContentType("message/http");
+ resp.setContentLength(responseLength);
+ ServletOutputStream out = resp.getOutputStream();
+ out.print(buffer.toString());
+ }
+
+
+ /**
+ * Receives standard HTTP requests from the public
+ * <code>service</code> method and dispatches
+ * them to the <code>do</code><i>XXX</i> methods defined in
+ * this class. This method is an HTTP-specific version of the
+ * {@link javax.servlet.Servlet#service} method. There's no
+ * need to override this method.
+ *
+ * @param req the {@link HttpServletRequest} object that
+ * contains the request the client made of
+ * the servlet
+ *
+ * @param resp the {@link HttpServletResponse} object that
+ * contains the response the servlet returns
+ * to the client
+ *
+ * @throws IOException if an input or output error occurs
+ * while the servlet is handling the
+ * HTTP request
+ *
+ * @throws ServletException if the HTTP request
+ * cannot be handled
+ *
+ * @see javax.servlet.Servlet#service
+ */
+ protected void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ String method = req.getMethod();
+
+ if (method.equals(METHOD_GET)) {
+ long lastModified = getLastModified(req);
+ if (lastModified == -1) {
+ // servlet doesn't support if-modified-since, no reason
+ // to go through further expensive logic
+ doGet(req, resp);
+ } else {
+ long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
+ if (ifModifiedSince < lastModified) {
+ // If the servlet mod time is later, call doGet()
+ // Round down to the nearest second for a proper compare
+ // A ifModifiedSince of -1 will always be less
+ maybeSetLastModified(resp, lastModified);
+ doGet(req, resp);
+ } else {
+ resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ }
+ }
+
+ } else if (method.equals(METHOD_HEAD)) {
+ long lastModified = getLastModified(req);
+ maybeSetLastModified(resp, lastModified);
+ doHead(req, resp);
+
+ } else if (method.equals(METHOD_POST)) {
+ doPost(req, resp);
+
+ } else if (method.equals(METHOD_PUT)) {
+ doPut(req, resp);
+
+ } else if (method.equals(METHOD_DELETE)) {
+ doDelete(req, resp);
+
+ } else if (method.equals(METHOD_OPTIONS)) {
+ doOptions(req,resp);
+
+ } else if (method.equals(METHOD_TRACE)) {
+ doTrace(req,resp);
+
+ } else {
+ //
+ // Note that this means NO servlet supports whatever
+ // method was requested, anywhere on this server.
+ //
+
+ String errMsg = lStrings.getString("http.method_not_implemented");
+ Object[] errArgs = new Object[1];
+ errArgs[0] = method;
+ errMsg = MessageFormat.format(errMsg, errArgs);
+
+ resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
+ }
+ }
+
+
+ /*
+ * Sets the Last-Modified entity header field, if it has not
+ * already been set and if the value is meaningful. Called before
+ * doGet, to ensure that headers are set before response data is
+ * written. A subclass might have set this header already, so we
+ * check.
+ */
+ private void maybeSetLastModified(HttpServletResponse resp,
+ long lastModified) {
+ if (resp.containsHeader(HEADER_LASTMOD))
+ return;
+ if (lastModified >= 0)
+ resp.setDateHeader(HEADER_LASTMOD, lastModified);
+ }
+
+
+ /**
+ * Dispatches client requests to the protected
+ * <code>service</code> method. There's no need to
+ * override this method.
+ *
+ * @param req the {@link HttpServletRequest} object that
+ * contains the request the client made of
+ * the servlet
+ *
+ * @param res the {@link HttpServletResponse} object that
+ * contains the response the servlet returns
+ * to the client
+ *
+ * @throws IOException if an input or output error occurs
+ * while the servlet is handling the
+ * HTTP request
+ *
+ * @throws ServletException if the HTTP request cannot
+ * be handled or if either parameter is not
+ * an instance of its respective {@link HttpServletRequest}
+ * or {@link HttpServletResponse} counterparts.
+ *
+ * @see javax.servlet.Servlet#service
+ */
+ @Override
+ public void service(ServletRequest req, ServletResponse res)
+ throws ServletException, IOException
+ {
+ HttpServletRequest request;
+ HttpServletResponse response;
+
+ if (!(req instanceof HttpServletRequest &&
+ res instanceof HttpServletResponse)) {
+ throw new ServletException("non-HTTP request or response");
+ }
+
+ request = (HttpServletRequest) req;
+ response = (HttpServletResponse) res;
+
+ service(request, response);
+ }
+}
+
+
+/*
+ * A response that includes no body, for use in (dumb) "HEAD" support.
+ * This just swallows that body, counting the bytes in order to set
+ * the content length appropriately. All other methods delegate directly
+ * to the wrapped HTTP Servlet Response object.
+ */
+// file private
+class NoBodyResponse extends HttpServletResponseWrapper {
+
+ private static final ResourceBundle lStrings
+ = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
+
+ private NoBodyOutputStream noBody;
+ private PrintWriter writer;
+ private boolean didSetContentLength;
+ private boolean usingOutputStream;
+
+ // file private
+ NoBodyResponse(HttpServletResponse r) {
+ super(r);
+ noBody = new NoBodyOutputStream();
+ }
+
+ // file private
+ void setContentLength() {
+ if (!didSetContentLength) {
+ if (writer != null) {
+ writer.flush();
+ }
+ setContentLength(noBody.getContentLength());
+ }
+ }
+
+ @Override
+ public void setContentLength(int len) {
+ super.setContentLength(len);
+ didSetContentLength = true;
+ }
+
+ @Override
+ public void setContentLengthLong(long len) {
+ super.setContentLengthLong(len);
+ didSetContentLength = true;
+ }
+
+ @Override
+ public void setHeader(String name, String value) {
+ super.setHeader(name, value);
+ checkHeader(name);
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+ super.addHeader(name, value);
+ checkHeader(name);
+ }
+
+ @Override
+ public void setIntHeader(String name, int value) {
+ super.setIntHeader(name, value);
+ checkHeader(name);
+ }
+
+ @Override
+ public void addIntHeader(String name, int value) {
+ super.addIntHeader(name, value);
+ checkHeader(name);
+ }
+
+ private void checkHeader(String name) {
+ if ("content-length".equalsIgnoreCase(name)) {
+ didSetContentLength = true;
+ }
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+
+ if (writer != null) {
+ throw new IllegalStateException(
+ lStrings.getString("err.ise.getOutputStream"));
+ }
+ usingOutputStream = true;
+
+ return noBody;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws UnsupportedEncodingException {
+
+ if (usingOutputStream) {
+ throw new IllegalStateException(
+ lStrings.getString("err.ise.getWriter"));
+ }
+
+ if (writer == null) {
+ OutputStreamWriter w = new OutputStreamWriter(
+ noBody, getCharacterEncoding());
+ writer = new PrintWriter(w);
+ }
+
+ return writer;
+ }
+}
+
+
+/*
+ * Servlet output stream that gobbles up all its data.
+ */
+// file private
+class NoBodyOutputStream extends ServletOutputStream {
+
+ private static final String LSTRING_FILE =
+ "javax.servlet.http.LocalStrings";
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+ private int contentLength = 0;
+
+ // file private
+ NoBodyOutputStream() {}
+
+ // file private
+ int getContentLength() {
+ return contentLength;
+ }
+
+ @Override
+ public void write(int b) {
+ contentLength++;
+ }
+
+ @Override
+ public void write(byte buf[], int offset, int len)
+ throws IOException
+ {
+ if (buf == null) {
+ throw new NullPointerException(
+ lStrings.getString("err.io.nullArray"));
+ }
+
+ if (offset < 0 || len < 0 || offset+len > buf.length) {
+ String msg = lStrings.getString("err.io.indexOutOfBounds");
+ Object[] msgArgs = new Object[3];
+ msgArgs[0] = Integer.valueOf(offset);
+ msgArgs[1] = Integer.valueOf(len);
+ msgArgs[2] = Integer.valueOf(buf.length);
+ msg = MessageFormat.format(msg, msgArgs);
+ throw new IndexOutOfBoundsException(msg);
+ }
+
+ contentLength += len;
+ }
+
+
+ public boolean isReady() {
+ return false;
+ }
+
+ public void setWriteListener(WriteListener writeListener) {
+
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletMapping.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletMapping.java
new file mode 100644
index 0000000..3e057e2
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletMapping.java
@@ -0,0 +1,174 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+/**
+ * <p>Allows runtime discovery of the manner in which the {@link
+ * HttpServlet} for the current {@link HttpServletRequest} was invoked.
+ * Invoking any of the methods must not block the caller. The
+ * implementation must be thread safe. Instances are immutable and are
+ * returned from {@link HttpServletRequest#getHttpServletMapping}.</p>
+ *
+ * <p>Following are some illustrative examples for various combinations
+ * of mappings. Consider the following Servlet declaration:</p>
+ *
+ * <pre><code>
+ * <servlet>
+ * <servlet-name>MyServlet</servlet-name>
+ * <servlet-class>MyServlet</servlet-class>
+ * </servlet>
+ * <servlet-mapping>
+ * <servlet-name>MyServlet</servlet-name>
+ * <url-pattern>/MyServlet</url-pattern>
+ * <url-pattern>""</url-pattern>
+ * <url-pattern>*.extension</url-pattern>
+ * <url-pattern>/path/*</url-pattern>
+ * </servlet-mapping>
+ * </code></pre>
+ *
+ * <p>The expected values of the properties for various incoming URI
+ * path values are as shown in this table. The {@code servletName}
+ * column is omitted as its value is always {@code MyServlet}.</p>
+ *
+ * <table border="1">
+ * <caption>Expected values of properties for various URI paths</caption>
+ * <tr>
+ * <th>URI Path (in quotes)</th>
+ * <th>matchValue</th>
+ * <th>pattern</th>
+ * <th>mappingMatch</th>
+ * </tr>
+ * <tr>
+ * <td>""</td>
+ * <td>""</td>
+ * <td>""</td>
+ * <td>CONTEXT_ROOT</td>
+ * </tr>
+ * <tr>
+ * <td>"/index.html"</td>
+ * <td>""</td>
+ * <td>/</td>
+ * <td>DEFAULT</td>
+ * </tr>
+ * <tr>
+ * <td>"/MyServlet"</td>
+ * <td>MyServlet</td>
+ * <td>/MyServlet</td>
+ * <td>EXACT</td>
+ * </tr>
+ * <tr>
+ * <td>"/foo.extension"</td>
+ * <td>foo</td>
+ * <td>*.extension</td>
+ * <td>EXTENSION</td>
+ * </tr>
+ * <tr>
+ * <td>"/path/foo"</td>
+ * <td>foo</td>
+ * <td>/path/*</td>
+ * <td>PATH</td>
+ * </tr>
+ *
+ * </table>
+ *
+ * @since 4.0
+ */
+public interface HttpServletMapping {
+
+
+
+ /**
+ * <p>Return the portion of the URI path that caused this request to
+ * be matched. If the {@link getMappingMatch} value is {@code
+ * CONTEXT_ROOT} or {@code DEFAULT}, this method must return the
+ * empty string. If the {@link getMappingMatch} value is {@code
+ * EXACT}, this method must return the portion of the path that
+ * matched the servlet, omitting any leading slash. If the {@link
+ * getMappingMatch} value is {@code EXTENSION} or {@code PATH}, this
+ * method must return the value that matched the '*'. See the class
+ * javadoc for examples. </p>
+ *
+ * @return the match.
+ *
+ * @since 4.0
+ */
+ public String getMatchValue();
+
+ /**
+ * <p>Return the String representation for the {@code url-pattern}
+ * for this mapping. If the {@link getMappingMatch} value is {@code
+ * CONTEXT_ROOT} or {@code DEFAULT}, this method must return the
+ * empty string. If the {@link getMappingMatch} value is {@code
+ * EXTENSION}, this method must return the pattern, without any
+ * leading slash. Otherwise, this method returns the pattern
+ * exactly as specified in the descriptor or Java configuration.</p>
+ *
+ * @return the String representation for the
+ * {@code url-pattern} for this mapping.
+ *
+ * @since 4.0
+ */
+ public String getPattern();
+
+ /**
+ * <p>Return the String representation for the {@code servlet-name}
+ * for this mapping. If the Servlet providing the response is the
+ * default servlet, the return from this method is the name of the
+ * defautl servlet, which is container specific.</p>
+ *
+ * @return the String representation for the {@code servlet-name}
+ * for this mapping.
+ *
+ * @since 4.0
+ */
+ public String getServletName();
+
+ /**
+ * <p>Return the {@link MappingMatch} for this
+ * instance</p>
+ *
+ * @return the {@code MappingMatch} for this instance.
+ *
+ * @since 4.0
+ */
+ public MappingMatch getMappingMatch();
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletRequest.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletRequest.java
new file mode 100644
index 0000000..3f0a0d0
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletRequest.java
@@ -0,0 +1,871 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import java.util.*;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+
+/**
+ *
+ * Extends the {@link javax.servlet.ServletRequest} interface to provide
+ * request information for HTTP servlets.
+ *
+ * <p>The servlet container creates an <code>HttpServletRequest</code>
+ * object and passes it as an argument to the servlet's service
+ * methods (<code>doGet</code>, <code>doPost</code>, etc).
+ *
+ *
+ * @author Various
+ */
+
+public interface HttpServletRequest extends ServletRequest {
+
+ /**
+ * String identifier for Basic authentication. Value "BASIC"
+ */
+ public static final String BASIC_AUTH = "BASIC";
+
+ /**
+ * String identifier for Form authentication. Value "FORM"
+ */
+ public static final String FORM_AUTH = "FORM";
+
+ /**
+ * String identifier for Client Certificate authentication. Value "CLIENT_CERT"
+ */
+ public static final String CLIENT_CERT_AUTH = "CLIENT_CERT";
+
+ /**
+ * String identifier for Digest authentication. Value "DIGEST"
+ */
+ public static final String DIGEST_AUTH = "DIGEST";
+
+ /**
+ * Returns the name of the authentication scheme used to protect
+ * the servlet. All servlet containers support basic, form and client
+ * certificate authentication, and may additionally support digest
+ * authentication.
+ * If the servlet is not authenticated <code>null</code> is returned.
+ *
+ * <p>Same as the value of the CGI variable AUTH_TYPE.
+ *
+ * @return one of the static members BASIC_AUTH,
+ * FORM_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH
+ * (suitable for == comparison) or
+ * the container-specific string indicating
+ * the authentication scheme, or
+ * <code>null</code> if the request was
+ * not authenticated.
+ */
+ public String getAuthType();
+
+ /**
+ * Returns an array containing all of the <code>Cookie</code>
+ * objects the client sent with this request.
+ * This method returns <code>null</code> if no cookies were sent.
+ *
+ * @return an array of all the <code>Cookies</code>
+ * included with this request, or <code>null</code>
+ * if the request has no cookies
+ */
+ public Cookie[] getCookies();
+
+ /**
+ * Returns the value of the specified request header
+ * as a <code>long</code> value that represents a
+ * <code>Date</code> object. Use this method with
+ * headers that contain dates, such as
+ * <code>If-Modified-Since</code>.
+ *
+ * <p>The date is returned as
+ * the number of milliseconds since January 1, 1970 GMT.
+ * The header name is case insensitive.
+ *
+ * <p>If the request did not have a header of the
+ * specified name, this method returns -1. If the header
+ * can't be converted to a date, the method throws
+ * an <code>IllegalArgumentException</code>.
+ *
+ * @param name a <code>String</code> specifying the
+ * name of the header
+ *
+ * @return a <code>long</code> value
+ * representing the date specified
+ * in the header expressed as
+ * the number of milliseconds
+ * since January 1, 1970 GMT,
+ * or -1 if the named header
+ * was not included with the
+ * request
+ *
+ * @exception IllegalArgumentException If the header value
+ * can't be converted
+ * to a date
+ */
+ public long getDateHeader(String name);
+
+ /**
+ * Returns the value of the specified request header
+ * as a <code>String</code>. If the request did not include a header
+ * of the specified name, this method returns <code>null</code>.
+ * If there are multiple headers with the same name, this method
+ * returns the first head in the request.
+ * The header name is case insensitive. You can use
+ * this method with any request header.
+ *
+ * @param name a <code>String</code> specifying the
+ * header name
+ *
+ * @return a <code>String</code> containing the
+ * value of the requested
+ * header, or <code>null</code>
+ * if the request does not
+ * have a header of that name
+ */
+ public String getHeader(String name);
+
+ /**
+ * Returns all the values of the specified request header
+ * as an <code>Enumeration</code> of <code>String</code> objects.
+ *
+ * <p>Some headers, such as <code>Accept-Language</code> can be sent
+ * by clients as several headers each with a different value rather than
+ * sending the header as a comma separated list.
+ *
+ * <p>If the request did not include any headers
+ * of the specified name, this method returns an empty
+ * <code>Enumeration</code>.
+ * The header name is case insensitive. You can use
+ * this method with any request header.
+ *
+ * @param name a <code>String</code> specifying the
+ * header name
+ *
+ * @return an <code>Enumeration</code> containing
+ * the values of the requested header. If
+ * the request does not have any headers of
+ * that name return an empty
+ * enumeration. If
+ * the container does not allow access to
+ * header information, return null
+ */
+ public Enumeration<String> getHeaders(String name);
+
+ /**
+ * Returns an enumeration of all the header names
+ * this request contains. If the request has no
+ * headers, this method returns an empty enumeration.
+ *
+ * <p>Some servlet containers do not allow
+ * servlets to access headers using this method, in
+ * which case this method returns <code>null</code>
+ *
+ * @return an enumeration of all the
+ * header names sent with this
+ * request; if the request has
+ * no headers, an empty enumeration;
+ * if the servlet container does not
+ * allow servlets to use this method,
+ * <code>null</code>
+ */
+ public Enumeration<String> getHeaderNames();
+
+ /**
+ * Returns the value of the specified request header
+ * as an <code>int</code>. If the request does not have a header
+ * of the specified name, this method returns -1. If the
+ * header cannot be converted to an integer, this method
+ * throws a <code>NumberFormatException</code>.
+ *
+ * <p>The header name is case insensitive.
+ *
+ * @param name a <code>String</code> specifying the name
+ * of a request header
+ *
+ * @return an integer expressing the value
+ * of the request header or -1
+ * if the request doesn't have a
+ * header of this name
+ *
+ * @exception NumberFormatException If the header value
+ * can't be converted
+ * to an <code>int</code>
+ */
+ public int getIntHeader(String name);
+
+ /**
+ * <p>Return the {@link HttpServletMapping} by which the {@link
+ * HttpServlet} for this {@code HttpServletRequest} was invoked.
+ * The mappings for any applicable {@link javax.servlet.Filter}s are
+ * not indicated in the result. If the currently active {@link
+ * javax.servlet.Servlet} invocation was obtained by a call to
+ * {@link ServletRequest#getRequestDispatcher} followed by a call to
+ * {@link RequestDispatcher#forward}, the returned {@code
+ * HttpServletMapping} is the one corresponding to the path used to
+ * obtain the {@link RequestDispatcher}. If the currently active
+ * {@code Servlet} invocation was obtained by a call to {@link
+ * ServletRequest#getRequestDispatcher} followed by a call to {@link
+ * RequestDispatcher#include}, the returned {@code
+ * HttpServletMapping} is the one corresponding to the path that
+ * caused the first {@code Servlet} in the invocation sequence to be
+ * invoked. If the currently active {@code Servlet} invocation was
+ * obtained by a call to {@link
+ * javax.servlet.AsyncContext#dispatch}, the returned {@code
+ * HttpServletMapping} is the one corresponding to the path that
+ * caused the first {@code Servlet} in the invocation sequence to be
+ * invoked. See {@link
+ * javax.servlet.RequestDispatcher#FORWARD_MAPPING}, {@link
+ * javax.servlet.RequestDispatcher#INCLUDE_MAPPING} and {@link
+ * javax.servlet.AsyncContext#ASYNC_MAPPING} for additional request
+ * attributes related to {@code HttpServletMapping}. If the
+ * currently active {@code Servlet} invocation was obtained by a
+ * call to {@link javax.servlet.ServletContext#getNamedDispatcher},
+ * the returned {@code HttpServletMapping} is the one corresponding
+ * to the path for the mapping last applied to this request.</p>
+ *
+ * <p>The returned object is immutable. Servlet 4.0 compliant
+ * implementations must override this method.</p>
+ *
+ * @implSpec The default implementation returns a {@code
+ * HttpServletMapping} that returns the empty string for the match
+ * value, pattern and servlet name and {@code null} for the match
+ * type.
+ *
+ * @return An instance of {@code HttpServletMapping} describing the manner in which
+ * the current request was invoked.
+ *
+ * @since 4.0
+ */
+
+ default public HttpServletMapping getHttpServletMapping() {
+ return new HttpServletMapping() {
+ @Override
+ public String getMatchValue() {
+ return "";
+ }
+
+ @Override
+ public String getPattern() {
+ return "";
+ }
+
+ @Override
+ public String getServletName() {
+ return "";
+ }
+
+ @Override
+ public MappingMatch getMappingMatch() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "MappingImpl{" + "matchValue=" + getMatchValue()
+ + ", pattern=" + getPattern() + ", servletName="
+ + getServletName() + ", mappingMatch=" + getMappingMatch()
+ + "} HttpServletRequest {" + HttpServletRequest.this.toString()
+ + '}';
+ }
+
+
+
+ };
+ }
+
+ /**
+ * Returns the name of the HTTP method with which this
+ * request was made, for example, GET, POST, or PUT.
+ * Same as the value of the CGI variable REQUEST_METHOD.
+ *
+ * @return a <code>String</code>
+ * specifying the name
+ * of the method with which
+ * this request was made
+ */
+ public String getMethod();
+
+ /**
+ * Returns any extra path information associated with
+ * the URL the client sent when it made this request.
+ * The extra path information follows the servlet path
+ * but precedes the query string and will start with
+ * a "/" character.
+ *
+ * <p>This method returns <code>null</code> if there
+ * was no extra path information.
+ *
+ * <p>Same as the value of the CGI variable PATH_INFO.
+ *
+ * @return a <code>String</code>, decoded by the
+ * web container, specifying
+ * extra path information that comes
+ * after the servlet path but before
+ * the query string in the request URL;
+ * or <code>null</code> if the URL does not have
+ * any extra path information
+ */
+ public String getPathInfo();
+
+ /**
+ * Returns any extra path information after the servlet name
+ * but before the query string, and translates it to a real
+ * path. Same as the value of the CGI variable PATH_TRANSLATED.
+ *
+ * <p>If the URL does not have any extra path information,
+ * this method returns <code>null</code> or the servlet container
+ * cannot translate the virtual path to a real path for any reason
+ * (such as when the web application is executed from an archive).
+ *
+ * The web container does not decode this string.
+ *
+ * @return a <code>String</code> specifying the
+ * real path, or <code>null</code> if
+ * the URL does not have any extra path
+ * information
+ */
+ public String getPathTranslated();
+
+ /**
+ * Instantiates a new instance of {@link PushBuilder} for issuing server
+ * push responses from the current request. This method returns null
+ * if the current connection does not support server push, or server
+ * push has been disabled by the client via a
+ * {@code SETTINGS_ENABLE_PUSH} settings frame value of {@code 0} (zero).
+ *
+ * @implSpec
+ * The default implementation returns null.
+ *
+ * @return a {@link PushBuilder} for issuing server push responses
+ * from the current request, or null if push is not supported
+ *
+ * @since Servlet 4.0
+ */
+ default public PushBuilder newPushBuilder() {
+ return null;
+ }
+
+ /**
+ * Returns the portion of the request URI that indicates the context
+ * of the request. The context path always comes first in a request
+ * URI. The path starts with a "/" character but does not end with a "/"
+ * character. For servlets in the default (root) context, this method
+ * returns "". The container does not decode this string.
+ *
+ * <p>It is possible that a servlet container may match a context by
+ * more than one context path. In such cases this method will return the
+ * actual context path used by the request and it may differ from the
+ * path returned by the
+ * {@link javax.servlet.ServletContext#getContextPath()} method.
+ * The context path returned by
+ * {@link javax.servlet.ServletContext#getContextPath()}
+ * should be considered as the prime or preferred context path of the
+ * application.
+ *
+ * @return a <code>String</code> specifying the
+ * portion of the request URI that indicates the context
+ * of the request
+ *
+ * @see javax.servlet.ServletContext#getContextPath()
+ */
+ public String getContextPath();
+
+ /**
+ * Returns the query string that is contained in the request
+ * URL after the path. This method returns <code>null</code>
+ * if the URL does not have a query string. Same as the value
+ * of the CGI variable QUERY_STRING.
+ *
+ * @return a <code>String</code> containing the query
+ * string or <code>null</code> if the URL
+ * contains no query string. The value is not
+ * decoded by the container.
+ */
+ public String getQueryString();
+
+ /**
+ * Returns the login of the user making this request, if the
+ * user has been authenticated, or <code>null</code> if the user
+ * has not been authenticated.
+ * Whether the user name is sent with each subsequent request
+ * depends on the browser and type of authentication. Same as the
+ * value of the CGI variable REMOTE_USER.
+ *
+ * @return a <code>String</code> specifying the login
+ * of the user making this request, or <code>null</code>
+ * if the user login is not known
+ */
+ public String getRemoteUser();
+
+ /**
+ * Returns a boolean indicating whether the authenticated user is included
+ * in the specified logical "role". Roles and role membership can be
+ * defined using deployment descriptors. If the user has not been
+ * authenticated, the method returns <code>false</code>.
+ *
+ * <p>The role name "*" should never be used as an argument in calling
+ * <code>isUserInRole</code>. Any call to <code>isUserInRole</code> with
+ * "*" must return false.
+ * If the role-name of the security-role to be tested is "**", and
+ * the application has NOT declared an application security-role with
+ * role-name "**", <code>isUserInRole</code> must only return true if
+ * the user has been authenticated; that is, only when
+ * {@link #getRemoteUser} and {@link #getUserPrincipal} would both return
+ * a non-null value. Otherwise, the container must check
+ * the user for membership in the application role.
+ *
+ * @param role a <code>String</code> specifying the name
+ * of the role
+ *
+ * @return a <code>boolean</code> indicating whether
+ * the user making this request belongs to a given role;
+ * <code>false</code> if the user has not been
+ * authenticated
+ */
+ public boolean isUserInRole(String role);
+
+ /**
+ * Returns a <code>java.security.Principal</code> object containing
+ * the name of the current authenticated user. If the user has not been
+ * authenticated, the method returns <code>null</code>.
+ *
+ * @return a <code>java.security.Principal</code> containing
+ * the name of the user making this request;
+ * <code>null</code> if the user has not been
+ * authenticated
+ */
+ public java.security.Principal getUserPrincipal();
+
+ /**
+ * Returns the session ID specified by the client. This may
+ * not be the same as the ID of the current valid session
+ * for this request.
+ * If the client did not specify a session ID, this method returns
+ * <code>null</code>.
+ *
+ * @return a <code>String</code> specifying the session
+ * ID, or <code>null</code> if the request did
+ * not specify a session ID
+ *
+ * @see #isRequestedSessionIdValid
+ */
+ public String getRequestedSessionId();
+
+ /**
+ * Returns the part of this request's URL from the protocol
+ * name up to the query string in the first line of the HTTP request.
+ * The web container does not decode this String.
+ * For example:
+ *
+ * <table summary="Examples of Returned Values">
+ * <tr align=left><th>First line of HTTP request </th>
+ * <th> Returned Value</th>
+ * <tr><td>POST /some/path.html HTTP/1.1<td><td>/some/path.html
+ * <tr><td>GET http://foo.bar/a.html HTTP/1.0
+ * <td><td>/a.html
+ * <tr><td>HEAD /xyz?a=b HTTP/1.1<td><td>/xyz
+ * </table>
+ *
+ * <p>To reconstruct an URL with a scheme and host, use
+ * {@link HttpUtils#getRequestURL}.
+ *
+ * @return a <code>String</code> containing
+ * the part of the URL from the
+ * protocol name up to the query string
+ *
+ * @see HttpUtils#getRequestURL
+ */
+ public String getRequestURI();
+
+ /**
+ * Reconstructs the URL the client used to make the request.
+ * The returned URL contains a protocol, server name, port
+ * number, and server path, but it does not include query
+ * string parameters.
+ *
+ * <p>If this request has been forwarded using
+ * {@link javax.servlet.RequestDispatcher#forward}, the server path in the
+ * reconstructed URL must reflect the path used to obtain the
+ * RequestDispatcher, and not the server path specified by the client.
+ *
+ * <p>Because this method returns a <code>StringBuffer</code>,
+ * not a string, you can modify the URL easily, for example,
+ * to append query parameters.
+ *
+ * <p>This method is useful for creating redirect messages
+ * and for reporting errors.
+ *
+ * @return a <code>StringBuffer</code> object containing
+ * the reconstructed URL
+ */
+ public StringBuffer getRequestURL();
+
+ /**
+ * Returns the part of this request's URL that calls
+ * the servlet. This path starts with a "/" character
+ * and includes either the servlet name or a path to
+ * the servlet, but does not include any extra path
+ * information or a query string. Same as the value of
+ * the CGI variable SCRIPT_NAME.
+ *
+ * <p>This method will return an empty string ("") if the
+ * servlet used to process this request was matched using
+ * the "/*" pattern.
+ *
+ * @return a <code>String</code> containing
+ * the name or path of the servlet being
+ * called, as specified in the request URL,
+ * decoded, or an empty string if the servlet
+ * used to process the request is matched
+ * using the "/*" pattern.
+ */
+ public String getServletPath();
+
+ /**
+ * Returns the current <code>HttpSession</code>
+ * associated with this request or, if there is no
+ * current session and <code>create</code> is true, returns
+ * a new session.
+ *
+ * <p>If <code>create</code> is <code>false</code>
+ * and the request has no valid <code>HttpSession</code>,
+ * this method returns <code>null</code>.
+ *
+ * <p>To make sure the session is properly maintained,
+ * you must call this method before
+ * the response is committed. If the container is using cookies
+ * to maintain session integrity and is asked to create a new session
+ * when the response is committed, an IllegalStateException is thrown.
+ *
+ * @param create <code>true</code> to create
+ * a new session for this request if necessary;
+ * <code>false</code> to return <code>null</code>
+ * if there's no current session
+ *
+ * @return the <code>HttpSession</code> associated
+ * with this request or <code>null</code> if
+ * <code>create</code> is <code>false</code>
+ * and the request has no valid session
+ *
+ * @see #getSession()
+ */
+ public HttpSession getSession(boolean create);
+
+ /**
+ * Returns the current session associated with this request,
+ * or if the request does not have a session, creates one.
+ *
+ * @return the <code>HttpSession</code> associated
+ * with this request
+ *
+ * @see #getSession(boolean)
+ */
+ public HttpSession getSession();
+
+ /**
+ * Change the session id of the current session associated with this
+ * request and return the new session id.
+ *
+ * @return the new session id
+ *
+ * @throws IllegalStateException if there is no session associated
+ * with the request
+ *
+ * @since Servlet 3.1
+ */
+ public String changeSessionId();
+
+ /**
+ * Checks whether the requested session ID is still valid.
+ *
+ * <p>If the client did not specify any session ID, this method returns
+ * <code>false</code>.
+ *
+ * @return <code>true</code> if this
+ * request has an id for a valid session
+ * in the current session context;
+ * <code>false</code> otherwise
+ *
+ * @see #getRequestedSessionId
+ * @see #getSession
+ * @see HttpSessionContext
+ */
+ public boolean isRequestedSessionIdValid();
+
+ /**
+ * <p>Checks whether the requested session ID was conveyed to the
+ * server as an HTTP cookie.</p>
+ *
+ * @return <code>true</code> if the session ID
+ * was conveyed to the server an an HTTP
+ * cookie; otherwise, <code>false</code>
+ *
+ * @see #getSession
+ */
+ public boolean isRequestedSessionIdFromCookie();
+
+ /**
+ * <p>Checks whether the requested session ID was conveyed to the
+ * server as part of the request URL.</p>
+ *
+ * @return <code>true</code> if the session ID was conveyed to the
+ * server as part of a URL; otherwise,
+ * <code>false</code>
+ *
+ * @see #getSession
+ */
+ public boolean isRequestedSessionIdFromURL();
+
+ /**
+ * @deprecated As of Version 2.1 of the Java Servlet
+ * API, use {@link #isRequestedSessionIdFromURL}
+ * instead.
+ *
+ * @return <code>true</code> if the session ID was conveyed to the
+ * server as part of a URL; otherwise,
+ * <code>false</code>
+ */
+ @Deprecated
+ public boolean isRequestedSessionIdFromUrl();
+
+ /**
+ * Use the container login mechanism configured for the
+ * <code>ServletContext</code> to authenticate the user making
+ * this request.
+ *
+ * <p>This method may modify and commit the argument
+ * <code>HttpServletResponse</code>.
+ *
+ * @param response The <code>HttpServletResponse</code>
+ * associated with this <code>HttpServletRequest</code>
+ *
+ * @return <code>true</code> when non-null values were or have been
+ * established as the values returned by <code>getUserPrincipal</code>,
+ * <code>getRemoteUser</code>, and <code>getAuthType</code>. Return
+ * <code>false</code> if authentication is incomplete and the underlying
+ * login mechanism has committed, in the response, the message (e.g.,
+ * challenge) and HTTP status code to be returned to the user.
+ *
+ * @throws IOException if an input or output error occurred while
+ * reading from this request or writing to the given response
+ *
+ * @throws IllegalStateException if the login mechanism attempted to
+ * modify the response and it was already committed
+ *
+ * @throws ServletException if the authentication failed and
+ * the caller is responsible for handling the error (i.e., the
+ * underlying login mechanism did NOT establish the message and
+ * HTTP status code to be returned to the user)
+ *
+ * @since Servlet 3.0
+ */
+ public boolean authenticate(HttpServletResponse response)
+ throws IOException,ServletException;
+
+ /**
+ * Validate the provided username and password in the password validation
+ * realm used by the web container login mechanism configured for the
+ * <code>ServletContext</code>.
+ *
+ * <p>This method returns without throwing a <code>ServletException</code>
+ * when the login mechanism configured for the <code>ServletContext</code>
+ * supports username password validation, and when, at the time of the
+ * call to login, the identity of the caller of the request had
+ * not been established (i.e, all of <code>getUserPrincipal</code>,
+ * <code>getRemoteUser</code>, and <code>getAuthType</code> return null),
+ * and when validation of the provided credentials is successful.
+ * Otherwise, this method throws a <code>ServletException</code> as
+ * described below.
+ *
+ * <p>When this method returns without throwing an exception, it must
+ * have established non-null values as the values returned by
+ * <code>getUserPrincipal</code>, <code>getRemoteUser</code>, and
+ * <code>getAuthType</code>.
+ *
+ * @param username The <code>String</code> value corresponding to
+ * the login identifier of the user.
+ *
+ * @param password The password <code>String</code> corresponding
+ * to the identified user.
+ *
+ * @exception ServletException if the configured login mechanism
+ * does not support username
+ * password authentication, or if a
+ * non-null caller identity had
+ * already been established (prior
+ * to the call to login), or if
+ * validation of the provided
+ * username and password fails.
+ *
+ * @since Servlet 3.0
+ */
+ public void login(String username, String password)
+ throws ServletException;
+
+ /**
+ * Establish <code>null</code> as the value returned when
+ * <code>getUserPrincipal</code>, <code>getRemoteUser</code>,
+ * and <code>getAuthType</code> is called on the request.
+ *
+ * @exception ServletException if logout fails
+ *
+ * @since Servlet 3.0
+ */
+ public void logout() throws ServletException;
+
+ /**
+ * Gets all the {@link Part} components of this request, provided
+ * that it is of type <code>multipart/form-data</code>.
+ *
+ * <p>If this request is of type <code>multipart/form-data</code>, but
+ * does not contain any <code>Part</code> components, the returned
+ * <code>Collection</code> will be empty.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>HttpServletRequest</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the
+ * <code>Part</code> components of this request
+ *
+ * @throws IOException if an I/O error occurred during the retrieval
+ * of the {@link Part} components of this request
+ *
+ * @throws ServletException if this request is not of type
+ * <code>multipart/form-data</code>
+ *
+ * @throws IllegalStateException if the request body is larger than
+ * <code>maxRequestSize</code>, or any <code>Part</code> in the
+ * request is larger than <code>maxFileSize</code>, or there is no
+ * <code>@MultipartConfig</code> or <code>multipart-config</code> in
+ * deployment descriptors
+ *
+ * @see javax.servlet.annotation.MultipartConfig#maxFileSize
+ * @see javax.servlet.annotation.MultipartConfig#maxRequestSize
+ *
+ * @since Servlet 3.0
+ */
+ public Collection<Part> getParts() throws IOException, ServletException;
+
+ /**
+ * Gets the {@link Part} with the given name.
+ *
+ * @param name the name of the requested <code>Part</code>
+ *
+ * @return The <code>Part</code> with the given name, or
+ * <code>null</code> if this request is of type
+ * <code>multipart/form-data</code>, but does not
+ * contain the requested <code>Part</code>
+ *
+ * @throws IOException if an I/O error occurred during the retrieval
+ * of the requested <code>Part</code>
+ * @throws ServletException if this request is not of type
+ * <code>multipart/form-data</code>
+ * @throws IllegalStateException if the request body is larger than
+ * <code>maxRequestSize</code>, or any <code>Part</code> in the
+ * request is larger than <code>maxFileSize</code>, or there is no
+ * <code>@MultipartConfig</code> or <code>multipart-config</code> in
+ * deployment descriptors
+ *
+ * @see javax.servlet.annotation.MultipartConfig#maxFileSize
+ * @see javax.servlet.annotation.MultipartConfig#maxRequestSize
+ *
+ * @since Servlet 3.0
+ */
+ public Part getPart(String name) throws IOException, ServletException;
+
+ /**
+ * Creates an instance of <code>HttpUpgradeHandler</code> for a given
+ * class and uses it for the http protocol upgrade processing.
+ *
+ * @param <T> The {@code Class}, which extends {@link
+ * HttpUpgradeHandler}, of the {@code handlerClass}.
+
+ * @param handlerClass The <code>HttpUpgradeHandler</code> class used for the upgrade.
+ *
+ * @return an instance of the <code>HttpUpgradeHandler</code>
+ *
+ * @exception IOException if an I/O error occurred during the upgrade
+ * @exception ServletException if the given <code>handlerClass</code> fails to
+ * be instantiated
+ *
+ * @see javax.servlet.http.HttpUpgradeHandler
+ * @see javax.servlet.http.WebConnection
+ *
+ * @since Servlet 3.1
+ */
+ public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass)
+ throws IOException, ServletException;
+
+ /**
+ * Get the request trailer fields.
+ *
+ * <p>The returned map is not backed by the {@code HttpServletRequest} object,
+ * so changes in the returned map are not reflected in the
+ * {@code HttpServletRequest} object, and vice-versa.</p>
+ *
+ * <p>{@link #isTrailerFieldsReady()} should be called first to determine
+ * if it is safe to call this method without causing an exception.</p>
+ *
+ * @implSpec
+ * The default implementation returns an empty map.
+ *
+ * @return A map of trailer fields in which all the keys are in lowercase,
+ * regardless of the case they had at the protocol level. If there are no
+ * trailer fields, yet {@link #isTrailerFieldsReady} is returning true,
+ * the empty map is returned.
+ *
+ * @throws IllegalStateException if {@link #isTrailerFieldsReady()} is false
+ *
+ * @since Servlet 4.0
+ */
+ default public Map<String, String> getTrailerFields() {
+ return Collections.emptyMap();
+ }
+
+ /**
+ * Return a boolean indicating whether trailer fields are ready to read
+ * using {@link #getTrailerFields}.
+ *
+ * This methods returns true immediately if it is known that there is no
+ * trailer in the request, for instance, the underlying protocol (such
+ * as HTTP 1.0) does not supports the trailer fields, or the request is
+ * not in chunked encoding in HTTP 1.1.
+ * And the method also returns true if both of the following conditions
+ * are satisfied:
+ * <ol type="a">
+ * <li> the application has read all the request data and an EOF
+ * indication has been returned from the {@link #getReader}
+ * or {@link #getInputStream}.
+ * <li> all the trailer fields sent by the client have been received.
+ * Note that it is possible that the client has sent no trailer fields.
+ * </ol>
+ *
+ * @implSpec
+ * The default implementation returns false.
+ *
+ * @return a boolean whether trailer fields are ready to read
+ *
+ * @since Servlet 4.0
+ */
+ default public boolean isTrailerFieldsReady() {
+ return true;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletRequestWrapper.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletRequestWrapper.java
new file mode 100644
index 0000000..cb2393e
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletRequestWrapper.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import java.util.*;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequestWrapper;
+
+/**
+ * Provides a convenient implementation of the HttpServletRequest interface
+ * that can be subclassed by developers wishing to adapt the request to a
+ * Servlet.
+ *
+ * <p>This class implements the Wrapper or Decorator pattern. Methods default
+ * to calling through to the wrapped request object.
+ *
+ * @see javax.servlet.http.HttpServletRequest
+ * @since Servlet 2.3
+ */
+
+
+public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest {
+
+ /**
+ * Constructs a request object wrapping the given request.
+ * @throws java.lang.IllegalArgumentException if the request is null
+
+ * @param request the {@link HttpServletRequest} to be wrapped.
+ */
+ public HttpServletRequestWrapper(HttpServletRequest request) {
+ super(request);
+ }
+
+ private HttpServletRequest _getHttpServletRequest() {
+ return (HttpServletRequest) super.getRequest();
+ }
+
+ /**
+ * The default behavior of this method is to return getAuthType()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getAuthType() {
+ return this._getHttpServletRequest().getAuthType();
+ }
+
+ /**
+ * The default behavior of this method is to return getCookies()
+ * on the wrapped request object.
+ */
+ @Override
+ public Cookie[] getCookies() {
+ return this._getHttpServletRequest().getCookies();
+ }
+
+ /**
+ * The default behavior of this method is to return getDateHeader(String name)
+ * on the wrapped request object.
+ */
+ @Override
+ public long getDateHeader(String name) {
+ return this._getHttpServletRequest().getDateHeader(name);
+ }
+
+ /**
+ * The default behavior of this method is to return getHeader(String name)
+ * on the wrapped request object.
+ */
+ @Override
+ public String getHeader(String name) {
+ return this._getHttpServletRequest().getHeader(name);
+ }
+
+ /**
+ * The default behavior of this method is to return getHeaders(String name)
+ * on the wrapped request object.
+ */
+ @Override
+ public Enumeration<String> getHeaders(String name) {
+ return this._getHttpServletRequest().getHeaders(name);
+ }
+
+ /**
+ * The default behavior of this method is to return getHeaderNames()
+ * on the wrapped request object.
+ */
+ @Override
+ public Enumeration<String> getHeaderNames() {
+ return this._getHttpServletRequest().getHeaderNames();
+ }
+
+ /**
+ * The default behavior of this method is to return
+ * getIntHeader(String name) on the wrapped request object.
+ */
+ @Override
+ public int getIntHeader(String name) {
+ return this._getHttpServletRequest().getIntHeader(name);
+ }
+
+ /**
+ * <p>The default behavior of this method is to
+ * return getServletMapping() on the wrapped request object.</p>
+ */
+ @Override
+ public HttpServletMapping getHttpServletMapping() {
+ return this._getHttpServletRequest().getHttpServletMapping();
+ }
+
+ /**
+ * The default behavior of this method is to return getMethod()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getMethod() {
+ return this._getHttpServletRequest().getMethod();
+ }
+
+ /**
+ * The default behavior of this method is to return getPathInfo()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getPathInfo() {
+ return this._getHttpServletRequest().getPathInfo();
+ }
+
+ /**
+ * The default behavior of this method is to return getPathTranslated()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getPathTranslated() {
+ return this._getHttpServletRequest().getPathTranslated();
+ }
+
+ /**
+ * The default behavior of this method is to return getContextPath()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getContextPath() {
+ return this._getHttpServletRequest().getContextPath();
+ }
+
+ /**
+ * The default behavior of this method is to return getQueryString()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getQueryString() {
+ return this._getHttpServletRequest().getQueryString();
+ }
+
+ /**
+ * The default behavior of this method is to return getRemoteUser()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getRemoteUser() {
+ return this._getHttpServletRequest().getRemoteUser();
+ }
+
+ /**
+ * The default behavior of this method is to return isUserInRole(String role)
+ * on the wrapped request object.
+ */
+ @Override
+ public boolean isUserInRole(String role) {
+ return this._getHttpServletRequest().isUserInRole(role);
+ }
+
+ /**
+ * The default behavior of this method is to return getUserPrincipal()
+ * on the wrapped request object.
+ */
+ @Override
+ public java.security.Principal getUserPrincipal() {
+ return this._getHttpServletRequest().getUserPrincipal();
+ }
+
+ /**
+ * The default behavior of this method is to return getRequestedSessionId()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getRequestedSessionId() {
+ return this._getHttpServletRequest().getRequestedSessionId();
+ }
+
+ /**
+ * The default behavior of this method is to return getRequestURI()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getRequestURI() {
+ return this._getHttpServletRequest().getRequestURI();
+ }
+
+ /**
+ * The default behavior of this method is to return getRequestURL()
+ * on the wrapped request object.
+ */
+ @Override
+ public StringBuffer getRequestURL() {
+ return this._getHttpServletRequest().getRequestURL();
+ }
+
+ /**
+ * The default behavior of this method is to return getServletPath()
+ * on the wrapped request object.
+ */
+ @Override
+ public String getServletPath() {
+ return this._getHttpServletRequest().getServletPath();
+ }
+
+ /**
+ * The default behavior of this method is to return getSession(boolean create)
+ * on the wrapped request object.
+ */
+ @Override
+ public HttpSession getSession(boolean create) {
+ return this._getHttpServletRequest().getSession(create);
+ }
+
+ /**
+ * The default behavior of this method is to return getSession()
+ * on the wrapped request object.
+ */
+ @Override
+ public HttpSession getSession() {
+ return this._getHttpServletRequest().getSession();
+ }
+
+ /**
+ * The default behavior of this method is to return changeSessionId()
+ * on the wrapped request object.
+ *
+ * @since Servlet 3.1
+ */
+ @Override
+ public String changeSessionId() {
+ return this._getHttpServletRequest().changeSessionId();
+ }
+
+ /**
+ * The default behavior of this method is to return isRequestedSessionIdValid()
+ * on the wrapped request object.
+ */
+ @Override
+ public boolean isRequestedSessionIdValid() {
+ return this._getHttpServletRequest().isRequestedSessionIdValid();
+ }
+
+ /**
+ * The default behavior of this method is to return isRequestedSessionIdFromCookie()
+ * on the wrapped request object.
+ */
+ @Override
+ public boolean isRequestedSessionIdFromCookie() {
+ return this._getHttpServletRequest().isRequestedSessionIdFromCookie();
+ }
+
+ /**
+ * The default behavior of this method is to return isRequestedSessionIdFromURL()
+ * on the wrapped request object.
+ */
+ @Override
+ public boolean isRequestedSessionIdFromURL() {
+ return this._getHttpServletRequest().isRequestedSessionIdFromURL();
+ }
+
+ /**
+ * The default behavior of this method is to return isRequestedSessionIdFromUrl()
+ * on the wrapped request object.
+ *
+ * @deprecated As of Version 4.0 of the Java Servlet API,
+ * use {@link #isRequestedSessionIdFromURL} instead.
+ */
+ @Deprecated
+ @Override
+ public boolean isRequestedSessionIdFromUrl() {
+ return this._getHttpServletRequest().isRequestedSessionIdFromUrl();
+ }
+
+ /**
+ * The default behavior of this method is to call authenticate on the
+ * wrapped request object.
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public boolean authenticate(HttpServletResponse response)
+ throws IOException, ServletException {
+ return this._getHttpServletRequest().authenticate(response);
+ }
+
+ /**
+ * The default behavior of this method is to call login on the wrapped
+ * request object.
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public void login(String username, String password)
+ throws ServletException {
+ this._getHttpServletRequest().login(username,password);
+ }
+
+ /**
+ * The default behavior of this method is to call login on the wrapped
+ * request object.
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public void logout() throws ServletException {
+ this._getHttpServletRequest().logout();
+ }
+
+ /**
+ * The default behavior of this method is to call getParts on the wrapped
+ * request object.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>HttpServletRequestWrapper</code>.
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public Collection<Part> getParts() throws IOException, ServletException {
+ return this._getHttpServletRequest().getParts();
+ }
+
+ /**
+ * The default behavior of this method is to call getPart on the wrapped
+ * request object.
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public Part getPart(String name) throws IOException, ServletException {
+ return this._getHttpServletRequest().getPart(name);
+
+ }
+
+ /**
+ * Create an instance of <code>HttpUpgradeHandler</code> for a given
+ * class and uses it for the http protocol upgrade processing.
+ *
+ * @since Servlet 3.1
+ */
+ @Override
+ public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass)
+ throws IOException, ServletException {
+ return this._getHttpServletRequest().upgrade(handlerClass);
+ }
+
+ /**
+ * The default behavior of this method is to call newPushBuilder on the
+ * wrapped request object.
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public PushBuilder newPushBuilder() {
+ return this._getHttpServletRequest().newPushBuilder();
+ }
+
+ /**
+ * The default behavior of this method is to call getTrailerFields on the
+ * wrapped request object.
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public Map<String, String> getTrailerFields() {
+ return this._getHttpServletRequest().getTrailerFields();
+ }
+
+ /**
+ * The default behavior of this method is to call isTrailerFieldsReady on the
+ * wrapped request object.
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public boolean isTrailerFieldsReady() {
+ return this._getHttpServletRequest().isTrailerFieldsReady();
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletResponse.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletResponse.java
new file mode 100644
index 0000000..08888ac
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletResponse.java
@@ -0,0 +1,738 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Supplier;
+import javax.servlet.ServletResponse;
+
+/**
+ *
+ * Extends the {@link ServletResponse} interface to provide HTTP-specific
+ * functionality in sending a response. For example, it has methods
+ * to access HTTP headers and cookies.
+ *
+ * <p>The servlet container creates an <code>HttpServletResponse</code> object
+ * and passes it as an argument to the servlet's service methods
+ * (<code>doGet</code>, <code>doPost</code>, etc).
+ *
+ *
+ * @author Various
+ *
+ * @see javax.servlet.ServletResponse
+ *
+ */
+public interface HttpServletResponse extends ServletResponse {
+
+ /**
+ * Adds the specified cookie to the response. This method can be called
+ * multiple times to set more than one cookie.
+ *
+ * @param cookie the Cookie to return to the client
+ *
+ */
+ public void addCookie(Cookie cookie);
+
+ /**
+ * Returns a boolean indicating whether the named response header
+ * has already been set.
+ *
+ * @param name the header name
+ * @return <code>true</code> if the named response header
+ * has already been set;
+ * <code>false</code> otherwise
+ */
+ public boolean containsHeader(String name);
+
+ /**
+ * Encodes the specified URL by including the session ID,
+ * or, if encoding is not needed, returns the URL unchanged.
+ * The implementation of this method includes the logic to
+ * determine whether the session ID needs to be encoded in the URL.
+ * For example, if the browser supports cookies, or session
+ * tracking is turned off, URL encoding is unnecessary.
+ *
+ * <p>For robust session tracking, all URLs emitted by a servlet
+ * should be run through this
+ * method. Otherwise, URL rewriting cannot be used with browsers
+ * which do not support cookies.
+ *
+ * <p>If the URL is relative, it is always relative to the current
+ * HttpServletRequest.
+ *
+ * @param url the url to be encoded.
+ * @return the encoded URL if encoding is needed;
+ * the unchanged URL otherwise.
+ * @exception IllegalArgumentException if the url is not valid
+ */
+ public String encodeURL(String url);
+
+ /**
+ * Encodes the specified URL for use in the
+ * <code>sendRedirect</code> method or, if encoding is not needed,
+ * returns the URL unchanged. The implementation of this method
+ * includes the logic to determine whether the session ID
+ * needs to be encoded in the URL. For example, if the browser supports
+ * cookies, or session tracking is turned off, URL encoding is
+ * unnecessary. Because the rules for making this determination can
+ * differ from those used to decide whether to
+ * encode a normal link, this method is separated from the
+ * <code>encodeURL</code> method.
+ *
+ * <p>All URLs sent to the <code>HttpServletResponse.sendRedirect</code>
+ * method should be run through this method. Otherwise, URL
+ * rewriting cannot be used with browsers which do not support
+ * cookies.
+ *
+ * <p>If the URL is relative, it is always relative to the current
+ * HttpServletRequest.
+ *
+ * @param url the url to be encoded.
+ * @return the encoded URL if encoding is needed;
+ * the unchanged URL otherwise.
+ * @exception IllegalArgumentException if the url is not valid
+ *
+ * @see #sendRedirect
+ * @see #encodeUrl
+ */
+ public String encodeRedirectURL(String url);
+
+ /**
+ * @deprecated As of version 2.1, use encodeURL(String url) instead
+ *
+ * @param url the url to be encoded.
+ * @return the encoded URL if encoding is needed;
+ * the unchanged URL otherwise.
+ * @exception IllegalArgumentException if the url is not valid
+ */
+ @Deprecated
+ public String encodeUrl(String url);
+
+ /**
+ * @deprecated As of version 2.1, use
+ * encodeRedirectURL(String url) instead
+ *
+ * @param url the url to be encoded.
+ * @return the encoded URL if encoding is needed;
+ * the unchanged URL otherwise.
+ * @exception IllegalArgumentException if the url is not valid
+ */
+ @Deprecated
+ public String encodeRedirectUrl(String url);
+
+ /**
+ * <p>Sends an error response to the client using the specified
+ * status and clears the buffer. The server defaults to creating
+ * the response to look like an HTML-formatted server error page
+ * containing the specified message, setting the content type to
+ * "text/html". The caller is <strong>not</strong> responsible for
+ * escaping or re-encoding the message to ensure it is safe with
+ * respect to the current response encoding and content type. This
+ * aspect of safety is the responsibility of the container, as it is
+ * generating the error page containing the message. The server
+ * will preserve cookies and may clear or update any headers needed
+ * to serve the error page as a valid response.</p>
+ *
+ * <p>If an error-page declaration has been made for the web
+ * application corresponding to the status code passed in, it will
+ * be served back in preference to the suggested msg parameter and
+ * the msg parameter will be ignored.</p>
+ *
+ * <p>If the response has already been committed, this method throws
+ * an IllegalStateException.
+ * After using this method, the response should be considered
+ * to be committed and should not be written to.
+ *
+ * @param sc the error status code
+ * @param msg the descriptive message
+ * @exception IOException If an input or output exception occurs
+ * @exception IllegalStateException If the response was committed
+ */
+ public void sendError(int sc, String msg) throws IOException;
+
+ /**
+ * Sends an error response to the client using the specified status
+ * code and clears the buffer.
+ *
+ * The server will preserve cookies and may clear or
+ * update any headers needed to serve the error page as a valid response.
+ *
+ * If an error-page declaration has been made for the web application
+ * corresponding to the status code passed in, it will be served back
+ * the error page
+ *
+ * <p>If the response has already been committed, this method throws
+ * an IllegalStateException.
+ * After using this method, the response should be considered
+ * to be committed and should not be written to.
+ *
+ * @param sc the error status code
+ * @exception IOException If an input or output exception occurs
+ * @exception IllegalStateException If the response was committed
+ * before this method call
+ */
+ public void sendError(int sc) throws IOException;
+
+ /**
+ * Sends a temporary redirect response to the client using the
+ * specified redirect location URL and clears the buffer. The buffer will
+ * be replaced with the data set by this method. Calling this method sets the
+ * status code to {@link #SC_FOUND} 302 (Found).
+ * This method can accept relative URLs;the servlet container must convert
+ * the relative URL to an absolute URL
+ * before sending the response to the client. If the location is relative
+ * without a leading '/' the container interprets it as relative to
+ * the current request URI. If the location is relative with a leading
+ * '/' the container interprets it as relative to the servlet container root.
+ * If the location is relative with two leading '/' the container interprets
+ * it as a network-path reference (see
+ * <a href="http://www.ietf.org/rfc/rfc3986.txt">
+ * RFC 3986: Uniform Resource Identifier (URI): Generic Syntax</a>, section 4.2
+ * "Relative Reference").
+ *
+ * <p>If the response has already been committed, this method throws
+ * an IllegalStateException.
+ * After using this method, the response should be considered
+ * to be committed and should not be written to.
+ *
+ * @param location the redirect location URL
+ * @exception IOException If an input or output exception occurs
+ * @exception IllegalStateException If the response was committed or
+ * if a partial URL is given and cannot be converted into a valid URL
+ */
+ public void sendRedirect(String location) throws IOException;
+
+ /**
+ *
+ * Sets a response header with the given name and
+ * date-value. The date is specified in terms of
+ * milliseconds since the epoch. If the header had already
+ * been set, the new value overwrites the previous one. The
+ * <code>containsHeader</code> method can be used to test for the
+ * presence of a header before setting its value.
+ *
+ * @param name the name of the header to set
+ * @param date the assigned date value
+ *
+ * @see #containsHeader
+ * @see #addDateHeader
+ */
+ public void setDateHeader(String name, long date);
+
+ /**
+ *
+ * Adds a response header with the given name and
+ * date-value. The date is specified in terms of
+ * milliseconds since the epoch. This method allows response headers
+ * to have multiple values.
+ *
+ * @param name the name of the header to set
+ * @param date the additional date value
+ *
+ * @see #setDateHeader
+ */
+ public void addDateHeader(String name, long date);
+
+ /**
+ *
+ * Sets a response header with the given name and value.
+ * If the header had already been set, the new value overwrites the
+ * previous one. The <code>containsHeader</code> method can be
+ * used to test for the presence of a header before setting its
+ * value.
+ *
+ * @param name the name of the header
+ * @param value the header value If it contains octet string,
+ * it should be encoded according to RFC 2047
+ * (http://www.ietf.org/rfc/rfc2047.txt)
+ *
+ * @see #containsHeader
+ * @see #addHeader
+ */
+ public void setHeader(String name, String value);
+
+ /**
+ * Adds a response header with the given name and value.
+ * This method allows response headers to have multiple values.
+ *
+ * @param name the name of the header
+ * @param value the additional header value If it contains
+ * octet string, it should be encoded
+ * according to RFC 2047
+ * (http://www.ietf.org/rfc/rfc2047.txt)
+ *
+ * @see #setHeader
+ */
+ public void addHeader(String name, String value);
+
+ /**
+ * Sets a response header with the given name and
+ * integer value. If the header had already been set, the new value
+ * overwrites the previous one. The <code>containsHeader</code>
+ * method can be used to test for the presence of a header before
+ * setting its value.
+ *
+ * @param name the name of the header
+ * @param value the assigned integer value
+ *
+ * @see #containsHeader
+ * @see #addIntHeader
+ */
+ public void setIntHeader(String name, int value);
+
+ /**
+ * Adds a response header with the given name and
+ * integer value. This method allows response headers to have multiple
+ * values.
+ *
+ * @param name the name of the header
+ * @param value the assigned integer value
+ *
+ * @see #setIntHeader
+ */
+ public void addIntHeader(String name, int value);
+
+ /**
+ * Sets the status code for this response.
+ *
+ * <p>This method is used to set the return status code when there is
+ * no error (for example, for the SC_OK or SC_MOVED_TEMPORARILY status
+ * codes).
+ *
+ * <p>If this method is used to set an error code, then the container's
+ * error page mechanism will not be triggered. If there is an error and
+ * the caller wishes to invoke an error page defined in the web
+ * application, then {@link #sendError} must be used instead.
+ *
+ * <p>This method preserves any cookies and other response headers.
+ *
+ * <p>Valid status codes are those in the 2XX, 3XX, 4XX, and 5XX ranges.
+ * Other status codes are treated as container specific.
+ *
+ * @param sc the status code
+ *
+ * @see #sendError
+ */
+ public void setStatus(int sc);
+
+
+ /**
+ * @deprecated As of version 2.1, due to ambiguous meaning of the
+ * message parameter. To set a status code
+ * use <code>setStatus(int)</code>, to send an error with a description
+ * use <code>sendError(int, String)</code>.
+ *
+ * Sets the status code and message for this response.
+ *
+ * @param sc the status code
+ * @param sm the status message
+ */
+ @Deprecated
+ public void setStatus(int sc, String sm);
+
+ /**
+ * Gets the current status code of this response.
+ *
+ * @return the current status code of this response
+ *
+ * @since Servlet 3.0
+ */
+ public int getStatus();
+
+ /**
+ * Gets the value of the response header with the given name.
+ *
+ * <p>If a response header with the given name exists and contains
+ * multiple values, the value that was added first will be returned.
+ *
+ * <p>This method considers only response headers set or added via
+ * {@link #setHeader}, {@link #addHeader}, {@link #setDateHeader},
+ * {@link #addDateHeader}, {@link #setIntHeader}, or
+ * {@link #addIntHeader}, respectively.
+ *
+ * @param name the name of the response header whose value to return
+ *
+ * @return the value of the response header with the given name,
+ * or <tt>null</tt> if no header with the given name has been set
+ * on this response
+ *
+ * @since Servlet 3.0
+ */
+ public String getHeader(String name);
+
+ /**
+ * Gets the values of the response header with the given name.
+ *
+ * <p>This method considers only response headers set or added via
+ * {@link #setHeader}, {@link #addHeader}, {@link #setDateHeader},
+ * {@link #addDateHeader}, {@link #setIntHeader}, or
+ * {@link #addIntHeader}, respectively.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>HttpServletResponse</code>.
+ *
+ * @param name the name of the response header whose values to return
+ *
+ * @return a (possibly empty) <code>Collection</code> of the values
+ * of the response header with the given name
+ *
+ * @since Servlet 3.0
+ */
+ public Collection<String> getHeaders(String name);
+
+ /**
+ * Gets the names of the headers of this response.
+ *
+ * <p>This method considers only response headers set or added via
+ * {@link #setHeader}, {@link #addHeader}, {@link #setDateHeader},
+ * {@link #addDateHeader}, {@link #setIntHeader}, or
+ * {@link #addIntHeader}, respectively.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>HttpServletResponse</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the names
+ * of the headers of this response
+ *
+ * @since Servlet 3.0
+ */
+ public Collection<String> getHeaderNames();
+
+ /**
+ * Sets the supplier of trailer headers.
+ *
+ * <p>The trailer header field value is defined as a comma-separated list
+ * (see Section 3.2.2 and Section 4.1.2 of RFC 7230).</p>
+ *
+ * <p>The supplier will be called within the scope of whatever thread/call
+ * causes the response content to be completed. Typically this will
+ * be any thread calling close() on the output stream or writer.</p>
+ *
+ * <p>The trailers that run afoul of the provisions of section 4.1.2 of
+ * RFC 7230 are ignored.</p>
+ *
+ * <p>The RFC requires the name of every key that is to be in the
+ * supplied Map is included in the comma separated list that is the value
+ * of the "Trailer" response header. The application is responsible for
+ * ensuring this requirement is met. Failure to do so may lead to
+ * interoperability failures.</p>
+ *
+ * @implSpec
+ * The default implementation is a no-op.
+ *
+ * @param supplier the supplier of trailer headers
+ *
+ * @exception IllegalStateException if it is invoked after the response has
+ * has been committed,
+ * or the trailer is not supported in the request, for instance,
+ * the underlying protocol is HTTP 1.0, or the response is not
+ * in chunked encoding in HTTP 1.1.
+ *
+ * @since Servlet 4.0
+ */
+ default public void setTrailerFields(Supplier<Map<String, String>> supplier) {
+ }
+
+ /**
+ * Gets the supplier of trailer headers.
+ *
+ * @implSpec
+ * The default implememtation return null.
+ *
+ * @return <code>Supplier</code> of trailer headers
+ *
+ * @since Servlet 4.0
+ */
+ default public Supplier<Map<String, String>> getTrailerFields() {
+ return null;
+ }
+
+
+ /*
+ * Server status codes; see RFC 2068.
+ */
+
+ /**
+ * Status code (100) indicating the client can continue.
+ */
+ public static final int SC_CONTINUE = 100;
+
+ /**
+ * Status code (101) indicating the server is switching protocols
+ * according to Upgrade header.
+ */
+ public static final int SC_SWITCHING_PROTOCOLS = 101;
+
+ /**
+ * Status code (200) indicating the request succeeded normally.
+ */
+ public static final int SC_OK = 200;
+
+ /**
+ * Status code (201) indicating the request succeeded and created
+ * a new resource on the server.
+ */
+ public static final int SC_CREATED = 201;
+
+ /**
+ * Status code (202) indicating that a request was accepted for
+ * processing, but was not completed.
+ */
+ public static final int SC_ACCEPTED = 202;
+
+ /**
+ * Status code (203) indicating that the meta information presented
+ * by the client did not originate from the server.
+ */
+ public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
+
+ /**
+ * Status code (204) indicating that the request succeeded but that
+ * there was no new information to return.
+ */
+ public static final int SC_NO_CONTENT = 204;
+
+ /**
+ * Status code (205) indicating that the agent <em>SHOULD</em> reset
+ * the document view which caused the request to be sent.
+ */
+ public static final int SC_RESET_CONTENT = 205;
+
+ /**
+ * Status code (206) indicating that the server has fulfilled
+ * the partial GET request for the resource.
+ */
+ public static final int SC_PARTIAL_CONTENT = 206;
+
+ /**
+ * Status code (300) indicating that the requested resource
+ * corresponds to any one of a set of representations, each with
+ * its own specific location.
+ */
+ public static final int SC_MULTIPLE_CHOICES = 300;
+
+ /**
+ * Status code (301) indicating that the resource has permanently
+ * moved to a new location, and that future references should use a
+ * new URI with their requests.
+ */
+ public static final int SC_MOVED_PERMANENTLY = 301;
+
+ /**
+ * Status code (302) indicating that the resource has temporarily
+ * moved to another location, but that future references should
+ * still use the original URI to access the resource.
+ *
+ * This definition is being retained for backwards compatibility.
+ * SC_FOUND is now the preferred definition.
+ */
+ public static final int SC_MOVED_TEMPORARILY = 302;
+
+ /**
+ * Status code (302) indicating that the resource reside
+ * temporarily under a different URI. Since the redirection might
+ * be altered on occasion, the client should continue to use the
+ * Request-URI for future requests.(HTTP/1.1) To represent the
+ * status code (302), it is recommended to use this variable.
+ */
+ public static final int SC_FOUND = 302;
+
+ /**
+ * Status code (303) indicating that the response to the request
+ * can be found under a different URI.
+ */
+ public static final int SC_SEE_OTHER = 303;
+
+ /**
+ * Status code (304) indicating that a conditional GET operation
+ * found that the resource was available and not modified.
+ */
+ public static final int SC_NOT_MODIFIED = 304;
+
+ /**
+ * Status code (305) indicating that the requested resource
+ * <em>MUST</em> be accessed through the proxy given by the
+ * <code><em>Location</em></code> field.
+ */
+ public static final int SC_USE_PROXY = 305;
+
+ /**
+ * Status code (307) indicating that the requested resource
+ * resides temporarily under a different URI. The temporary URI
+ * <em>SHOULD</em> be given by the <code><em>Location</em></code>
+ * field in the response.
+ */
+ public static final int SC_TEMPORARY_REDIRECT = 307;
+
+ /**
+ * Status code (400) indicating the request sent by the client was
+ * syntactically incorrect.
+ */
+ public static final int SC_BAD_REQUEST = 400;
+
+ /**
+ * Status code (401) indicating that the request requires HTTP
+ * authentication.
+ */
+ public static final int SC_UNAUTHORIZED = 401;
+
+ /**
+ * Status code (402) reserved for future use.
+ */
+ public static final int SC_PAYMENT_REQUIRED = 402;
+
+ /**
+ * Status code (403) indicating the server understood the request
+ * but refused to fulfill it.
+ */
+ public static final int SC_FORBIDDEN = 403;
+
+ /**
+ * Status code (404) indicating that the requested resource is not
+ * available.
+ */
+ public static final int SC_NOT_FOUND = 404;
+
+ /**
+ * Status code (405) indicating that the method specified in the
+ * <code><em>Request-Line</em></code> is not allowed for the resource
+ * identified by the <code><em>Request-URI</em></code>.
+ */
+ public static final int SC_METHOD_NOT_ALLOWED = 405;
+
+ /**
+ * Status code (406) indicating that the resource identified by the
+ * request is only capable of generating response entities which have
+ * content characteristics not acceptable according to the accept
+ * headers sent in the request.
+ */
+ public static final int SC_NOT_ACCEPTABLE = 406;
+
+ /**
+ * Status code (407) indicating that the client <em>MUST</em> first
+ * authenticate itself with the proxy.
+ */
+ public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
+
+ /**
+ * Status code (408) indicating that the client did not produce a
+ * request within the time that the server was prepared to wait.
+ */
+ public static final int SC_REQUEST_TIMEOUT = 408;
+
+ /**
+ * Status code (409) indicating that the request could not be
+ * completed due to a conflict with the current state of the
+ * resource.
+ */
+ public static final int SC_CONFLICT = 409;
+
+ /**
+ * Status code (410) indicating that the resource is no longer
+ * available at the server and no forwarding address is known.
+ * This condition <em>SHOULD</em> be considered permanent.
+ */
+ public static final int SC_GONE = 410;
+
+ /**
+ * Status code (411) indicating that the request cannot be handled
+ * without a defined <code><em>Content-Length</em></code>.
+ */
+ public static final int SC_LENGTH_REQUIRED = 411;
+
+ /**
+ * Status code (412) indicating that the precondition given in one
+ * or more of the request-header fields evaluated to false when it
+ * was tested on the server.
+ */
+ public static final int SC_PRECONDITION_FAILED = 412;
+
+ /**
+ * Status code (413) indicating that the server is refusing to process
+ * the request because the request entity is larger than the server is
+ * willing or able to process.
+ */
+ public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
+
+ /**
+ * Status code (414) indicating that the server is refusing to service
+ * the request because the <code><em>Request-URI</em></code> is longer
+ * than the server is willing to interpret.
+ */
+ public static final int SC_REQUEST_URI_TOO_LONG = 414;
+
+ /**
+ * Status code (415) indicating that the server is refusing to service
+ * the request because the entity of the request is in a format not
+ * supported by the requested resource for the requested method.
+ */
+ public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
+
+ /**
+ * Status code (416) indicating that the server cannot serve the
+ * requested byte range.
+ */
+ public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+
+ /**
+ * Status code (417) indicating that the server could not meet the
+ * expectation given in the Expect request header.
+ */
+ public static final int SC_EXPECTATION_FAILED = 417;
+
+ /**
+ * Status code (500) indicating an error inside the HTTP server
+ * which prevented it from fulfilling the request.
+ */
+ public static final int SC_INTERNAL_SERVER_ERROR = 500;
+
+ /**
+ * Status code (501) indicating the HTTP server does not support
+ * the functionality needed to fulfill the request.
+ */
+ public static final int SC_NOT_IMPLEMENTED = 501;
+
+ /**
+ * Status code (502) indicating that the HTTP server received an
+ * invalid response from a server it consulted when acting as a
+ * proxy or gateway.
+ */
+ public static final int SC_BAD_GATEWAY = 502;
+
+ /**
+ * Status code (503) indicating that the HTTP server is
+ * temporarily overloaded, and unable to handle the request.
+ */
+ public static final int SC_SERVICE_UNAVAILABLE = 503;
+
+ /**
+ * Status code (504) indicating that the server did not receive
+ * a timely response from the upstream server while acting as
+ * a gateway or proxy.
+ */
+ public static final int SC_GATEWAY_TIMEOUT = 504;
+
+ /**
+ * Status code (505) indicating that the server does not support
+ * or refuses to support the HTTP protocol version that was used
+ * in the request message.
+ */
+ public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletResponseWrapper.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletResponseWrapper.java
new file mode 100644
index 0000000..ee92253
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpServletResponseWrapper.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Supplier;
+import javax.servlet.ServletResponseWrapper;
+
+/**
+ *
+ * Provides a convenient implementation of the HttpServletResponse interface that
+ * can be subclassed by developers wishing to adapt the response from a Servlet.
+ * This class implements the Wrapper or Decorator pattern. Methods default to
+ * calling through to the wrapped response object.
+ *
+ * @author Various
+ * @since Servlet 2.3
+ *
+ * @see javax.servlet.http.HttpServletResponse
+ */
+
+public class HttpServletResponseWrapper extends ServletResponseWrapper implements HttpServletResponse {
+
+ /**
+ * Constructs a response adaptor wrapping the given response.
+ * @throws java.lang.IllegalArgumentException if the response is null
+ *
+ * @param response the {@link HttpServletResponse} to be wrapped.
+ */
+ public HttpServletResponseWrapper(HttpServletResponse response) {
+ super(response);
+ }
+
+ private HttpServletResponse _getHttpServletResponse() {
+ return (HttpServletResponse) super.getResponse();
+ }
+
+ /**
+ * The default behavior of this method is to call addCookie(Cookie cookie)
+ * on the wrapped response object.
+ */
+ @Override
+ public void addCookie(Cookie cookie) {
+ this._getHttpServletResponse().addCookie(cookie);
+ }
+
+ /**
+ * The default behavior of this method is to call containsHeader(String name)
+ * on the wrapped response object.
+ */
+ @Override
+ public boolean containsHeader(String name) {
+ return this._getHttpServletResponse().containsHeader(name);
+ }
+
+ /**
+ * The default behavior of this method is to call encodeURL(String url)
+ * on the wrapped response object.
+ */
+ @Override
+ public String encodeURL(String url) {
+ return this._getHttpServletResponse().encodeURL(url);
+ }
+
+ /**
+ * The default behavior of this method is to return encodeRedirectURL(String url)
+ * on the wrapped response object.
+ */
+ @Override
+ public String encodeRedirectURL(String url) {
+ return this._getHttpServletResponse().encodeRedirectURL(url);
+ }
+
+ /**
+ * The default behavior of this method is to call encodeUrl(String url)
+ * on the wrapped response object.
+ *
+ * @deprecated As of version 2.1, use {@link #encodeURL(String url)}
+ * instead
+ */
+ @Deprecated
+ @Override
+ public String encodeUrl(String url) {
+ return this._getHttpServletResponse().encodeUrl(url);
+ }
+
+ /**
+ * The default behavior of this method is to return
+ * encodeRedirectUrl(String url) on the wrapped response object.
+ *
+ * @deprecated As of version 2.1, use
+ * {@link #encodeRedirectURL(String url)} instead
+ */
+ @Deprecated
+ @Override
+ public String encodeRedirectUrl(String url) {
+ return this._getHttpServletResponse().encodeRedirectUrl(url);
+ }
+
+ /**
+ * The default behavior of this method is to call sendError(int sc, String msg)
+ * on the wrapped response object.
+ */
+ @Override
+ public void sendError(int sc, String msg) throws IOException {
+ this._getHttpServletResponse().sendError(sc, msg);
+ }
+
+ /**
+ * The default behavior of this method is to call sendError(int sc)
+ * on the wrapped response object.
+ */
+ @Override
+ public void sendError(int sc) throws IOException {
+ this._getHttpServletResponse().sendError(sc);
+ }
+
+ /**
+ * The default behavior of this method is to return sendRedirect(String location)
+ * on the wrapped response object.
+ */
+ @Override
+ public void sendRedirect(String location) throws IOException {
+ this._getHttpServletResponse().sendRedirect(location);
+ }
+
+ /**
+ * The default behavior of this method is to call setDateHeader(String name, long date)
+ * on the wrapped response object.
+ */
+ @Override
+ public void setDateHeader(String name, long date) {
+ this._getHttpServletResponse().setDateHeader(name, date);
+ }
+
+ /**
+ * The default behavior of this method is to call addDateHeader(String name, long date)
+ * on the wrapped response object.
+ */
+ @Override
+ public void addDateHeader(String name, long date) {
+ this._getHttpServletResponse().addDateHeader(name, date);
+ }
+
+ /**
+ * The default behavior of this method is to return setHeader(String name, String value)
+ * on the wrapped response object.
+ */
+ @Override
+ public void setHeader(String name, String value) {
+ this._getHttpServletResponse().setHeader(name, value);
+ }
+
+ /**
+ * The default behavior of this method is to return addHeader(String name, String value)
+ * on the wrapped response object.
+ */
+ @Override
+ public void addHeader(String name, String value) {
+ this._getHttpServletResponse().addHeader(name, value);
+ }
+
+ /**
+ * The default behavior of this method is to call setIntHeader(String name, int value)
+ * on the wrapped response object.
+ */
+ @Override
+ public void setIntHeader(String name, int value) {
+ this._getHttpServletResponse().setIntHeader(name, value);
+ }
+
+ /**
+ * The default behavior of this method is to call addIntHeader(String name, int value)
+ * on the wrapped response object.
+ */
+ @Override
+ public void addIntHeader(String name, int value) {
+ this._getHttpServletResponse().addIntHeader(name, value);
+ }
+
+ /**
+ * The default behavior of this method is to call setStatus(int sc)
+ * on the wrapped response object.
+ */
+ @Override
+ public void setStatus(int sc) {
+ this._getHttpServletResponse().setStatus(sc);
+ }
+
+ /**
+ * The default behavior of this method is to call
+ * setStatus(int sc, String sm) on the wrapped response object.
+ *
+ * @deprecated As of version 2.1, due to ambiguous meaning of the
+ * message parameter. To set a status code
+ * use {@link #setStatus(int)}, to send an error with a description
+ * use {@link #sendError(int, String)}
+ */
+ @Deprecated
+ @Override
+ public void setStatus(int sc, String sm) {
+ this._getHttpServletResponse().setStatus(sc, sm);
+ }
+
+ /**
+ * The default behaviour of this method is to call
+ * {@link HttpServletResponse#getStatus} on the wrapped response
+ * object.
+ *
+ * @return the current status code of the wrapped response
+ */
+ @Override
+ public int getStatus() {
+ return _getHttpServletResponse().getStatus();
+ }
+
+ /**
+ * The default behaviour of this method is to call
+ * {@link HttpServletResponse#getHeader} on the wrapped response
+ * object.
+ *
+ * @param name the name of the response header whose value to return
+ *
+ * @return the value of the response header with the given name,
+ * or <tt>null</tt> if no header with the given name has been set
+ * on the wrapped response
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public String getHeader(String name) {
+ return _getHttpServletResponse().getHeader(name);
+ }
+
+ /**
+ * The default behaviour of this method is to call
+ * {@link HttpServletResponse#getHeaders} on the wrapped response
+ * object.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>HttpServletResponseWrapper</code>.
+ *
+ * @param name the name of the response header whose values to return
+ *
+ * @return a (possibly empty) <code>Collection</code> of the values
+ * of the response header with the given name
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public Collection<String> getHeaders(String name) {
+ return _getHttpServletResponse().getHeaders(name);
+ }
+
+ /**
+ * The default behaviour of this method is to call
+ * {@link HttpServletResponse#getHeaderNames} on the wrapped response
+ * object.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>HttpServletResponseWrapper</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the names
+ * of the response headers
+ *
+ * @since Servlet 3.0
+ */
+ @Override
+ public Collection<String> getHeaderNames() {
+ return _getHttpServletResponse().getHeaderNames();
+ }
+
+ /**
+ * The default behaviour of this method is to call
+ * {@link HttpServletResponse#setTrailerFields} on the wrapped response
+ * object.
+ *
+ * @param supplier of trailer headers
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public void setTrailerFields(Supplier<Map<String, String>> supplier) {
+ _getHttpServletResponse().setTrailerFields(supplier);
+ }
+
+ /**
+ * The default behaviour of this method is to call
+ * {@link HttpServletResponse#getTrailerFields} on the wrapped response
+ * object.
+ *
+ * @return supplier of trailer headers
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public Supplier<Map<String, String>> getTrailerFields() {
+ return _getHttpServletResponse().getTrailerFields();
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSession.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSession.java
new file mode 100644
index 0000000..158d0bc
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSession.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.util.Enumeration;
+import javax.servlet.ServletContext;
+
+/**
+ *
+ * Provides a way to identify a user across more than one page
+ * request or visit to a Web site and to store information about that user.
+ *
+ * <p>The servlet container uses this interface to create a session
+ * between an HTTP client and an HTTP server. The session persists
+ * for a specified time period, across more than one connection or
+ * page request from the user. A session usually corresponds to one
+ * user, who may visit a site many times. The server can maintain a
+ * session in many ways such as using cookies or rewriting URLs.
+ *
+ * <p>This interface allows servlets to
+ * <ul>
+ * <li>View and manipulate information about a session, such as
+ * the session identifier, creation time, and last accessed time
+ * <li>Bind objects to sessions, allowing user information to persist
+ * across multiple user connections
+ * </ul>
+ *
+ * <p>When an application stores an object in or removes an object from a
+ * session, the session checks whether the object implements
+ * {@link HttpSessionBindingListener}. If it does,
+ * the servlet notifies the object that it has been bound to or unbound
+ * from the session. Notifications are sent after the binding methods complete.
+ * For session that are invalidated or expire, notifications are sent after
+ * the session has been invalidated or expired.
+ *
+ * <p> When container migrates a session between VMs in a distributed container
+ * setting, all session attributes implementing the {@link HttpSessionActivationListener}
+ * interface are notified.
+ *
+ * <p>A servlet should be able to handle cases in which
+ * the client does not choose to join a session, such as when cookies are
+ * intentionally turned off. Until the client joins the session,
+ * <code>isNew</code> returns <code>true</code>. If the client chooses
+ * not to join
+ * the session, <code>getSession</code> will return a different session
+ * on each request, and <code>isNew</code> will always return
+ * <code>true</code>.
+ *
+ * <p>Session information is scoped only to the current web application
+ * (<code>ServletContext</code>), so information stored in one context
+ * will not be directly visible in another.
+ *
+ * @author Various
+ *
+ * @see HttpSessionBindingListener
+ * @see HttpSessionContext
+ */
+
+public interface HttpSession {
+
+ /**
+ *
+ * Returns the time when this session was created, measured
+ * in milliseconds since midnight January 1, 1970 GMT.
+ *
+ * @return a <code>long</code> specifying
+ * when this session was created,
+ * expressed in
+ * milliseconds since 1/1/1970 GMT
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ public long getCreationTime();
+
+
+ /**
+ * Returns a string containing the unique identifier assigned
+ * to this session. The identifier is assigned
+ * by the servlet container and is implementation dependent.
+ *
+ * @return a string specifying the identifier
+ * assigned to this session
+ */
+ public String getId();
+
+
+ /**
+ *
+ * Returns the last time the client sent a request associated with
+ * this session, as the number of milliseconds since midnight
+ * January 1, 1970 GMT, and marked by the time the container received the
+ * request.
+ *
+ * <p>Actions that your application takes, such as getting or setting
+ * a value associated with the session, do not affect the access
+ * time.
+ *
+ * @return a <code>long</code>
+ * representing the last time
+ * the client sent a request associated
+ * with this session, expressed in
+ * milliseconds since 1/1/1970 GMT
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ public long getLastAccessedTime();
+
+
+ /**
+ * Returns the ServletContext to which this session belongs.
+ *
+ * @return The ServletContext object for the web application
+ * @since Servlet 2.3
+ */
+ public ServletContext getServletContext();
+
+
+ /**
+ * Specifies the time, in seconds, between client requests before the
+ * servlet container will invalidate this session.
+ *
+ * <p>An <tt>interval</tt> value of zero or less indicates that the
+ * session should never timeout.
+ *
+ * @param interval An integer specifying the number
+ * of seconds
+ */
+ public void setMaxInactiveInterval(int interval);
+
+
+ /**
+ * Returns the maximum time interval, in seconds, that
+ * the servlet container will keep this session open between
+ * client accesses. After this interval, the servlet container
+ * will invalidate the session. The maximum time interval can be set
+ * with the <code>setMaxInactiveInterval</code> method.
+ *
+ * <p>A return value of zero or less indicates that the
+ * session will never timeout.
+ *
+ * @return an integer specifying the number of
+ * seconds this session remains open
+ * between client requests
+ *
+ * @see #setMaxInactiveInterval
+ */
+ public int getMaxInactiveInterval();
+
+
+ /**
+ *
+ * @deprecated As of Version 2.1, this method is
+ * deprecated and has no replacement.
+ * It will be removed in a future
+ * version of the Java Servlet API.
+ *
+ * @return the {@link HttpSessionContext} for this session.
+ */
+ @Deprecated
+ public HttpSessionContext getSessionContext();
+
+
+ /**
+ * Returns the object bound with the specified name in this session, or
+ * <code>null</code> if no object is bound under the name.
+ *
+ * @param name a string specifying the name of the object
+ *
+ * @return the object with the specified name
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ public Object getAttribute(String name);
+
+
+ /**
+ * @deprecated As of Version 2.2, this method is
+ * replaced by {@link #getAttribute}.
+ *
+ * @param name a string specifying the name of the object
+ *
+ * @return the object with the specified name
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ @Deprecated
+ public Object getValue(String name);
+
+
+ /**
+ * Returns an <code>Enumeration</code> of <code>String</code> objects
+ * containing the names of all the objects bound to this session.
+ *
+ * @return an <code>Enumeration</code> of
+ * <code>String</code> objects specifying the
+ * names of all the objects bound to
+ * this session
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ public Enumeration<String> getAttributeNames();
+
+
+ /**
+ * @deprecated As of Version 2.2, this method is
+ * replaced by {@link #getAttributeNames}
+ *
+ * @return an array of <code>String</code>
+ * objects specifying the
+ * names of all the objects bound to
+ * this session
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ @Deprecated
+ public String[] getValueNames();
+
+
+ /**
+ * Binds an object to this session, using the name specified.
+ * If an object of the same name is already bound to the session,
+ * the object is replaced.
+ *
+ * <p>After this method executes, and if the new object
+ * implements <code>HttpSessionBindingListener</code>,
+ * the container calls
+ * <code>HttpSessionBindingListener.valueBound</code>. The container then
+ * notifies any <code>HttpSessionAttributeListener</code>s in the web
+ * application.
+
+ * <p>If an object was already bound to this session of this name
+ * that implements <code>HttpSessionBindingListener</code>, its
+ * <code>HttpSessionBindingListener.valueUnbound</code> method is called.
+ *
+ * <p>If the value passed in is null, this has the same effect as calling
+ * <code>removeAttribute()</code>.
+ *
+ *
+ * @param name the name to which the object is bound;
+ * cannot be null
+ *
+ * @param value the object to be bound
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ public void setAttribute(String name, Object value);
+
+
+ /**
+ * @deprecated As of Version 2.2, this method is
+ * replaced by {@link #setAttribute}
+ *
+ * @param name the name to which the object is bound;
+ * cannot be null
+ *
+ * @param value the object to be bound; cannot be null
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ @Deprecated
+ public void putValue(String name, Object value);
+
+
+ /**
+ * Removes the object bound with the specified name from
+ * this session. If the session does not have an object
+ * bound with the specified name, this method does nothing.
+ *
+ * <p>After this method executes, and if the object
+ * implements <code>HttpSessionBindingListener</code>,
+ * the container calls
+ * <code>HttpSessionBindingListener.valueUnbound</code>. The container
+ * then notifies any <code>HttpSessionAttributeListener</code>s in the web
+ * application.
+ *
+ * @param name the name of the object to
+ * remove from this session
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ public void removeAttribute(String name);
+
+
+ /**
+ * @deprecated As of Version 2.2, this method is
+ * replaced by {@link #removeAttribute}
+ *
+ * @param name the name of the object to
+ * remove from this session
+ *
+ * @exception IllegalStateException if this method is called on an
+ * invalidated session
+ */
+ @Deprecated
+ public void removeValue(String name);
+
+
+ /**
+ * Invalidates this session then unbinds any objects bound
+ * to it.
+ *
+ * @exception IllegalStateException if this method is called on an
+ * already invalidated session
+ */
+ public void invalidate();
+
+
+ /**
+ * Returns <code>true</code> if the client does not yet know about the
+ * session or if the client chooses not to join the session. For
+ * example, if the server used only cookie-based sessions, and
+ * the client had disabled the use of cookies, then a session would
+ * be new on each request.
+ *
+ * @return <code>true</code> if the
+ * server has created a session,
+ * but the client has not yet joined
+ *
+ * @exception IllegalStateException if this method is called on an
+ * already invalidated session
+ */
+ public boolean isNew();
+
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionActivationListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionActivationListener.java
new file mode 100644
index 0000000..3206927
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionActivationListener.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.util.EventListener;
+
+/** Objects that are bound to a session may listen to container
+ * events notifying them that sessions will be passivated and that
+ * session will be activated. A container that migrates session
+ * between VMs or persists sessions is required to notify all
+ * attributes bound to sessions implementing
+ * HttpSessionActivationListener.
+ *
+ * @since Servlet 2.3
+ */
+
+public interface HttpSessionActivationListener extends EventListener {
+
+ /**
+ * Notification that the session is about to be passivated.
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param se the {@link HttpSessionEvent} indicating the passivation
+ * of the session
+ */
+ default public void sessionWillPassivate(HttpSessionEvent se) {}
+
+ /**
+ * Notification that the session has just been activated.
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param se the {@link HttpSessionEvent} indicating the activation
+ * of the session
+ */
+ default public void sessionDidActivate(HttpSessionEvent se) {}
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionAttributeListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionAttributeListener.java
new file mode 100644
index 0000000..2a1eceb
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionAttributeListener.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about HttpSession
+ * attribute changes.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link javax.servlet.ServletContext}.
+ *
+ * <p>The order in which implementations of this interface are invoked is
+ * unspecified.
+ *
+ * @since Servlet 2.3
+ */
+
+public interface HttpSessionAttributeListener extends EventListener {
+
+ /**
+ * Receives notification that an attribute has been added to a
+ * session.
+ *
+ * @param event the HttpSessionBindingEvent containing the session
+ * and the name and value of the attribute that was added
+ */
+ default public void attributeAdded(HttpSessionBindingEvent event) {}
+
+ /**
+ * Receives notification that an attribute has been removed from a
+ * session.
+ *
+ * @param event the HttpSessionBindingEvent containing the session
+ * and the name and value of the attribute that was removed
+ */
+ default public void attributeRemoved(HttpSessionBindingEvent event) {}
+
+ /**
+ * Receives notification that an attribute has been replaced in a
+ * session.
+ *
+ * @param event the HttpSessionBindingEvent containing the session
+ * and the name and (old) value of the attribute that was replaced
+ */
+ default public void attributeReplaced(HttpSessionBindingEvent event) {}
+
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionBindingEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionBindingEvent.java
new file mode 100644
index 0000000..2538817
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionBindingEvent.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+/**
+ *
+ * Events of this type are either sent to an object that implements
+ * {@link HttpSessionBindingListener} when it is bound or unbound from a
+ * session, or to a {@link HttpSessionAttributeListener} that has been
+ * configured in the deployment descriptor when any attribute is bound, unbound
+ * or replaced in a session.
+ *
+ * <p>The session binds the object by a call to
+ * <code>HttpSession.setAttribute</code> and unbinds the object
+ * by a call to <code>HttpSession.removeAttribute</code>.
+ *
+ * @author Various
+ *
+ * @see HttpSession
+ * @see HttpSessionBindingListener
+ * @see HttpSessionAttributeListener
+ */
+
+public class HttpSessionBindingEvent extends HttpSessionEvent {
+
+ private static final long serialVersionUID = 7308000419984825907L;
+
+ /* The name to which the object is being bound or unbound */
+ private String name;
+
+ /* The object is being bound or unbound */
+ private Object value;
+
+ /**
+ *
+ * Constructs an event that notifies an object that it
+ * has been bound to or unbound from a session.
+ * To receive the event, the object must implement
+ * {@link HttpSessionBindingListener}.
+ *
+ * @param session the session to which the object is bound or unbound
+ * @param name the name with which the object is bound or unbound
+ *
+ * @see #getName
+ * @see #getSession
+ */
+ public HttpSessionBindingEvent(HttpSession session, String name) {
+ super(session);
+ this.name = name;
+ }
+
+ /**
+ *
+ * Constructs an event that notifies an object that it
+ * has been bound to or unbound from a session.
+ * To receive the event, the object must implement
+ * {@link HttpSessionBindingListener}.
+ *
+ * @param session the session to which the object is bound or unbound
+ * @param name the name with which the object is bound or unbound
+ * @param value the object that is bound or unbound
+ *
+ * @see #getName
+ * @see #getSession
+ */
+ public HttpSessionBindingEvent(HttpSession session, String name, Object value) {
+ super(session);
+ this.name = name;
+ this.value = value;
+ }
+
+ /** Return the session that changed. */
+ @Override
+ public HttpSession getSession () {
+ return super.getSession();
+ }
+
+ /**
+ * Returns the name with which the attribute is bound to or
+ * unbound from the session.
+ *
+ * @return a string specifying the name with which
+ * the object is bound to or unbound from the session
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the value of the attribute that has been added, removed or
+ * replaced. If the attribute was added (or bound), this is the value of the
+ * attribute. If the attribute was removed (or unbound), this is the value
+ * of the removed attribute. If the attribute was replaced, this is the old
+ * value of the attribute.
+ *
+ * @return the value of the attribute that has been added, removed
+ * or replaced
+ *
+ * @since Servlet 2.3
+ */
+ public Object getValue() {
+ return this.value;
+ }
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionBindingListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionBindingListener.java
new file mode 100644
index 0000000..9dd95db
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionBindingListener.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.util.EventListener;
+
+
+
+
+
+/**
+ * Causes an object to be notified when it is bound to
+ * or unbound from a session. The object is notified
+ * by an {@link HttpSessionBindingEvent} object. This may be as a result
+ * of a servlet programmer explicitly unbinding an attribute from a session,
+ * due to a session being invalidated, or due to a session timing out.
+ *
+ *
+ * @author Various
+ *
+ * @see HttpSession
+ * @see HttpSessionBindingEvent
+ *
+ */
+
+public interface HttpSessionBindingListener extends EventListener {
+
+ /**
+ *
+ * Notifies the object that it is being bound to
+ * a session and identifies the session.
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param event the event that identifies the
+ * session
+ *
+ * @see #valueUnbound
+ *
+ */
+ default public void valueBound(HttpSessionBindingEvent event) {}
+
+ /**
+ *
+ * Notifies the object that it is being unbound
+ * from a session and identifies the session.
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param event the event that identifies
+ * the session
+ *
+ * @see #valueBound
+ *
+ */
+ default public void valueUnbound(HttpSessionBindingEvent event) {}
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionContext.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionContext.java
new file mode 100644
index 0000000..e9ef098
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionContext.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.util.Enumeration;
+
+/**
+ *
+ * @author Various
+ *
+ * @deprecated As of Java(tm) Servlet API 2.1
+ * for security reasons, with no replacement.
+ * This interface will be removed in a future
+ * version of this API.
+ *
+ * @see HttpSession
+ * @see HttpSessionBindingEvent
+ * @see HttpSessionBindingListener
+ *
+ */
+
+@Deprecated
+public interface HttpSessionContext {
+
+ /**
+ *
+ * @deprecated As of Java Servlet API 2.1 with
+ * no replacement. This method must
+ * return null and will be removed in
+ * a future version of this API.
+ * @param sessionId the id of the session to be returned
+ *
+ * @return null in all cases
+ */
+ @Deprecated
+ public HttpSession getSession(String sessionId);
+
+
+
+
+ /**
+ *
+ * @deprecated As of Java Servlet API 2.1 with
+ * no replacement. This method must return
+ * an empty <code>Enumeration</code> and will be removed
+ * in a future version of this API.
+ *
+ * @return null
+ *
+ */
+ @Deprecated
+ public Enumeration<String> getIds();
+}
+
+
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionEvent.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionEvent.java
new file mode 100644
index 0000000..7a348b8
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionEvent.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+/**
+ * This is the class representing event notifications for changes to
+ * sessions within a web application.
+ *
+ * @since Servlet 2.3
+ */
+public class HttpSessionEvent extends java.util.EventObject {
+
+ private static final long serialVersionUID = -7622791603672342895L;
+
+ /**
+ * Construct a session event from the given source.
+ *
+ * @param source the {@link HttpSession} corresponding to this event
+ */
+ public HttpSessionEvent(HttpSession source) {
+ super(source);
+ }
+
+ /**
+ * Return the session that changed.
+ * @return the {@link HttpSession} for this event.
+ */
+ public HttpSession getSession () {
+ return (HttpSession) super.getSource();
+ }
+}
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionIdListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionIdListener.java
new file mode 100644
index 0000000..412ea46
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionIdListener.java
@@ -0,0 +1,74 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about HttpSession
+ * id changes.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link javax.servlet.ServletContext}.
+ *
+ * <p>The order in which implementations of this interface are invoked is
+ * unspecified.
+ *
+ * @since Servlet 3.1
+ */
+
+public interface HttpSessionIdListener extends EventListener {
+
+ /**
+ * Receives notification that session id has been changed in a
+ * session.
+ *
+ * @param event the HttpSessionBindingEvent containing the session
+ * and the name and (old) value of the attribute that was replaced
+ *
+ * @param oldSessionId the old session id
+ */
+ public void sessionIdChanged(HttpSessionEvent event, String oldSessionId);
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionListener.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionListener.java
new file mode 100644
index 0000000..9b4dc8c
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpSessionListener.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import java.util.EventListener;
+
+/**
+ * Interface for receiving notification events about HttpSession
+ * lifecycle changes.
+ *
+ * <p>In order to receive these notification events, the implementation
+ * class must be either declared in the deployment descriptor of the web
+ * application, annotated with {@link javax.servlet.annotation.WebListener},
+ * or registered via one of the addListener methods defined on
+ * {@link javax.servlet.ServletContext}.
+ *
+ * <p>Implementations of this interface are invoked at their
+ * {@link #sessionCreated} method in the order in which they have been
+ * declared, and at their {@link #sessionDestroyed} method in reverse
+ * order.
+ *
+ * @see HttpSessionEvent
+ *
+ * @since Servlet 2.3
+ */
+public interface HttpSessionListener extends EventListener {
+
+ /**
+ * Receives notification that a session has been created.
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param se the HttpSessionEvent containing the session
+ */
+ default public void sessionCreated(HttpSessionEvent se) {}
+
+ /**
+ * Receives notification that a session is about to be invalidated.
+ *
+ * @implSpec
+ * The default implementation takes no action.
+ *
+ * @param se the HttpSessionEvent containing the session
+ */
+ default public void sessionDestroyed(HttpSessionEvent se) {}
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpUpgradeHandler.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpUpgradeHandler.java
new file mode 100644
index 0000000..23e9689
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpUpgradeHandler.java
@@ -0,0 +1,64 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+/**
+ * This interface encapsulates the upgrade protocol processing.
+ * A HttpUpgradeHandler implementation would allow the servlet container
+ * to communicate with it.
+ *
+ * @since Servlet 3.1
+ */
+
+public interface HttpUpgradeHandler {
+ /**
+ * It is called once the HTTP Upgrade process has been completed and
+ * the upgraded connection is ready to start using the new protocol.
+ *
+ * @param wc the WebConnection object associated to this upgrade request
+ */
+ public void init(WebConnection wc);
+
+ /**
+ * It is called when the client is disconnected.
+ */
+ public void destroy();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpUtils.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpUtils.java
new file mode 100644
index 0000000..372f056
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/HttpUtils.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package javax.servlet.http;
+
+import javax.servlet.ServletInputStream;
+import java.util.Hashtable;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.io.IOException;
+
+/**
+ * @deprecated As of Java(tm) Servlet API 2.3.
+ * These methods were only useful
+ * with the default encoding and have been moved
+ * to the request interfaces.
+ *
+ */
+@Deprecated
+public class HttpUtils {
+
+ private static final String LSTRING_FILE =
+ "javax.servlet.http.LocalStrings";
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+
+ /**
+ * Constructs an empty <code>HttpUtils</code> object.
+ */
+ public HttpUtils() {}
+
+
+ /**
+ * Parses a query string passed from the client to the
+ * server and builds a <code>HashTable</code> object
+ * with key-value pairs.
+ * The query string should be in the form of a string
+ * packaged by the GET or POST method, that is, it
+ * should have key-value pairs in the form <i>key=value</i>,
+ * with each pair separated from the next by a & character.
+ *
+ * <p>A key can appear more than once in the query string
+ * with different values. However, the key appears only once in
+ * the hashtable, with its value being
+ * an array of strings containing the multiple values sent
+ * by the query string.
+ *
+ * <p>The keys and values in the hashtable are stored in their
+ * decoded form, so
+ * any + characters are converted to spaces, and characters
+ * sent in hexadecimal notation (like <i>%xx</i>) are
+ * converted to ASCII characters.
+ *
+ * @param s a string containing the query to be parsed
+ *
+ * @return a <code>HashTable</code> object built
+ * from the parsed key-value pairs
+ *
+ * @exception IllegalArgumentException if the query string is invalid
+ */
+ public static Hashtable<String, String[]> parseQueryString(String s) {
+
+ String valArray[] = null;
+
+ if (s == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Hashtable<String, String[]> ht = new Hashtable<String, String[]>();
+ StringBuilder sb = new StringBuilder();
+ StringTokenizer st = new StringTokenizer(s, "&");
+ while (st.hasMoreTokens()) {
+ String pair = st.nextToken();
+ int pos = pair.indexOf('=');
+ if (pos == -1) {
+ // XXX
+ // should give more detail about the illegal argument
+ throw new IllegalArgumentException();
+ }
+ String key = parseName(pair.substring(0, pos), sb);
+ String val = parseName(pair.substring(pos+1, pair.length()), sb);
+ if (ht.containsKey(key)) {
+ String oldVals[] = ht.get(key);
+ valArray = new String[oldVals.length + 1];
+ for (int i = 0; i < oldVals.length; i++) {
+ valArray[i] = oldVals[i];
+ }
+ valArray[oldVals.length] = val;
+ } else {
+ valArray = new String[1];
+ valArray[0] = val;
+ }
+ ht.put(key, valArray);
+ }
+
+ return ht;
+ }
+
+
+ /**
+ *
+ * Parses data from an HTML form that the client sends to
+ * the server using the HTTP POST method and the
+ * <i>application/x-www-form-urlencoded</i> MIME type.
+ *
+ * <p>The data sent by the POST method contains key-value
+ * pairs. A key can appear more than once in the POST data
+ * with different values. However, the key appears only once in
+ * the hashtable, with its value being
+ * an array of strings containing the multiple values sent
+ * by the POST method.
+ *
+ * <p>The keys and values in the hashtable are stored in their
+ * decoded form, so
+ * any + characters are converted to spaces, and characters
+ * sent in hexadecimal notation (like <i>%xx</i>) are
+ * converted to ASCII characters.
+ *
+ * @param len an integer specifying the length,
+ * in characters, of the
+ * <code>ServletInputStream</code>
+ * object that is also passed to this
+ * method
+ *
+ * @param in the <code>ServletInputStream</code>
+ * object that contains the data sent
+ * from the client
+ *
+ * @return a <code>HashTable</code> object built
+ * from the parsed key-value pairs
+ *
+ * @exception IllegalArgumentException if the data
+ * sent by the POST method is invalid
+ */
+ public static Hashtable<String, String[]> parsePostData(int len,
+ ServletInputStream in) {
+ // XXX
+ // should a length of 0 be an IllegalArgumentException
+
+ if (len <=0) {
+ // cheap hack to return an empty hash
+ return new Hashtable<String, String[]>();
+ }
+
+ if (in == null) {
+ throw new IllegalArgumentException();
+ }
+
+ //
+ // Make sure we read the entire POSTed body.
+ //
+ byte[] postedBytes = new byte [len];
+ try {
+ int offset = 0;
+
+ do {
+ int inputLen = in.read (postedBytes, offset, len - offset);
+ if (inputLen <= 0) {
+ String msg = lStrings.getString("err.io.short_read");
+ throw new IllegalArgumentException (msg);
+ }
+ offset += inputLen;
+ } while ((len - offset) > 0);
+
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+
+ // XXX we shouldn't assume that the only kind of POST body
+ // is FORM data encoded using ASCII or ISO Latin/1 ... or
+ // that the body should always be treated as FORM data.
+ //
+
+ try {
+ String postedBody = new String(postedBytes, 0, len, "8859_1");
+ return parseQueryString(postedBody);
+ } catch (java.io.UnsupportedEncodingException e) {
+ // XXX function should accept an encoding parameter & throw this
+ // exception. Otherwise throw something expected.
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+
+
+ /*
+ * Parse a name in the query string.
+ */
+ private static String parseName(String s, StringBuilder sb) {
+ sb.setLength(0);
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '+':
+ sb.append(' ');
+ break;
+ case '%':
+ try {
+ sb.append((char) Integer.parseInt(s.substring(i+1, i+3),
+ 16));
+ i += 2;
+ } catch (NumberFormatException e) {
+ // XXX
+ // need to be more specific about illegal arg
+ throw new IllegalArgumentException();
+ } catch (StringIndexOutOfBoundsException e) {
+ String rest = s.substring(i);
+ sb.append(rest);
+ if (rest.length()==2)
+ i++;
+ }
+
+ break;
+ default:
+ sb.append(c);
+ break;
+ }
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ *
+ * Reconstructs the URL the client used to make the request,
+ * using information in the <code>HttpServletRequest</code> object.
+ * The returned URL contains a protocol, server name, port
+ * number, and server path, but it does not include query
+ * string parameters.
+ *
+ * <p>Because this method returns a <code>StringBuffer</code>,
+ * not a string, you can modify the URL easily, for example,
+ * to append query parameters.
+ *
+ * <p>This method is useful for creating redirect messages
+ * and for reporting errors.
+ *
+ * @param req a <code>HttpServletRequest</code> object
+ * containing the client's request
+ *
+ * @return a <code>StringBuffer</code> object containing
+ * the reconstructed URL
+ */
+ public static StringBuffer getRequestURL (HttpServletRequest req) {
+ StringBuffer url = new StringBuffer();
+ String scheme = req.getScheme ();
+ int port = req.getServerPort ();
+ String urlPath = req.getRequestURI();
+
+ //String servletPath = req.getServletPath ();
+ //String pathInfo = req.getPathInfo ();
+
+ url.append (scheme); // http, https
+ url.append ("://");
+ url.append (req.getServerName ());
+ if ((scheme.equals ("http") && port != 80)
+ || (scheme.equals ("https") && port != 443)) {
+ url.append (':');
+ url.append (req.getServerPort ());
+ }
+ //if (servletPath != null)
+ // url.append (servletPath);
+ //if (pathInfo != null)
+ // url.append (pathInfo);
+ url.append(urlPath);
+
+ return url;
+ }
+}
+
+
+
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings.properties b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings.properties
new file mode 100644
index 0000000..e52aa45
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings.properties
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# Default localized string information
+# Localized for Locale en_US
+
+err.cookie_name_is_token=Cookie name \"{0}\" is a reserved token
+err.cookie_name_blank=Cookie name must not be null or empty
+err.io.nullArray=Null passed for byte array in write method
+err.io.indexOutOfBounds=Invalid offset [{0}] and / or length [{1}] specified for array of size [{2}]
+err.io.short_read=Short Read
+err.ise.getWriter=Illegal to call getWriter() after getOutputStream() has been called
+err.ise.getOutputStream=Illegal to call getOutputStream() after getWriter() has been called
+
+http.method_not_implemented=Method {0} is not defined in RFC 2068 and is not supported by the Servlet API
+
+http.method_get_not_supported=HTTP method GET is not supported by this URL
+http.method_post_not_supported=HTTP method POST is not supported by this URL
+http.method_put_not_supported=HTTP method PUT is not supported by this URL
+http.method_delete_not_supported=Http method DELETE is not supported by this URL
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_es.properties b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_es.properties
new file mode 100644
index 0000000..65367d9
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_es.properties
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# $Id: LocalStrings_es.properties,v 1.1.1.1 2003/01/27 16:07:47 ja120174 Exp $
+#
+# Default localized string information
+# Localized para Locale es_ES
+
+err.cookie_name_is_token=El Nombre de Cookie {0} es una palabra reservada
+err.io.negativelength=Longitud Negativa en el metodo write
+err.io.short_read=Lectura Corta
+
+http.method_not_implemented=El Metodo {0} no esta definido en la especificacion RFC 2068 y no es soportado por la API Servlet
+
+http.method_get_not_supported=El Metodo HTTP GET no es soportado por esta URL
+http.method_post_not_supported=El Metodo HTTP POST no es soportado por esta URL
+http.method_put_not_supported=El Metodo HTTP PUT no es soportado por esta URL
+http.method_delete_not_supported=El Metodo HTTP DELETE no es soportado por esta URL
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_fr.properties b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_fr.properties
new file mode 100644
index 0000000..0c3f5d6
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_fr.properties
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# Default localized string information
+# Localized for Locale fr_FR
+
+err.cookie_name_is_token=Le nom de cookie \"{0}\" est un \"token\" réservé
+err.io.negativelength=Taille négative donnée dans la méthode \"write\"
+err.io.short_read=Lecture partielle
+
+http.method_not_implemented=Le méthode {0} n''est pas définie dans la RFC 2068 et n''est pas supportée par l''API Servlet
+
+http.method_get_not_supported=La méthode HTTP GET n''est pas supportée par cette URL
+http.method_post_not_supported=La méthode HTTP POST n''est pas supportée par cette URL
+http.method_put_not_supported=La méthode HTTP PUT n''est pas supportée par cette URL
+http.method_delete_not_supported=La méthode HTTP DELETE n''est pas supportée par cette URL
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_ja.properties b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_ja.properties
new file mode 100644
index 0000000..eec2148
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/LocalStrings_ja.properties
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright 2004 The Apache Software Foundation
+#
+# Licensed 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.
+#
+
+# Default localized string information
+# Localized for Locale ja_JP
+
+err.cookie_name_is_token=\u30af\u30c3\u30ad\u30fc\u540d \"{0}\" \u306f\u4e88\u7d04\u6e08\u306e\u30c8\u30fc\u30af\u30f3\u3067\u3059\u3002
+err.io.negativelength=write\u30e1\u30bd\u30c3\u30c9\u306b\u8ca0\u306e\u9577\u3055\u304c\u6307\u5b9a\u3055\u308c\u307e\u3057\u305f\u3002
+err.io.short_read=\u8aad\u307f\u8fbc\u307f\u304c\u3059\u3050\u306b\u7d42\u308f\u308a\u307e\u3057\u305f\u3002
+
+http.method_not_implemented=\u30e1\u30bd\u30c3\u30c9 {0} \u306fRFC 2068\u306b\u306f\u5b9a\u7fa9\u3055\u308c\u3066\u304a\u3089\u305a\u3001\u30b5\u30fc\u30d6\u30ec\u30c3\u30c8API\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u307e\u305b\u3093\u3002
+
+http.method_get_not_supported=HTTP\u306eGET\u30e1\u30bd\u30c3\u30c9\u306f\u3001\u3053\u306eURL\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
+http.method_post_not_supported=HTTP\u306ePOST\u30e1\u30bd\u30c3\u30c9\u306f\u3001\u3053\u306eURL\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
+http.method_put_not_supported=HTTP\u306ePUT\u30e1\u30bd\u30c3\u30c9\u306f\u3001\u3053\u306eURL\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
+http.method_delete_not_supported=HTTP\u306eDELETE\u30e1\u30bd\u30c3\u30c9\u306f\u3001\u3053\u306eURL\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/MappingMatch.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/MappingMatch.java
new file mode 100644
index 0000000..4077cc5
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/MappingMatch.java
@@ -0,0 +1,75 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+/**
+ * <p>Enumeration of Servlet mapping types.</p>
+ *
+ * @since 4.0
+ */
+public enum MappingMatch {
+ /**
+ * <p>This is used when the mapping was achieved
+ * with an exact match to the application's context root.</p>
+ */
+ CONTEXT_ROOT,
+ /**
+ * <p>This is used when the mapping was achieved
+ * with an exact match to the default servlet of the application, the '{@code /}'
+ * character.</p>
+ */
+ DEFAULT,
+ /**
+ * <p>This is used when the mapping was achieved
+ * with an exact match to the incoming request.</p>
+ */
+ EXACT,
+ /**
+ * <p>This is used when the mapping was achieved
+ * using an extension, such as "{@code *.xhtml}".</p>
+ */
+ EXTENSION,
+ /**
+ * <p>This is used when the mapping was achieved
+ * using a path, such as "{@code /faces/*}".</p>
+ */
+ PATH
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/Part.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/Part.java
new file mode 100644
index 0000000..6df5083
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/Part.java
@@ -0,0 +1,174 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * <p> This class represents a part or form item that was received within a
+ * <code>multipart/form-data</code> POST request.
+ *
+ * @since Servlet 3.0
+ */
+public interface Part {
+
+ /**
+ * Gets the content of this part as an <tt>InputStream</tt>
+ *
+ * @return The content of this part as an <tt>InputStream</tt>
+ * @throws IOException If an error occurs in retrieving the content
+ * as an <tt>InputStream</tt>
+ */
+ public InputStream getInputStream() throws IOException;
+
+ /**
+ * Gets the content type of this part.
+ *
+ * @return The content type of this part.
+ */
+ public String getContentType();
+
+ /**
+ * Gets the name of this part
+ *
+ * @return The name of this part as a <tt>String</tt>
+ */
+ public String getName();
+
+ /**
+ * Gets the file name specified by the client
+ *
+ * @return the submitted file name
+ *
+ * @since Servlet 3.1
+ */
+ public String getSubmittedFileName();
+
+ /**
+ * Returns the size of this fille.
+ *
+ * @return a <code>long</code> specifying the size of this part, in bytes.
+ */
+ public long getSize();
+
+ /**
+ * A convenience method to write this uploaded item to disk.
+ *
+ * <p>This method is not guaranteed to succeed if called more than once for
+ * the same part. This allows a particular implementation to use, for
+ * example, file renaming, where possible, rather than copying all of the
+ * underlying data, thus gaining a significant performance benefit.
+ *
+ * @param fileName The location into which the uploaded part should
+ be stored. The value may be a file name or a path. The actual
+ location of the file in the filesystem is relative to {@link
+ javax.servlet.MultipartConfigElement#getLocation()}. Absolute
+ paths are used as provided and are relative to
+ <code>getLocation()</code>. Note: that this is a system
+ dependent string and URI notation may not be acceptable on all
+ systems. For portability, this string should be generated with
+ the File or Path APIs.
+ *
+ * @throws IOException if an error occurs.
+ */
+ public void write(String fileName) throws IOException;
+
+ /**
+ * Deletes the underlying storage for a file item, including deleting any
+ * associated temporary disk file.
+ *
+ * @throws IOException if an error occurs.
+ */
+ public void delete() throws IOException;
+
+ /**
+ *
+ * Returns the value of the specified mime header
+ * as a <code>String</code>. If the Part did not include a header
+ * of the specified name, this method returns <code>null</code>.
+ * If there are multiple headers with the same name, this method
+ * returns the first header in the part.
+ * The header name is case insensitive. You can use
+ * this method with any request header.
+ *
+ * @param name a <code>String</code> specifying the
+ * header name
+ *
+ * @return a <code>String</code> containing the
+ * value of the requested
+ * header, or <code>null</code>
+ * if the part does not
+ * have a header of that name
+ */
+ public String getHeader(String name);
+
+ /**
+ * Gets the values of the Part header with the given name.
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>Part</code>.
+ *
+ * <p>Part header names are case insensitive.
+ *
+ * @param name the header name whose values to return
+ *
+ * @return a (possibly empty) <code>Collection</code> of the values of
+ * the header with the given name
+ */
+ public Collection<String> getHeaders(String name);
+
+ /**
+ * Gets the header names of this Part.
+ *
+ * <p>Some servlet containers do not allow
+ * servlets to access headers using this method, in
+ * which case this method returns <code>null</code>
+ *
+ * <p>Any changes to the returned <code>Collection</code> must not
+ * affect this <code>Part</code>.
+ *
+ * @return a (possibly empty) <code>Collection</code> of the header
+ * names of this Part
+ */
+ public Collection<String> getHeaderNames();
+
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/PushBuilder.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/PushBuilder.java
new file mode 100644
index 0000000..08c68cd
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/PushBuilder.java
@@ -0,0 +1,279 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+import java.util.Set;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Build a request to be pushed.
+ *
+ * According section 8.2 of RFC 7540, a promised request must be cacheable and
+ * safe without a request body.
+ *
+ * <p>A PushBuilder is obtained by calling {@link
+ * HttpServletRequest#newPushBuilder()}. Each call to this method will
+ * a new instance of a PushBuilder based off the current {@code
+ * HttpServletRequest}, or null. Any mutations to the returned PushBuilder are
+ * not reflected on future returns.</p>
+ *
+ * <p>The instance is initialized as follows:</p>
+ *
+ * <ul>
+ *
+ * <li>The method is initialized to "GET"</li>
+ *
+ * <li>The existing request headers of the current {@link HttpServletRequest}
+ * are added to the builder, except for:
+ *
+ * <ul>
+ * <li>Conditional headers (defined in RFC 7232)
+ * <li>Range headers
+ * <li>Expect headers
+ * <li>Authorization headers
+ * <li>Referrer headers
+ * </ul>
+ *
+ * </li>
+ *
+ * <li>If the request was authenticated, an Authorization header will
+ * be set with a container generated token that will result in equivalent
+ * Authorization for the pushed request.</li>
+ *
+ * <li>The session ID will be the value returned from {@link
+ * HttpServletRequest#getRequestedSessionId()}, unless {@link
+ * HttpServletRequest#getSession(boolean)} has previously been called to
+ * create a new {@link HttpSession} prior to the call to create the
+ * {@code PushBuilder}, in which case the new session ID will be used as
+ * the PushBuilder's requested session ID. Note that the session ID
+ * returned from the request can effectively come from one of two
+ * "sources": a cookie or the URL (as specified in {@link
+ * HttpServletRequest#isRequestedSessionIdFromCookie} and {@link
+ * HttpServletRequest#isRequestedSessionIdFromURL}, respectively). The
+ * session ID for the {@code PushBuilder} will also come from the same
+ * source as the request.</li>
+ *
+ * <li>The Referer(sic) header will be set to {@link
+ * HttpServletRequest#getRequestURL()} plus any {@link
+ * HttpServletRequest#getQueryString()} </li>
+ *
+ * <li>If {@link HttpServletResponse#addCookie(Cookie)} has been called
+ * on the associated response, then a corresponding Cookie header will be added
+ * to the PushBuilder, unless the {@link Cookie#getMaxAge()} is <=0, in which
+ * case the Cookie will be removed from the builder.</li>
+ *
+ * </ul>
+ *
+ * <p>The {@link #path} method must be called on the {@code PushBuilder}
+ * instance before the call to {@link #push}. Failure to do so must
+ * cause an exception to be thrown from {@link
+ * #push}, as specified in that method.</p>
+ *
+ * <p>A PushBuilder can be customized by chained calls to mutator
+ * methods before the {@link #push()} method is called to initiate an
+ * asynchronous push request with the current state of the builder.
+ * After the call to {@link #push()}, the builder may be reused for
+ * another push, however the implementation must make it so the {@link
+ * #path(String)} and conditional headers (defined in RFC 7232)
+ * values are cleared before returning from {@link #push}.
+ * All other values are retained over calls to {@link #push()}.
+ *
+ * @since Servlet 4.0
+ */
+public interface PushBuilder {
+ /**
+ * <p>Set the method to be used for the push.</p>
+ *
+ * @throws NullPointerException if the argument is {@code null}
+ *
+ * @throws IllegalArgumentException if the argument is the empty String,
+ * or any non-cacheable or unsafe methods defined in RFC 7231,
+ * which are POST, PUT, DELETE, CONNECT, OPTIONS and TRACE.
+ *
+ * @param method the method to be used for the push.
+ * @return this builder.
+ */
+ public PushBuilder method(String method);
+
+ /**
+ * Set the query string to be used for the push.
+ *
+ * The query string will be appended to any query String included in a call
+ * to {@link #path(String)}. Any duplicate parameters must be preserved.
+ * This method should be used instead of a query in {@link #path(String)}
+ * when multiple {@link #push()} calls are to be made with the same
+ * query string.
+ * @param queryString the query string to be used for the push.
+ * @return this builder.
+ */
+ public PushBuilder queryString(String queryString);
+
+ /**
+ * Set the SessionID to be used for the push.
+ * The session ID will be set in the same way it was on the associated request (ie
+ * as a cookie if the associated request used a cookie, or as a url parameter if
+ * the associated request used a url parameter).
+ * Defaults to the requested session ID or any newly assigned session id from
+ * a newly created session.
+ * @param sessionId the SessionID to be used for the push.
+ * @return this builder.
+ */
+ public PushBuilder sessionId(String sessionId);
+
+ /**
+ * <p>Set a request header to be used for the push. If the builder has an
+ * existing header with the same name, its value is overwritten.</p>
+ *
+ * @param name The header name to set
+ * @param value The header value to set
+ * @return this builder.
+ */
+ public PushBuilder setHeader(String name, String value);
+
+ /**
+ * <p>Add a request header to be used for the push.</p>
+ * @param name The header name to add
+ * @param value The header value to add
+ * @return this builder.
+ */
+ public PushBuilder addHeader(String name, String value);
+
+ /**
+ * <p>Remove the named request header. If the header does not exist, take
+ * no action.</p>
+ *
+ * @param name The name of the header to remove
+ * @return this builder.
+ */
+ public PushBuilder removeHeader(String name);
+
+ /**
+ * Set the URI path to be used for the push. The path may start
+ * with "/" in which case it is treated as an absolute path,
+ * otherwise it is relative to the context path of the associated
+ * request. There is no path default and {@link #path(String)} must
+ * be called before every call to {@link #push()}. If a query
+ * string is present in the argument {@code path}, its contents must
+ * be merged with the contents previously passed to {@link
+ * #queryString}, preserving duplicates.
+ *
+ * @param path the URI path to be used for the push, which may include a
+ * query string.
+ * @return this builder.
+ */
+ public PushBuilder path(String path);
+
+ /**
+ * Push a resource given the current state of the builder,
+ * the method must be non-blocking.
+ *
+ * <p>Push a resource based on the current state of the PushBuilder.
+ * Calling this method does not guarantee the resource will actually
+ * be pushed, since it is possible the client can decline acceptance
+ * of the pushed resource using the underlying HTTP/2 protocol.</p>
+ *
+ * <p>If the builder has a session ID, then the pushed request will
+ * include the session ID either as a Cookie or as a URI parameter
+ * as appropriate. The builders query string is merged with any
+ * passed query string.</p>
+ *
+ * <p>Before returning from this method, the builder has its path,
+ * conditional headers (defined in RFC 7232) nulled. All other fields
+ * are left as is for possible reuse in another push.</p>
+ *
+ * @throws IllegalStateException if there was no call to {@link
+ * #path} on this instance either between its instantiation or the
+ * last call to {@code push()} that did not throw an
+ * IllegalStateException.
+ */
+ public void push();
+
+ /**
+ * Return the method to be used for the push.
+ *
+ * @return the method to be used for the push.
+ */
+ public String getMethod();
+
+ /**
+ * Return the query string to be used for the push.
+ *
+ * @return the query string to be used for the push.
+ */
+ public String getQueryString();
+
+ /**
+ * Return the SessionID to be used for the push.
+ *
+ * @return the SessionID to be used for the push.
+ */
+ public String getSessionId();
+
+ /**
+ * Return the set of header to be used for the push.
+ *
+ * <p>The returned set is not backed by the {@code PushBuilder} object,
+ * so changes in the returned set are not reflected in the
+ * {@code PushBuilder} object, and vice-versa.</p>
+ *
+ * @return the set of header to be used for the push.
+ */
+ public Set<String> getHeaderNames();
+
+ /**
+ * Return the header of the given name to be used for the push.
+ * @param name the name of the header
+ *
+ * @return the header of the given name to be used for the push.
+ */
+ public String getHeader(String name);
+
+ /**
+ * Return the URI path to be used for the push.
+ *
+ * @return the URI path to be used for the push.
+ */
+ public String getPath();
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/WebConnection.java b/third_party/servlet-spec/src/main/java/javax/servlet/http/WebConnection.java
new file mode 100644
index 0000000..cf208d5
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/WebConnection.java
@@ -0,0 +1,73 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.servlet.http;
+
+import java.io.IOException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+
+/**
+ * This interface encapsulates the connection for an upgrade request.
+ * It allows the protocol handler to send service requests and status
+ * queries to the container.
+ *
+ * @since Servlet 3.1
+ */
+
+public interface WebConnection extends AutoCloseable {
+ /**
+ * Returns an input stream for this web connection.
+ *
+ * @return a ServletInputStream for reading binary data
+ *
+ * @exception IOException if an I/O error occurs
+ */
+ public ServletInputStream getInputStream() throws IOException;
+
+ /**
+ * Returns an output stream for this web connection.
+ *
+ * @return a ServletOutputStream for writing binary data
+ *
+ * @exception IOException if an I/O error occurs
+ */
+ public ServletOutputStream getOutputStream() throws IOException;
+}
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/http/package.html b/third_party/servlet-spec/src/main/java/javax/servlet/http/package.html
new file mode 100644
index 0000000..831ffad
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/http/package.html
@@ -0,0 +1,35 @@
+<!--
+
+ Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ Copyright 2004 The Apache Software Foundation
+
+ Licensed 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.
+
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+
+
+</HEAD>
+<BODY BGCOLOR="white">
+
+The javax.servlet.http package contains a number of classes and interfaces
+that describe and define the contracts between a servlet class
+running under the HTTP protocol and the runtime environment provided
+for an instance of such a class by a conforming servlet container.
+
+
+</BODY>
+</HTML>
diff --git a/third_party/servlet-spec/src/main/java/javax/servlet/package.html b/third_party/servlet-spec/src/main/java/javax/servlet/package.html
new file mode 100644
index 0000000..04d1e5a
--- /dev/null
+++ b/third_party/servlet-spec/src/main/java/javax/servlet/package.html
@@ -0,0 +1,35 @@
+<!--
+
+ Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ Copyright 2004 The Apache Software Foundation
+
+ Licensed 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.
+
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+
+
+</HEAD>
+<BODY BGCOLOR="white">
+
+The javax.servlet package contains a number of classes and interfaces that
+describe and define the contracts between a servlet class and the
+runtime environment provided for an instance of such a class by a
+conforming servlet container.
+
+
+</BODY>
+</HTML>
diff --git a/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-blank.graffle b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-blank.graffle
new file mode 100644
index 0000000..9818b37
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-blank.graffle
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ or LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<plist version="1.0">
+<dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>ApplicationVersion</key>
+ <array>
+ <string>com.omnigroup.OmniGrafflePro</string>
+ <string>139.16.0.171715</string>
+ </array>
+ <key>AutoAdjust</key>
+ <false/>
+ <key>BackgroundGraphic</key>
+ <dict>
+ <key>Bounds</key>
+ <string>{{0, 0}, {576, 753.9000244140625}}</string>
+ <key>Class</key>
+ <string>SolidGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <key>BaseZoom</key>
+ <integer>0</integer>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>CreationDate</key>
+ <string>2006-07-19 19:53:09 +0000</string>
+ <key>Creator</key>
+ <string>Edward Burns</string>
+ <key>DisplayScale</key>
+ <string>1 0/72 in = 1.0000 in</string>
+ <key>GraphDocumentVersion</key>
+ <integer>8</integer>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{31, 54.125}, {13, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>3</integer>
+ <key>Rotation</key>
+ <real>66</real>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510
+{\fonttbl\f0\fnil\fcharset0 AmericanTypewriter;}
+{\colortbl;\red255\green255\blue255;\red255\green242\blue230;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf2 }</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>HPages</key>
+ <integer>1</integer>
+ <key>ImageCounter</key>
+ <integer>1</integer>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>Animate</key>
+ <string>NO</string>
+ <key>circoMinDist</key>
+ <real>18</real>
+ <key>circoSeparation</key>
+ <real>0.0</real>
+ <key>layoutEngine</key>
+ <string>dot</string>
+ <key>neatoSeparation</key>
+ <real>0.0</real>
+ <key>twopiSeparation</key>
+ <real>0.0</real>
+ </dict>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array/>
+ <key>ModificationDate</key>
+ <string>2012-12-05 21:20:18 +0000</string>
+ <key>Modifier</key>
+ <string>Edward Burns</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>4.97998</string>
+ </array>
+ <key>NSHorizonalPagination</key>
+ <array>
+ <string>coded</string>
+ <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>size</string>
+ <string>{612, 792}</string>
+ </array>
+ <key>NSPrintAllPages</key>
+ <array>
+ <string>int</string>
+ <string>0</string>
+ </array>
+ <key>NSPrintReverseOrientation</key>
+ <array>
+ <string>int</string>
+ <string>0</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>33.12</string>
+ </array>
+ </dict>
+ <key>PrintOnePage</key>
+ <false/>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>UseEntirePage</key>
+ <true/>
+ <key>VPages</key>
+ <integer>1</integer>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <integer>0</integer>
+ <key>ExpandedCanvases</key>
+ <array/>
+ <key>Frame</key>
+ <string>{{78, 0}, {591, 828}}</string>
+ <key>ListView</key>
+ <false/>
+ <key>OutlineWidth</key>
+ <integer>142</integer>
+ <key>RightSidebar</key>
+ <false/>
+ <key>Sidebar</key>
+ <true/>
+ <key>SidebarWidth</key>
+ <integer>138</integer>
+ <key>VisibleRegion</key>
+ <string>{{0.5, 1}, {219.5, 359.5}}</string>
+ <key>Zoom</key>
+ <real>2</real>
+ <key>ZoomValues</key>
+ <array>
+ <array>
+ <string>Canvas 1</string>
+ <real>2</real>
+ <real>1.5</real>
+ </array>
+ </array>
+ </dict>
+</dict>
+</plist>
diff --git a/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-blank.png b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-blank.png
new file mode 100644
index 0000000..346a7d8
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-blank.png
Binary files differ
diff --git a/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-non-blank.graffle b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-non-blank.graffle
new file mode 100644
index 0000000..63b54c2
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-non-blank.graffle
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ or LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<plist version="1.0">
+<dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>ApplicationVersion</key>
+ <array>
+ <string>com.omnigroup.OmniGrafflePro</string>
+ <string>139.18.0.187838</string>
+ </array>
+ <key>AutoAdjust</key>
+ <false/>
+ <key>BackgroundGraphic</key>
+ <dict>
+ <key>Bounds</key>
+ <string>{{0, 0}, {578.800048828125, 754.800048828125}}</string>
+ <key>Class</key>
+ <string>SolidGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <key>BaseZoom</key>
+ <integer>0</integer>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>CreationDate</key>
+ <string>2006-07-19 19:53:09 +0000</string>
+ <key>Creator</key>
+ <string>Edward Burns</string>
+ <key>DisplayScale</key>
+ <string>1 0/72 in = 1.0000 in</string>
+ <key>GraphDocumentVersion</key>
+ <integer>8</integer>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{-28, 54.125}, {131, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>1</integer>
+ <key>Rotation</key>
+ <real>66</real>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 AmericanTypewriter;}
+{\colortbl;\red255\green255\blue255;\red170\green162\blue153;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf2 Expert Draft Version}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>HPages</key>
+ <integer>1</integer>
+ <key>ImageCounter</key>
+ <integer>1</integer>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>Animate</key>
+ <string>NO</string>
+ <key>circoMinDist</key>
+ <real>18</real>
+ <key>circoSeparation</key>
+ <real>0.0</real>
+ <key>layoutEngine</key>
+ <string>dot</string>
+ <key>neatoSeparation</key>
+ <real>0.0</real>
+ <key>twopiSeparation</key>
+ <real>0.0</real>
+ </dict>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array/>
+ <key>ModificationDate</key>
+ <string>2011-06-16 16:56:40 +0000</string>
+ <key>Modifier</key>
+ <string>Edward Burns</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>18.6</string>
+ </array>
+ <key>NSHorizonalPagination</key>
+ <array>
+ <string>coded</string>
+ <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>16.6</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>size</string>
+ <string>{612.00002479553223, 792}</string>
+ </array>
+ <key>NSPrintAllPages</key>
+ <array>
+ <string>int</string>
+ <string>0</string>
+ </array>
+ <key>NSPrintReverseOrientation</key>
+ <array>
+ <string>int</string>
+ <string>0</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>16.6</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>18.6</string>
+ </array>
+ </dict>
+ <key>PrintOnePage</key>
+ <false/>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>UseEntirePage</key>
+ <true/>
+ <key>VPages</key>
+ <integer>1</integer>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <integer>0</integer>
+ <key>ExpandedCanvases</key>
+ <array/>
+ <key>Frame</key>
+ <string>{{244, 0}, {591, 828}}</string>
+ <key>ListView</key>
+ <false/>
+ <key>OutlineWidth</key>
+ <integer>142</integer>
+ <key>RightSidebar</key>
+ <false/>
+ <key>Sidebar</key>
+ <true/>
+ <key>SidebarWidth</key>
+ <integer>138</integer>
+ <key>VisibleRegion</key>
+ <string>{{0.5, 2}, {219.5, 351.5}}</string>
+ <key>Zoom</key>
+ <real>2</real>
+ <key>ZoomValues</key>
+ <array>
+ <array>
+ <string>Canvas 1</string>
+ <real>2</real>
+ <real>1.5</real>
+ </array>
+ </array>
+ </dict>
+</dict>
+</plist>
diff --git a/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-non-blank.png b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-non-blank.png
new file mode 100644
index 0000000..714e00c
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg-non-blank.png
Binary files differ
diff --git a/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg.png b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg.png
new file mode 100644
index 0000000..497f46c
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/doc-files/expert-draft-bg.png
Binary files differ
diff --git a/third_party/servlet-spec/src/main/javadoc/doc-files/speclicense.html b/third_party/servlet-spec/src/main/javadoc/doc-files/speclicense.html
new file mode 100644
index 0000000..ceee9d7
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/doc-files/speclicense.html
@@ -0,0 +1,215 @@
+<html>
+<head>
+<title>Specification License</title>
+</head>
+<body>
+Specification: JSR-340 Java Servlet 3.1 Specification ("Specification")
+<br/>
+Version: 3.1
+<br/>
+Status: Final Release
+<br/>
+Specification Lead: Oracle America, Inc. ("Specification Lead")
+<br/>
+Release: April 2017
+<br/>
+
+<br/>
+Copyright © 2017 Oracle America, Inc.
+<br/>
+All rights reserved.
+<br/>
+<p>
+LIMITED LICENSE GRANTS
+<br/>
+1. License for Evaluation Purposes. Specification Lead hereby grants
+you a fully-paid, non-exclusive, non-transferable, worldwide, limited
+license (without the right to sublicense), under Specification Lead's
+applicable intellectual property rights to view, download, use and
+reproduce the Specification only for the purpose of internal
+evaluation. This includes (i) developing applications intended to run
+on an implementation of the Specification, provided that such
+applications do not themselves implement any portion(s) of the
+Specification, and (ii) discussing the Specification with any third
+party; and (iii) excerpting brief portions of the Specification in oral
+or written communications which discuss the Specification provided that
+such excerpts do not in the aggregate constitute a significant portion
+of the Specification.
+</p>
+<p>
+2. License for the Distribution of Compliant Implementations.
+Specification Lead also grants you a perpetual, non-exclusive,
+non-transferable, worldwide, fully paid-up, royalty free, limited
+license (without the right to sublicense) under any applicable
+copyrights or, subject to the provisions of subsection 4 below, patent
+rights it may have covering the Specification to create and/or
+distribute an Independent Implementation of the Specification that: (a)
+fully implements the Specification including all its required
+interfaces and functionality; (b) does not modify, subset, superset or
+otherwise extend the Licensor Name Space, or include any public or
+protected packages, classes, Java interfaces, fields or methods within
+the Licensor Name Space other than those required/authorized by the
+Specification or Specifications being implemented; and (c) passes the
+Technology Compatibility Kit (including satisfying the requirements of
+the applicable TCK Users Guide) for such Specification ("Compliant
+Implementation"). In addition, the foregoing license is expressly
+conditioned on your not acting outside its scope. No license is
+granted hereunder for any other purpose (including, for example,
+modifying the Specification, other than to the extent of your fair use
+rights, or distributing the Specification to third parties). Also, no
+right, title, or interest in or to any trademarks, service marks, or
+trade names of Specification Lead or Specification Lead's licensors is
+granted hereunder. Java, and Java-related logos, marks and names are
+trademarks or registered trademarks of Oracle America, Inc. in the U.S.
+and other countries.
+</p>
+<p>
+3. Pass-through Conditions. You need not include limitations (a)-(c)
+from the previous paragraph or any other particular "pass through"
+requirements in any license You grant concerning the use of your
+Independent Implementation or products derived from it. However,
+except with respect to Independent Implementations (and products
+derived from them) that satisfy limitations (a)-(c) from the previous
+paragraph, You may neither: (a) grant or otherwise pass through to
+your licensees any licenses under Specification Lead's applicable
+intellectual property rights; nor (b) authorize your licensees to make
+any claims concerning their implementation's compliance with the
+Specification in question.
+</p>
+<p>
+4. Reciprocity Concerning Patent Licenses.
+<br/>
+a. With respect to any patent claims covered by the license granted
+under subparagraph 2 above that would be infringed by all technically
+feasible implementations of the Specification, such license is
+conditioned upon your offering on fair, reasonable and
+non-discriminatory terms, to any party seeking it from You, a
+perpetual, non-exclusive, non-transferable, worldwide license under
+Your patent rights which are or would be infringed by all technically
+feasible implementations of the Specification to develop, distribute
+and use a Compliant Implementation.
+<br/>
+b. With respect to any patent claims owned by Specification Lead and
+covered by the license granted under subparagraph 2, whether or not
+their infringement can be avoided in a technically feasible manner when
+implementing the Specification, such license shall terminate with
+respect to such claims if You initiate a claim against Specification
+Lead that it has, in the course of performing its responsibilities as
+the Specification Lead, induced any other entity to infringe Your
+patent rights.
+<br/>
+c. Also with respect to any patent claims owned by Specification Lead
+and covered by the license granted under subparagraph 2 above, where
+the infringement of such claims can be avoided in a technically
+feasible manner when implementing the Specification such license, with
+respect to such claims, shall terminate if You initiate a claim against
+Specification Lead that its making, having made, using, offering to
+sell, selling or importing a Compliant Implementation infringes Your
+patent rights.
+</p>
+<p>
+5. Definitions. For the purposes of this Agreement: "Independent
+Implementation" shall mean an implementation of the Specification that
+neither derives from any of Specification Lead's source code or binary
+code materials nor, except with an appropriate and separate license
+from Specification Lead, includes any of Specification Lead's source
+code or binary code materials; "Licensor Name Space" shall mean the
+public class or interface declarations whose names begin with "java",
+"javax", "com.sun" and "com.oracle" or their equivalents in any
+subsequent naming convention adopted by Oracle America, Inc. through
+the Java Community Process, or any recognized successors or
+replacements thereof; and "Technology Compatibility Kit" or "TCK" shall
+mean the test suite and accompanying TCK User's Guide provided by
+Specification Lead which corresponds to the Specification and that was
+available either (i) from Specification Lead's 120 days before the
+first release of Your Independent Implementation that allows its use
+for commercial purposes, or (ii) more recently than 120 days from such
+release but against which You elect to test Your implementation of the
+Specification.
+</p>
+<p>
+This Agreement will terminate immediately without notice from
+Specification Lead if you breach the Agreement or act outside the scope
+of the licenses granted above.
+</p>
+<p>
+DISCLAIMER OF WARRANTIES
+<br/>
+THE SPECIFICATION IS PROVIDED "AS IS". SPECIFICATION LEAD MAKES NO
+REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE, NON-INFRINGEMENT (INCLUDING AS A CONSEQUENCE OF ANY PRACTICE
+OR IMPLEMENTATION OF THE SPECIFICATION), OR THAT THE CONTENTS OF THE
+SPECIFICATION ARE SUITABLE FOR ANY PURPOSE. This document does not
+represent any commitment to release or implement any portion of the
+Specification in any product. In addition, the Specification could
+include technical inaccuracies or typographical errors.
+</p>
+<p>
+LIMITATION OF LIABILITY
+<br/>
+TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SPECIFICATION
+LEAD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT
+LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT,
+CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED IN ANY
+WAY TO YOUR HAVING, IMPELEMENTING OR OTHERWISE USING USING THE
+SPECIFICATION, EVEN IF SPECIFICATION LEAD AND/OR ITS LICENSORS HAVE
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. You will indemnify,
+hold harmless, and defend Specification Lead and its licensors from any
+claims arising or resulting from: (i) your use of the Specification;
+(ii) the use or distribution of your Java application, applet and/or
+implementation; and/or (iii) any claims that later versions or releases
+of any Specification furnished to you are incompatible with the
+Specification provided to you under this license.
+</p>
+<p>
+RESTRICTED RIGHTS LEGEND
+<br/>
+U.S. Government: If this Specification is being acquired by or on
+behalf of the U.S. Government or by a U.S. Government prime contractor
+or subcontractor (at any tier), then the Government's rights in the
+Software and accompanying documentation shall be only as set forth in
+this license; this is in accordance with 48 C.F.R. 227.7201 through
+227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48
+C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).
+</p>
+<p>
+REPORT
+<br/>
+If you provide Specification Lead with any comments or suggestions
+concerning the Specification ("Feedback"), you hereby: (i) agree that
+such Feedback is provided on a non-proprietary and non-confidential
+basis, and (ii) grant Specification Lead a perpetual, non-exclusive,
+worldwide, fully paid-up, irrevocable license, with the right to
+sublicense through multiple levels of sublicensees, to incorporate,
+disclose, and use without limitation the Feedback for any purpose.
+</p>
+<p>
+GENERAL TERMS
+<br/>
+Any action related to this Agreement will be governed by California law
+and controlling U.S. federal law. The U.N. Convention for the
+International Sale of Goods and the choice of law rules of any
+jurisdiction will not apply.
+</p>
+<p>
+The Specification is subject to U.S. export control laws and may be
+subject to export or import regulations in other countries. Licensee
+agrees to comply strictly with all such laws and regulations and
+acknowledges that it has the responsibility to obtain such licenses to
+export, re-export or import as may be required after delivery to
+Licensee.
+</p>
+<p>
+This Agreement is the parties' entire agreement relating to its subject
+matter. It supersedes all prior or contemporaneous oral or written
+communications, proposals, conditions, representations and warranties
+and prevails over any conflicting or additional terms of any quote,
+order, acknowledgment, or other communication between the parties
+relating to its subject matter during the term of this Agreement. No
+modification to this Agreement will be binding, unless in writing and
+signed by an authorized representative of each party.
+</p>
+</body>
+</html>
diff --git a/third_party/servlet-spec/src/main/javadoc/javax.servlet-api.css b/third_party/servlet-spec/src/main/javadoc/javax.servlet-api.css
new file mode 100644
index 0000000..4062a9f
--- /dev/null
+++ b/third_party/servlet-spec/src/main/javadoc/javax.servlet-api.css
@@ -0,0 +1,641 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+
+@import url('resources/fonts/dejavu.css');
+
+/* background: url(doc-files/expert-draft-bg.png); */
+
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
+ font-size:14px;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4A6782;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4A6782;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+}
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:11px;
+ z-index:200;
+ margin-top:-9px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.topNav {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#dee3e9;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+ text-transform:uppercase;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+ text-transform:uppercase;
+}
+.navBarCell1Rev {
+ background-color:#F8981D;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:13px;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:12px;
+}
+.indexContainer h2 {
+ font-size:13px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:12px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Sans Mono',monospace;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #ededed;
+ background-color:#f8f8f8;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
+ width:100%;
+ border-left:1px solid #EEE;
+ border-right:1px solid #EEE;
+ border-bottom:1px solid #EEE;
+}
+.overviewSummary, .memberSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ height:16px;
+}
+.memberSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#4D7A97;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#4D7A97;
+ float:left;
+
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+ width:100%;
+}
+th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
+td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colLast, th.colOne, .constantsSummary th {
+ background:#dee3e9;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ white-space:nowrap;
+ font-size:13px;
+}
+td.colLast, th.colLast {
+ font-size:13px;
+}
+td.colOne, th.colOne {
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.overviewSummary td.colOne, .overviewSummary th.colOne,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colOne, .memberSummary th.colOne,
+.typeSummary td.colFirst{
+ width:25%;
+ vertical-align:top;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#EEEEFF;
+}
+.altColor {
+ background-color:#FFFFFF;
+}
+.rowColor {
+ background-color:#EEEEEF;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+
+div.block {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+
+td.colLast div {
+ padding-top:0px;
+}
+
+
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#474747;
+}
+.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
+.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
+.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+
+div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+
+div.contentContainer ul.blockList li.blockList h2{
+ padding-bottom:0px;
+}
+
+
+/* Change bars from http://www.geocities.com/hentaihelper/2atimlin.htm */
+
+/*
+ .changed_added_4_0 { cursor: url(doc-files/changed_added_4_0_cursor.cur), auto;
+ background: url(doc-files/changed_added_4_0.png);
+ padding-left:0.2em; border-left:solid;
+ border-left-width:thin; border-right:none;
+ border-top:none; border-bottom:none; border-color:green }
+
+ .changed_modified_4_0 { cursor: url(doc-files/changed_modified_4_0_cursor.cur), auto;
+ background: url(doc-files/changed_modified_4_0.png);
+ padding-left:0.2em; border-left:solid;
+ border-left-width:thin; border-right:none;
+ border-top:none; border-bottom:none; border-color:orange }
+
+ .changed_deleted_4_0 { cursor: url(doc-files/changed_deleted_4_0_cursor.cur), auto;
+ background: url(doc-files/changed_deleted_4_0.png);
+ padding-left:0.2em; border-left:solid;
+ border-left-width:thin; border-right:none;
+ border-top:none; border-bottom:none; border-color:red;
+ text-decoration: line-through; }
+
+*/
diff --git a/third_party/servlet-spec/src/main/resources/META-INF/MANIFEST.MF b/third_party/servlet-spec/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/servlet-spec/src/main/resources/META-INF/MANIFEST.MF
diff --git a/third_party/servlet-spec/src/main/resources/META-INF/README b/third_party/servlet-spec/src/main/resources/META-INF/README
new file mode 100644
index 0000000..56bb2b5
--- /dev/null
+++ b/third_party/servlet-spec/src/main/resources/META-INF/README
@@ -0,0 +1,49 @@
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+
+The empty MANIFEST.MF is needed because of the way we have configured maven-jar-plugin
+and maven-bundle-plugin to interact with each other. We may be able to avoid it now,
+but that will require some effort. I have filed [1] and hopefully I will have some time
+to fix it in future.
+
+Thanks,
+Sahoo
+
+[1] https://glassfish.dev.java.net/issues/show_bug.cgi?id=11422