diff --git a/README.md b/README.md
index cb9ddde3..b395a2c4 100644
--- a/README.md
+++ b/README.md
@@ -213,3 +213,5 @@ Rocket is licensed under either of the following, at your option:
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+The Rocket website source is licensed under [separate terms](site/README.md#license).
diff --git a/scripts/bump_version.sh b/scripts/bump_version.sh
index 36e42409..d91e127d 100755
--- a/scripts/bump_version.sh
+++ b/scripts/bump_version.sh
@@ -11,4 +11,5 @@ if [ -z ${1} ] || [ -z ${2} ]; then
fi
find . -name "*.toml" | xargs sed -i.bak "s/${1}/${2}/g"
+find site/ -name "*.md" | xargs sed -i.bak "s/${1}/${2}/g"
find . -name "*.bak" | xargs rm
diff --git a/site/LICENSE b/site/LICENSE
new file mode 100644
index 00000000..55b5b7e2
--- /dev/null
+++ b/site/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 3 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, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ {project} Copyright (C) {year} {fullname}
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU 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 Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/site/README.md b/site/README.md
new file mode 100644
index 00000000..ea5491b5
--- /dev/null
+++ b/site/README.md
@@ -0,0 +1,29 @@
+# Rocket Website Source
+
+This directory contains the source files for the content on [Rocket's
+website](https://rocket.rs).
+
+## Contents
+
+This directory contains the following:
+
+ * `index.toml` - Source data for the index (`/`).
+ * `news.toml` - Source data for the news page (`/news`).
+ * `overview.toml` - Source data for the overview page (`/overview`).
+ * `guide.md` - Index page for the guide (`/guide`).
+ * `news/*.md` - News articles linked to from `news.toml`.
+ * `guide/*.md` - Guide pages linked to from `guide.md`.
+
+## Guide
+
+The source files for the [Rocket Programming Guide](https://rocket.rs/guide/)
+can be found in the `guide/` directory. One exception is the root of the guide,
+which is `guide.md`.
+
+Cross-linking to pages in the guide is accomplished via absolute links rooted at
+`/guide/`. To link to the page whose source is at `guide/page.md` in this
+directory, for instance, link to `/guide/page`.
+
+# License
+
+The Rocket website source is licensed under the [GNU General Public License v3.0](LICENSE).
diff --git a/site/guide.md b/site/guide.md
new file mode 100644
index 00000000..3cd83139
--- /dev/null
+++ b/site/guide.md
@@ -0,0 +1,43 @@
+# The Rocket Programming Guide
+
+Welcome to Rocket!
+
+This is the official guide. It is designed to serve as a starting point to
+writing web application with Rocket and Rust. The guide is also designed to be a
+reference for experienced Rocket developers. This guide is conversational in
+tone. For concise and purely technical documentation, see the [API
+documentation](https://api.rocket.rs).
+
+The guide is split into several sections, each with a focus on a different
+aspect of Rocket. The sections are:
+
+ - **[Introduction](introduction/):** introduces Rocket and its philosophy.
+ - **[Quickstart](quickstart/):** presents the minimal steps necessary to
+ run your first Rocket application.
+ - **[Getting Started](getting-started/):** a gentle introduction to getting
+ your first Rocket application running.
+ - **[Overview](overview/):** describes the core concepts of Rocket.
+ - **[Requests](requests/):** discusses handling requests: control-flow,
+ parsing, and validating.
+ - **[Responses](responses/):** discusses generating responses.
+ - **[State](state/):** how to manage state in a Rocket application.
+ - **[Testing](testing/):** how to unit and integration test a Rocket
+ application.
+ - **[Pastebin](pastebin/):** a tutorial on how to create a pastebin with
+ Rocket.
+ - **[Conclusion](conclusion/):** concludes the guide and discusses next steps
+ for learning.
+
+## Getting Help
+
+The official community support channels are the `#rocket` IRC channel on the
+[Mozilla IRC Server](https://wiki.mozilla.org/IRC) at `irc.mozilla.org` and the
+bridged [Rocket room on
+Matrix](https://riot.im/app/#/room/#mozilla_#rocket:matrix.org). If you're not
+familiar with IRC, we recommend chatting through [Matrix via
+Riot](https://riot.im/app/#/room/#mozilla_#rocket:matrix.org) or via the [Kiwi
+web IRC client](https://kiwiirc.com/client/irc.mozilla.org/#rocket). You can
+learn more about IRC via Mozilla's [Getting Started with
+IRC](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Getting_Started_with_IRC)
+guide.
+
diff --git a/site/guide/conclusion.md b/site/guide/conclusion.md
new file mode 100644
index 00000000..d7d337a4
--- /dev/null
+++ b/site/guide/conclusion.md
@@ -0,0 +1,28 @@
+# Conclusion
+
+We hope you agree that Rocket is a refreshing take on web frameworks. As with
+any software project, Rocket is _alive_. There are always things to improve, and
+we're happy to take the best ideas. If you have something in mind, please
+[submit an issue](https://github.com/SergioBenitez/Rocket/issues).
+
+## Getting Help
+
+If you find yourself having trouble developing Rocket applications, you can get
+help via the `#rocket` IRC channel on the [Mozilla IRC
+Server](https://wiki.mozilla.org/IRC) at `irc.mozilla.org` and the bridged
+[Rocket room on Matrix](https://riot.im/app/#/room/#mozilla_#rocket:matrix.org).
+If you're not familiar with IRC, we recommend chatting through [Matrix via
+Riot](https://riot.im/app/#/room/#mozilla_#rocket:matrix.org) or via the [Kiwi
+web IRC client](https://kiwiirc.com/client/irc.mozilla.org/#rocket). You can
+learn more about IRC via Mozilla's [Getting Started with
+IRC](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Getting_Started_with_IRC)
+guide.
+
+## What's next?
+
+The best way to learn Rocket is to _build something_. It should be fun and easy,
+and there's always someone to help. Alternatively, you can read through the
+[Rocket examples](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples)
+or the [Rocket source
+code](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/lib/src). Whatever you
+decide to do next, we hope you have a blast!
diff --git a/site/guide/getting-started.md b/site/guide/getting-started.md
new file mode 100644
index 00000000..9b601608
--- /dev/null
+++ b/site/guide/getting-started.md
@@ -0,0 +1,95 @@
+# Getting Started
+
+Let's create and run our first Rocket application. We'll ensure we have a
+compatible version of Rust, create a new Cargo project that depends on Rocket,
+and then run the application.
+
+## Installing Rust
+
+Rocket makes abundant use of Rust's syntax extensions. Because syntax extensions
+don't yet have a stable compiler API, we'll need to use a nightly version of
+Rust. If you already have a working installation of the latest Rust nightly,
+feel free to skip to the next section.
+
+To install a nightly version of Rust, we recommend using `rustup`. Install
+`rustup` by following the instructions on [its website](https://rustup.rs/).
+Once `rustup` is installed, configure Rust nightly as your default toolchain by
+running the command:
+
+```sh
+rustup default nightly
+```
+
+If you prefer, once we setup a project directory in the following section, you
+can use per-directory overrides to use the nightly version _only_ for your
+Rocket project by running the following command in the directory:
+
+```sh
+rustup override set nightly
+```
+
+## Nightly Version
+
+Rocket requires the _latest_ version of Rust nightly to function. If your Rocket
+application suddently stops building, ensure you're using the latest version of
+Rust nightly and Rocket by updating your toolchain and dependencies with:
+
+```sh
+rustup update && cargo update
+```
+
+## Hello, world!
+
+Let's write our first Rocket application! Start by creating a new binary-based
+Cargo project and changing into the new directory:
+
+```sh
+cargo new hello-rocket --bin
+cd hello-rocket
+```
+
+Now, add Rocket and its code generation facilities as dependencies of your
+project by ensuring your `Cargo.toml` contains the following:
+
+```
+[dependencies]
+rocket = "0.2.5"
+rocket_codegen = "0.2.5"
+```
+
+Modify `src/main.rs` so that it contains the code for the Rocket `Hello, world!`
+program, which we reproduce below:
+
+```rust
+#![feature(plugin)]
+#![plugin(rocket_codegen)]
+
+extern crate rocket;
+
+#[get("/")]
+fn index() -> &'static str {
+ "Hello, world!"
+}
+
+fn main() {
+ rocket::ignite().mount("/", routes![index]).launch();
+}
+```
+
+We won't explain exactly what the program does now; we leave that for the rest
+of the guide. In short, it creates an `index` route, _mounts_ the route at the
+`/` path, and launches the application. Run the program with `cargo run`. You
+should see the following:
+
+```sh
+🔧 Configured for development.
+ => address: localhost
+ => port: 8000
+ => log: normal
+ => workers: {logical cores}
+🛰 Mounting '/':
+ => GET /
+🚀 Rocket has launched from http://localhost:8000...
+```
+
+Visit `http://localhost:8000` to see your first Rocket application in action!
diff --git a/site/guide/introduction.md b/site/guide/introduction.md
new file mode 100644
index 00000000..a49a9e2c
--- /dev/null
+++ b/site/guide/introduction.md
@@ -0,0 +1,43 @@
+# Introduction
+
+Rocket is a web framework for Rust. If you'd like, you can think of Rocket as
+being a more flexible, friendly medley of [Rails](http://rubyonrails.org),
+[Flask](http://flask.pocoo.org/),
+[Bottle](http://bottlepy.org/docs/dev/index.html), and
+[Yesod](http://www.yesodweb.com/). We prefer to think of Rocket as something
+new. Rocket aims to be fast, easy, and flexible. It also aims to be _fun_, and
+it accomplishes this by ensuring that you write as little code as needed to
+accomplish your task. This guide introduces you to the core, intermediate, and
+advanced concepts of Rocket. After reading this guide, you should find yourself
+being _very_ productive with Rocket.
+
+## Audience
+
+Readers are assumed to have a good grasp of the Rust programming language.
+Readers new to Rust are encouraged to read the [Rust
+Book](https://doc.rust-lang.org/book/). This guide also assumes a basic
+understanding of web application fundamentals, such as routing and HTTP.
+
+## Foreword
+
+Rocket's design is centered around three core philosophies:
+
+ * **Function declaration and parameter types should contain all the necessary
+ information to validate and process a request.** This immediately prohibits
+ APIs where request state is retrieved from a global context. As a result,
+ request handling is **self-contained** in Rocket: handlers are regular
+ functions with regular arguments.
+
+ * **All request handling information should be typed.** Because the web and
+ HTTP are themselves untyped (or _stringly_ typed, as some call it), this
+ means that something or someone has to convert strings to native types.
+ Rocket does this for you with zero programming overhead.
+
+ * **Decisions should not be forced.** Templates, serialization, sessions, and
+ just about everything else are all pluggable, optional components. While
+ Rocket has official support and libraries for each of these, they are
+ completely optional and swappable.
+
+These three ideas dictate Rocket's interface, and you will find the ideas
+embedded in Rocket's core features.
+
diff --git a/site/guide/overview.md b/site/guide/overview.md
new file mode 100644
index 00000000..53a7ef0c
--- /dev/null
+++ b/site/guide/overview.md
@@ -0,0 +1,317 @@
+# Overview
+
+Rocket provides primitives to build web servers and applications with Rust: the
+rest is up to you. In short, Rocket provides routing, pre-processing of
+requests, and post-processing of responses. Your application code instructs
+Rocket on what to pre-process and post-process and fills the gaps between
+pre-processing and post-processing.
+
+## Lifecycle
+
+Rocket's main task is to listen for incoming web requests, dispatch the request
+to the application code, and return a response to the client. We call the
+process that goes from request to response: the _lifecycle_. We summarize the
+lifecycle as the sequence of steps:
+
+ 1. **Routing**
+
+ Rocket parses an incoming HTTP request into native structures that your code
+ operates on indirectly. Rocket determines which request handler to invoke by
+ matching against route attributes declared by your application.
+
+ 2. **Validation**
+
+ Rocket validates the incoming request against types and request guards
+ present in the matched route. If validation fails, Rocket _forwards_ the
+ request to the next matching route or calls an _error handler_.
+
+ 3. **Processing**
+
+ The request handler associated with the route is invoked with validated
+ arguments. This is the main business logic of the application. Processing
+ completes by returning a `Response`.
+
+ 4. **Response**
+
+ The returned `Response` is processed. Rocket generates the appropriate HTTP
+ response and sends it to the client. This completes the lifecycle. Rocket
+ continues listening for requests, restarting the lifecycle for each incoming
+ request.
+
+The remainder of this section details the _routing_ phase as well as additional
+components needed for Rocket to begin dispatching requests to request handlers.
+The sections following describe the request and response phases.
+
+## Routing
+
+Rocket applications are centered around routes and handlers.
+
+A _handler_ is simply a function that takes an arbitrary number of arguments and
+returns any arbitrary type. A _route_ is a combination of:
+
+ * A set of parameters to match an incoming request against.
+ * A handler to process the request and return a response.
+
+The parameters to match against include static paths, dynamic paths, path
+segments, forms, query strings, request format specifiers, and body data. Rocket
+uses attributes, which look like function decorators in other languages, to make
+declaring routes easy. Routes are declared by annotating a function, the
+handler, with the set of parameters to match against. A complete route
+declaration looks like this:
+
+```rust
+#[get("/world")] // <- route attribute
+fn world() -> &'static str { // <- request handler
+ "Hello, world!"
+}
+```
+
+This declares the `world` route to match against the static path `"/world"` on
+incoming `GET` requests. The `world` route is simple, but additional route
+parameters are necessary when building more interesting applications. The
+[Requests](/guide/requests) section describes the available options for
+constructing routes.
+
+## Mounting
+
+Before Rocket can dispatch requests to a route, the route needs to be _mounted_.
+Mounting a route is like namespacing it. Routes are mounted via the `mount`
+method on a `Rocket` instance. Rocket instances can be created with the
+`ignite()` static method.
+
+The `mount` method takes **1)** a path to namespace a list of routes under, and
+**2)** a list of route handlers through the `routes!` macro. The `routes!` macro
+ties Rocket's code generation to your application.
+
+For instance, to mount the `world` route we declared above, we would use the
+following code:
+
+```rust
+rocket::ignite().mount("/hello", routes![world])
+```
+
+Altogether, this creates a new `Rocket` instance via the `ignite` function and
+mounts the `world` route to the `"/hello"` path. As a result, `GET` requests to
+the `"/hello/world"` path will be directed to the `world` function.
+
+### Namespacing
+
+When a route is declared inside a module other than the root, you may find
+yourself with unexpected errors when mounting:
+
+```rust
+mod other {
+ #[get("/world")]
+ pub fn world() -> &'static str {
+ "Hello, world!"
+ }
+}
+
+use other::world;
+
+fn main() {
+ // error[E0425]: cannot find value `static_rocket_route_info_for_world` in this scope
+ rocket::ignite().mount("/hello", routes![world])
+}
+```
+
+This occurs because the `routes!` macro implicitly converts the route's name
+into the name of a structure generated by Rocket's code generation. The solution
+is to name the route by a module path instead:
+
+```rust
+rocket::ignite().mount("/hello", routes![other::world])
+```
+
+## Launching
+
+Now that Rocket knows about the route, you can tell Rocket to start accepting
+requests via the `launch` method. The method starts up the server and waits for
+incoming requests. When a request arrives, Rocket finds the matching route and
+dispatches the request to the route's handler.
+
+We typically call `launch` from the `main` function. Our complete _Hello,
+world!_ application thus looks like:
+
+```rust
+#![feature(plugin)]
+#![plugin(rocket_codegen)]
+
+extern crate rocket;
+
+#[get("/world")]
+fn world() -> &'static str {
+ "Hello, world!"
+}
+
+fn main() {
+ rocket::ignite().mount("/hello", routes![world]).launch();
+}
+```
+
+Note that we've added the `#![feature(plugin)]` and `#![plugin(rocket_codegen)]`
+lines to tell Rust that we'll be using Rocket's code generation plugin. We've
+also imported the `rocket` crate into our namespace via `extern crate rocket`.
+Finally, we call the `launch` method in the `main` function.
+
+Running the application, the console shows:
+
+```sh
+🔧 Configured for development.
+ => address: localhost
+ => port: 8000
+ => log: normal
+ => workers: {logical cores}
+🛰 Mounting '/world':
+ => GET /hello/world
+🚀 Rocket has launched from http://localhost:8000...
+```
+
+If we visit `localhost:8000/hello/world`, we see `Hello, world!`, exactly as
+we expected.
+
+A version of this example's complete crate, ready to `cargo run`, can be found
+on
+[GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/hello_world).
+You can find dozens of other complete examples, spanning all of Rocket's
+features, in the [GitHub examples
+directory](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/).
+
+## Configuration
+
+At any point in time, a Rocket application is operating in a given
+_configuration environment_. There are three such environments:
+
+ * `development` (short: `dev`)
+ * `staging` (short: `stage`)
+ * `production` (short: `prod`)
+
+Without any action, Rocket applications run in the `development` environment.
+The environment can be changed via the `ROCKET_ENV` environment variable. For
+example, to launch the `Hello, world!` application in the `staging` environment,
+we can run:
+
+```sh
+ROCKET_ENV=stage cargo run
+```
+
+You'll likely need `sudo` for the command to succeed since `staging` defaults to
+listening on port `80`. Note that you can use the short or long form of the
+environment name to specify the environment, `stage` _or_ `staging` here. Rocket
+tells us the environment we have chosen and its configuration when it launches:
+
+```sh
+$ sudo ROCKET_ENV=staging cargo run
+
+🔧 Configured for staging.
+ => address: 0.0.0.0
+ => port: 80
+ => log: normal
+ => workers: {logical cores}
+🛰 Mounting '/':
+ => GET /
+🚀 Rocket has launched from http://0.0.0.0:80...
+```
+
+Configuration settings can be changed in one of two ways: via the `Rocket.toml`
+configuration file, or via environment variables.
+
+### Configuration File
+
+A `Rocket.toml` file can be used to specify the configuration parameters for
+each environment. The file is optional. If it is not present, the default
+configuration parameters are used.
+
+The file must be a series of TOML tables, at most one for each environment and
+an optional "global" table, where each table contains key-value pairs
+corresponding to configuration parameters for that environment. If a
+configuration parameter is missing, the default value is used. The following is
+a complete `Rocket.toml` file, where every standard configuration parameter is
+specified with the default value:
+
+```toml
+[development]
+address = "localhost"
+port = 8000
+workers = max(number_of_cpus, 2)
+log = "normal"
+
+[staging]
+address = "0.0.0.0"
+port = 80
+workers = max(number_of_cpus, 2)
+log = "normal"
+
+[production]
+address = "0.0.0.0"
+port = 80
+workers = max(number_of_cpus, 2)
+log = "critical"
+```
+
+The `workers` parameter is computed by Rocket automatically; the value above is
+not valid TOML syntax.
+
+The "global" pseudo-environment can be used to set and/or override configuration
+parameters globally. A parameter defined in a `[global]` table sets, or
+overrides if already present, that parameter in every environment. For example,
+given the following `Rocket.toml` file, the value of `address` will be
+`"1.2.3.4"` in every environment:
+
+```toml
+[global]
+address = "1.2.3.4"
+
+[development]
+address = "localhost"
+
+[production]
+address = "0.0.0.0"
+```
+
+### Extras
+
+In addition to overriding default configuration parameters, a configuration file
+can also define values for any number of _extra_ configuration parameters. While
+these parameters aren't used by Rocket directly, other libraries, or your own
+application, can use them as they wish. As an example, the
+[Template](https://api.rocket.rs/rocket_contrib/struct.Template.html) type
+accepts a value for the `template_dir` configuration parameter. The parameter
+can be set in `Rocket.toml` as follows:
+
+```toml
+[development]
+template_dir = "dev_templates/"
+
+[production]
+template_dir = "prod_templates/"
+```
+
+This sets the `template_dir` extra configuration parameter to `"dev_templates/"`
+when operating in the `development` environment and `"prod_templates/"` when
+operating in the `production` environment. Rocket will prepend the `[extra]` tag
+to extra configuration parameters when launching:
+
+```sh
+🔧 Configured for development.
+ => ...
+ => [extra] template_dir: "dev_templates/"
+```
+
+### Environment Variables
+
+All configuration parameters, including extras, can be overridden through
+environment variables. To override the configuration parameter `{param}`, use an
+environment variable named `ROCKET_{PARAM}`. For instance, to override the
+"port" configuration parameter, you can run your application with:
+
+```sh
+ROCKET_PORT=3721 cargo run
+
+🔧 Configured for staging.
+ => ...
+ => port: 3721
+```
+
+Environment variables take precedence over all other configuration methods: if a
+variable is set, it will be used as that parameter's value.
diff --git a/site/guide/pastebin.md b/site/guide/pastebin.md
new file mode 100644
index 00000000..adf440f3
--- /dev/null
+++ b/site/guide/pastebin.md
@@ -0,0 +1,405 @@
+# Pastebin
+
+To give you a taste of what a real Rocket application looks like, this section
+of the guide is a tutorial on how to create a Pastebin application in Rocket. A
+pastebin is a simple web application that allows users to upload a text document
+and later retrieve it via a special URL. They're often used to share code
+snippets, configuration files, and error logs. In this tutorial, we'll build a
+simple pastebin service that allows users to upload a file from their terminal.
+The service will respond back with a URL to the uploaded file.
+
+## Finished Product
+
+A souped-up, completed version of the application you're about to build is
+deployed live at [paste.rs](https://paste.rs). Feel free to play with the
+application to get a feel for how it works. For example, to upload a text
+document named `test.txt`, you can do:
+
+```sh
+curl --data-binary @test.txt https://paste.rs/
+# => https://paste.rs/IYu
+```
+
+The finished product is composed of the following routes:
+
+ * index: **GET /** - returns a simple HTML page with instructions about how
+ to use the service
+ * upload: **POST /** - accepts raw data in the body of the request and
+ responds with a URL of a page containing the body's content
+ * retrieve: **GET /<id>** - retrieves the content for the paste with id
+ ``
+
+## Getting Started
+
+Let's get started! First, create a fresh Cargo binary project named
+`rocket-pastebin`:
+
+```rust
+cargo new --bin rocket-pastebin
+cd rocket-pastebin
+```
+
+Then add the usual Rocket dependencies to the `Cargo.toml` file:
+
+```toml
+[dependencies]
+rocket = "0.2.5"
+rocket_codegen = "0.2.5"
+```
+
+And finally, create a skeleton Rocket application to work off of in
+`src/main.rs`:
+
+```rust
+#![feature(plugin)]
+#![plugin(rocket_codegen)]
+
+extern crate rocket;
+
+fn main() {
+ rocket::ignite().launch()
+}
+```
+
+Ensure everything works by running the application:
+
+```sh
+cargo run
+```
+
+At this point, we haven't declared any routes or handlers, so visiting any page
+will result in Rocket returning a **404** error. Throughout the rest of the
+tutorial, we'll create the three routes and accompanying handlers.
+
+## Index
+
+The first route we'll create is the `index` route. This is the page users will
+see when they first visit the service. As such, the route should field requests
+of the form `GET /`. We declare the route and its handler by adding the `index`
+function below to `src/main.rs`:
+
+```rust
+#[get("/")]
+fn index() -> &'static str {
+ "
+ USAGE
+
+ POST /
+
+ accepts raw data in the body of the request and responds with a URL of
+ a page containing the body's content
+
+ GET /
+
+ retrieves the content for the paste with id ``
+ "
+}
+```
+
+This declares the `index` route for requests to `GET /` as returning a static
+string with the specified contents. Rocket will take the string and return it as
+the body of a fully formed HTTP response with `Content-Type: text/plain`. You
+can read more about how Rocket formulates responses at the [API documentation
+for the Responder
+ trait](https://api.rocket.rs/rocket/response/trait.Responder.html).
+
+Remember that routes first need to be mounted before Rocket dispatches requests
+to them. To mount the `index` route, modify the main function so that it reads:
+
+```rust
+fn main() {
+ rocket::ignite().mount("/", routes![index]).launch()
+}
+```
+
+You should now be able to `cargo run` the application and visit the root path
+(`/`) to see the text being displayed.
+
+## Uploading
+
+The most complicated aspect of the pastebin, as you might imagine, is handling
+upload requests. When a user attempts to upload a pastebin, our service needs to
+generate a unique ID for the upload, read the data, write it out to a file or
+database, and then return a URL with the ID. We'll take each of these one step
+at a time, beginning with generating IDs.
+
+### Unique IDs
+
+Generating a unique and useful ID is an interesting topic, but it is outside the
+scope of this tutorial. Instead, we simply provide the code for a `PasteID`
+structure that represents a _probably_ unique ID. Read through the code, then
+copy/paste it into a new file named `paste_id.rs` in the `src/` directory:
+
+```rust
+use std::fmt;
+use std::borrow::Cow;
+
+use rand::{self, Rng};
+
+/// Table to retrieve base62 values from.
+const BASE62: &'static [u8] = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+/// A _probably_ unique paste ID.
+pub struct PasteID<'a>(Cow<'a, str>);
+
+impl<'a> PasteID<'a> {
+ /// Generate a _probably_ unique ID with `size` characters. For readability,
+ /// the characters used are from the sets [0-9], [A-Z], [a-z]. The
+ /// probability of a collision depends on the value of `size`. In
+ /// particular, the probability of a collision is 1/62^(size).
+ pub fn new(size: usize) -> PasteID<'static> {
+ let mut id = String::with_capacity(size);
+ let mut rng = rand::thread_rng();
+ for _ in 0..size {
+ id.push(BASE62[rng.gen::() % 62] as char);
+ }
+
+ PasteID(Cow::Owned(id))
+ }
+}
+
+impl<'a> fmt::Display for PasteID<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.0)
+ }
+}
+```
+
+Then, in `src/main.rs`, add the following after `extern crate rocket`:
+
+```rust
+extern crate rand;
+
+mod paste_id;
+
+use paste_id::PasteID;
+```
+
+Finally, add a dependency for the `rand` crate to the `Cargo.toml` file:
+
+```toml
+[dependencies]
+# existing Rocket dependencies...
+rand = "0.3"
+```
+
+Then, ensure that your application builds with the new code:
+
+```sh
+cargo build
+```
+
+You'll likely see many "unused" warnings for the new code we've added: that's
+okay and expected. We'll be using the new code soon.
+
+### Processing
+
+Believe it or not, the hard part is done! (_whew!_).
+
+To process the upload, we'll need a place to store the uploaded files. To
+simplify things, we'll store the uploads in a directory named `uploads/`. Create
+an `upload` directory next to the `src` directory:
+
+```sh
+mkdir upload
+```
+
+For the `upload` route, we'll need to `use` a few items:
+
+```rust
+use std::io;
+use std::path::Path;
+
+use rocket::Data;
+```
+
+The [Data](https://api.rocket.rs/rocket/data/struct.Data.html) structure is key
+here: it represents an unopened stream to the incoming request body data. We'll
+use it to efficiently stream the incoming request to a file.
+
+### Upload Route
+
+We're finally ready to write the `upload` route. Before we show you the code,
+you should attempt to write the route yourself. Here's a hint: a possible route
+and handler signature look like this:
+
+```rust
+#[post("/", data = "")]
+fn upload(paste: Data) -> io::Result
+```
+
+Your code should:
+
+ 1. Create a new `PasteID` of a length of your choosing.
+ 2. Construct a filename inside `upload/` given the `PasteID`.
+ 3. Stream the `Data` to the file with the constructed filename.
+ 4. Construct a URL given the `PasteID`.
+ 5. Return the URL to the client.
+
+Here's our version (in `src/main.rs`):
+
+```rust
+#[post("/", data = "")]
+fn upload(paste: Data) -> io::Result {
+ let id = PasteID::new(3);
+ let filename = format!("upload/{id}", id = id);
+ let url = format!("{host}/{id}\n", host = "http://localhost:8000", id = id);
+
+ // Write the paste out to the file and return the URL.
+ paste.stream_to_file(Path::new(&filename))?;
+ Ok(url)
+}
+```
+
+Make sure that the route is mounted at the root path:
+
+```rust
+fn main() {
+ rocket::ignite().mount("/", routes![index, upload]).launch()
+}
+```
+
+Test that your route works via `cargo run`. From a separate terminal, upload a
+file using `curl`. Then verify that the file was saved to the `upload` directory
+with the correct ID:
+
+```sh
+# in the project root
+cargo run
+
+# in a seperate terminal
+echo "Hello, world." | curl --data-binary @- http://localhost:8000
+# => http://localhost:8000/eGs
+
+# back to the terminal running the pastebin
+ # kill running process
+ls upload # ensure the upload is there
+cat upload/* # ensure that contents are correct
+```
+
+Note that since we haven't created a `GET /` route, visting the returned URL
+will result in a **404**. We'll fix that now.
+
+## Retrieving Pastes
+
+The final step is to create the `retrieve` route which, given an ``, will
+return the corresponding paste if it exists.
+
+Here's a first take at implementing the `retrieve` route. The route below takes
+in an `` as a dynamic path element. The handler uses the `id` to construct a
+path to the paste inside `upload/`, and then attempts to open the file at that
+path, optionally returning the `File` if it exists. Rocket treats a `None`
+[Responder](https://api.rocket.rs/rocket/response/trait.Responder.html#provided-implementations)
+as a **404** error, which is exactly what we want to return when the requested
+paste doesn't exist.
+
+```rust
+use std::fs::File;
+
+#[get("/")]
+fn retrieve(id: &str) -> Option {
+ let filename = format!("upload/{id}", id = id);
+ File::open(&filename).ok()
+}
+```
+
+Unfortunately, there's a problem with this code. Can you spot the issue?
+
+The issue is that the _user_ controls the value of `id`, and as a result, can
+coerce the service into opening files inside `upload/` that aren't meant to be
+opened. For instance, imagine that you later decide that a special file
+`upload/_credentials.txt` will store some important, private information. If the
+user issues a `GET` request to `/_credentials.txt`, the server will read and
+return the `upload/_credentials.txt` file, leaking the sensitive information.
+This is a big problem; it's known as the [full path disclosure
+attack](https://www.owasp.org/index.php/Full_Path_Disclosure), and Rocket
+provides the tools to prevent this and other kinds of attacks from happening.
+
+To prevent the attack, we need to _validate_ `id` before we use it. Since the
+`id` is a dynamic parameter, we can use Rocket's
+[FromParam](https://api.rocket.rs/rocket/request/trait.FromParam.html) trait to
+implement the validation and ensure that the `id` is a valid `PasteID` before
+using it. We do this by implementing `FromParam` for `PasteID` in
+`src/paste_id.rs`, as below:
+
+```rust
+use rocket::request::FromParam;
+
+/// Returns `true` if `id` is a valid paste ID and `false` otherwise.
+fn valid_id(id: &str) -> bool {
+ id.chars().all(|c| {
+ (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ })
+}
+
+/// Returns an instance of `PasteID` if the path segment is a valid ID.
+/// Otherwise returns the invalid ID as the `Err` value.
+impl<'a> FromParam<'a> for PasteID<'a> {
+ type Error = &'a str;
+
+ fn from_param(param: &'a str) -> Result, &'a str> {
+ match valid_id(param) {
+ true => Ok(PasteID(Cow::Borrowed(param))),
+ false => Err(param)
+ }
+ }
+}
+```
+
+Then, we simply need to change the type of `id` in the handler to `PasteID`.
+Rocket will then ensure that `` represents a valid `PasteID` before calling
+the `retrieve` route, preventing attacks on the `retrieve` route:
+
+```rust
+#[get("/")]
+fn retrieve(id: PasteID) -> Option {
+ let filename = format!("upload/{id}", id = id);
+ File::open(&filename).ok()
+}
+```
+
+Note that our `valid_id` function is simple and could be improved by, for
+example, checking that the length of the `id` is within some known bound or
+potentially blacklisting sensitive files as needed.
+
+The wonderful thing about using `FromParam` and other Rocket traits is that they
+centralize policies. For instance, here, we've centralized the policy for valid
+`PasteID`s in dynamic parameters. At any point in the future, if other routes
+are added that require a `PasteID`, no further work has to be done: simply use
+the type in the signature and Rocket takes care of the rest.
+
+## Conclusion
+
+That's it! Ensure that all of your routes are mounted and test your application.
+You've now written a simple (~75 line!) pastebin in Rocket! There are many
+potential improvements to this small application, and we encourage you to work
+through some of them to get a better feel for Rocket. Here are some ideas:
+
+ * Add a web form to the `index` where users can manually input new pastes.
+ Accept the form at `POST /`. Use `format` and/or `rank` to specify which of
+ the two `POST /` routes should be called.
+ * Support **deletion** of pastes by adding a new `DELETE /` route. Use
+ `PasteID` to validate ``.
+ * **Limit the upload** to a maximum size. If the upload exceeds that size,
+ return a **206** partial status code. Otherwise, return a **201** created
+ status code.
+ * Set the `Content-Type` of the return value in `upload` and `retrieve` to
+ `text/plain`.
+ * **Return a unique "key"** after each upload and require that the key is
+ present and matches when doing deletion. Use one of Rocket's core traits to
+ do the key validation.
+ * Add a `PUT /` route that allows a user with the key for `` to
+ replace the existing paste, if any.
+ * Add a new route, `GET //` that syntax highlights the paste with ID
+ `` for language ``. If `` is not a known language, do no
+ highlighting. Possibly validate `` with `FromParam`.
+ * Use the [testing module](https://api.rocket.rs/rocket/testing/) to write
+ unit tests for your pastebin.
+ * Dispatch a thread before `launch`ing Rocket in `main` that periodically
+ cleans up idling old pastes in `upload/`.
+
+You can find the full source code for the completed pastebin tutorial in the
+[Rocket Github
+Repo](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/pastebin).
diff --git a/site/guide/quickstart.md b/site/guide/quickstart.md
new file mode 100644
index 00000000..0bcbba9e
--- /dev/null
+++ b/site/guide/quickstart.md
@@ -0,0 +1,21 @@
+# Quickstart
+
+Rocket requires a recent nightly version of Rust. We recommend you use
+[rustup](https://rustup.rs/) to install or configure such a version. If you
+don't have Rust installed, the [getting started](/guide/getting-started) section
+guides you through installing Rust.
+
+## Running Examples
+
+The absolute fastest way to start experimenting with Rocket is to clone the
+Rocket repository and run the included examples in the `examples/` directory.
+For instance, the following set of commands runs the `hello_world` example:
+
+```sh
+git clone https://github.com/SergioBenitez/rocket
+cd rocket/examples/hello_world
+cargo run
+```
+
+There are numerous examples. They can all be run with `cargo run`.
+
diff --git a/site/guide/requests.md b/site/guide/requests.md
new file mode 100644
index 00000000..4225f0dd
--- /dev/null
+++ b/site/guide/requests.md
@@ -0,0 +1,378 @@
+# Requests
+
+If all we could do was match against static paths like `"/world"`, Rocket
+wouldn't be much fun. Of course, Rocket allows you to match against just about
+any information in an incoming request. This section describes the available
+options and their effect on the application.
+
+## Methods
+
+A Rocket route attribute can be any one of `get`, `put`, `post`, `delete`,
+`head`, `patch`, or `options`, each corresponding to the HTTP method to match
+against. For example, the following attribute will match against `POST` requests
+to the root path:
+
+```rust
+#[post("/")]
+```
+
+The grammar for these routes is defined formally in the
+[rocket_codegen](https://api.rocket.rs/rocket_codegen/) API docs.
+
+Rocket handles `HEAD` requests automatically when there exists a `GET` route
+that would otherwise match. It does this by stripping the body from the
+response, if there is one. You can also specialize the handling of a `HEAD`
+request by declaring a route for it; Rocket won't interfere with `HEAD` requests
+your application handles.
+
+Because browsers only send `GET` and `POST` requests, Rocket _reinterprets_
+requests under certain conditions. If a `POST` request contains a body of
+`Content-Type: application/x-www-form-urlencoded`, and the form's **first**
+field has the name `_method` and a valid HTTP method as its value, that field's
+value is used as the method for the incoming request. This allows Rocket
+applications to submit non-`POST` forms. The [todo
+example](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/todo/static/index.html.tera#L47)
+makes use of this feature to submit `PUT` and `DELETE` requests from a web form.
+
+## Format
+
+When receiving data, you can specify the Content-Type the route matches against
+via the `format` route parameter. The parameter is a string of the Content-Type
+expected. For example, to match `application/json` data, a route can be declared
+as:
+
+```rust
+#[post("/user", format = "application/json", data = "")]
+fn new_user(user: JSON) -> T { ... }
+```
+
+Note the `format` parameter in the `post` attribute. The `data` parameter is
+described later in the [data](#data) section.
+
+## Dynamic Paths
+
+You can declare path segments as dynamic by using angle brackets around variable
+names in a route's path. For example, if we wanted to say _Hello!_ to anything,
+not just the world, we could declare a route and handler like so:
+
+```rust
+#[get("/hello/")]
+fn hello(name: &str) -> String {
+ format!("Hello, {}!", name)
+}
+```
+
+If we were to mount the path at the root (`.mount("/", routes![hello])`), then
+any request to a path with two non-empty segments, where the first segment is
+`hello`, will be dispatched to the `hello` route. For example, if we were to
+visit `/hello/John`, the application would respond with `Hello, John!`.
+
+You can have any number of dynamic path segments, and the type of the path
+segment can be any type that implements the [FromParam
+trait](https://api.rocket.rs/rocket/request/trait.FromParam.html), including
+your own! Rocket implements `FromParam` for many of the standard library types,
+as well as a few special Rocket types. Here's a somewhat complicated route to
+illustrate varied usage:
+
+```rust
+#[get("/hello///")]
+fn hello(name: &str, age: u8, cool: bool) -> String {
+ if cool {
+ format!("You're a cool {} year old, {}!", age, name)
+ } else {
+ format!("{}, we need to talk about your coolness.", name)
+ }
+}
+```
+
+## Forwarding
+
+In this example above, what if `cool` isn't a `bool`? Or, what if `age` isn't a
+`u8`? In this case, the request is _forwarded_ to the next matching route, if
+there is any. This continues until a route doesn't forward the request or there
+are no remaining routes to try. When there are no remaining matching routes, a
+customizable **404 error** is returned.
+
+Routes are tried in increasing _rank_ order. By default, routes with static
+paths have a rank of 0 and routes with dynamic paths have a rank of 1. A route's
+rank can be manually set with the `rank` route parameter.
+
+To illustrate, consider the following routes:
+
+```rust
+#[get("/user/")]
+fn user(id: usize) -> T { ... }
+
+#[get("/user/", rank = 2)]
+fn user_int(id: isize) -> T { ... }
+
+#[get("/user/", rank = 3)]
+fn user_str(id: &str) -> T { ... }
+```
+
+Notice the `rank` parameters in `user_int` and `user_str`. If we run this
+application with the routes mounted at the root, requests to `/user/` will
+be routed as follows:
+
+ 1. The `user` route matches first. If the string at the `` position is an
+ unsigned integer, then the `user` handler is called. If it is not, then the
+ request is forwarded to the next matching route: `user_int`.
+
+ 2. The `user_int` route matches next. If `` is a signed integer,
+ `user_int` is called. Otherwise, the request is forwarded.
+
+ 3. The `user_str` route matches last. Since `` is a always string, the
+ route always matches. The `user_str` handler is called.
+
+Forwards can be _caught_ by using a `Result` or `Option` type. For example, if
+the type of `id` in the `user` function was `Result`, then `user`
+would never forward. An `Ok` variant would indicate that `` was a valid
+`usize`, while an `Err` would indicate that `` was not a `usize`. The
+`Err`'s value would contain the string that failed to parse as a `usize`.
+
+By the way, if you were to omit the `rank` parameter in the `user_str` or
+`user_int` routes, Rocket would emit a warning indicating that the routes
+_collide_, or can match against similar incoming requests. The `rank` parameter
+resolves this collision.
+
+## Dynamic Segments
+
+You can also match against multiple segments by using `` in the route
+path. The type of such parameters, known as _segments_ parameters, can be any
+that implements
+[FromSegments](https://api.rocket.rs/rocket/request/trait.FromSegments.html).
+Segments parameters must be the final component of the path: any text after a
+segments parameter in a path will result in a compile-time error.
+
+As an example, the following route matches against all paths that begin with
+`/page/`:
+
+```rust
+#[get("/page/")]
+fn get_page(path: PathBuf) -> T { ... }
+```
+
+The path after `/page/` will be available in the `path` parameter. The
+`FromSegments` implementation for `PathBuf` ensures that `path` cannot lead to
+[path traversal attacks](https://www.owasp.org/index.php/Path_Traversal). With
+this, a safe and secure static file server can implemented in 4 lines:
+
+```rust
+#[get("/")]
+fn files(file: PathBuf) -> Option {
+ NamedFile::open(Path::new("static/").join(file)).ok()
+}
+```
+
+## Request Guards
+
+Sometimes we need data associated with a request that isn't a direct input.
+Headers and cookies are a good example of this: they simply tag along for the
+ride. Rocket makes retrieving and validating such information easy: simply add
+any number of parameters to the request handler with types that implement the
+[FromRequest](https://api.rocket.rs/rocket/request/trait.FromRequest.html)
+trait. If the data can be retrieved from the incoming request and validated, the
+handler is called. If it cannot, the handler isn't called, and the request is
+forwarded or terminated. In this way, these parameters act as _guards_: they
+protect the request handler from being called erroneously.
+
+For example, to retrieve cookies and the Content-Type header from a request, we
+can declare a route as follows:
+
+```rust
+#[get("/")]
+fn index(cookies: &Cookies, content: ContentType) -> String { ... }
+```
+
+The [cookies example on
+GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/cookies)
+illustrates how to use the `Cookies` type to get and set cookies.
+
+You can implement `FromRequest` for your own types. For instance, to protect a
+`sensitive` route from running unless an `APIKey` is present in the request
+headers, you might create an `APIKey` type that implements `FromRequest` and use
+it as a request guard:
+
+```rust
+#[get("/sensitive")]
+fn sensitive(key: APIKey) -> &'static str { ... }
+```
+
+You might also implement `FromRequest` for an `AdminUser` type that validates
+that the cookies in the incoming request authenticate an administrator. Then,
+any handler with an `AdminUser` or `APIKey` type in its argument list is assured
+to only be invoked if the appropriate conditions are met. Request guards
+centralize policies, resulting in a simpler, safer, and more secure
+applications.
+
+## Data
+
+At some point, your web application will need to process body data, and Rocket
+makes it as simple as possible. Data processing, like much of Rocket, is type
+directed. To indicate that a handler expects data, annotate it with a `data =
+""` parameter, where `param` is an argument in the handler. The
+argument's type must implement the
+[FromData](https://api.rocket.rs/rocket/data/trait.FromData.html) trait. It
+looks like this, where `T: FromData`:
+
+```rust
+#[post("/", data = "")]
+fn new(input: T) -> String { ... }
+```
+
+### Forms
+
+Forms are the most common type of data handled in web applications, and Rocket
+makes handling them easy. Say your application is processing a form submission
+for a new todo `Task`. The form contains two fields: `complete`, a checkbox, and
+`description`, a text field. You can easily handle the form request in Rocket
+as follows:
+
+```rust
+#[derive(FromForm)]
+struct Task {
+ complete: bool,
+ description: String,
+}
+
+#[post("/todo", data = "")]
+fn new(task: Form) -> String { ... }
+```
+
+The `Form` type implements the `FromData` trait as long as its generic parameter
+implements the
+[FromForm](https://api.rocket.rs/rocket/request/trait.FromForm.html) trait. In
+the example, we've derived the `FromForm` trait automatically for the `Task`
+structure. `FromForm` can be derived for any structure whose fields implement
+[FromFormValue](https://api.rocket.rs/rocket/request/trait.FromFormValue.html).
+If a `POST /todo` request arrives, the form data will automatically be parsed
+into the `Task` structure. If the data that arrives isn't of the correct
+Content-Type, the request is forwarded. If the data doesn't parse or is simply
+invalid, a customizable `400 Bad Request` error is returned. As before, a
+forward or failure can be caught by using the `Option` and `Result` types.
+
+Fields of forms can be easily validated via implementations of the
+`FromFormValue` trait. For example, if you'd like to verify that some user is
+over some age in a form, then you might define a new `AdultAge` type, use it as
+a field in a form structure, and implement `FromFormValue` so that it only
+validates integers over that age. If a form is a submitted with a bad age,
+Rocket won't call a handler requiring a valid form for that structure. You can
+use `Option` or `Result` types for fields to catch parse failures.
+
+The [forms](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/forms)
+and [forms kitchen
+sink](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/form_kitchen_sink)
+examples on GitHub provide further illustrations.
+
+### JSON
+
+Handling JSON data is no harder: simply use the
+[JSON](https://api.rocket.rs/rocket_contrib/struct.JSON.html) type:
+
+```rust
+#[derive(Deserialize)]
+struct Task {
+ description: String,
+ complete: bool
+}
+
+#[post("/todo", data = "")]
+fn new(task: JSON) -> String { ... }
+```
+
+The only condition is that the generic type to `JSON` implements the
+`Deserialize` trait. See the [JSON example on
+GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/json) for a
+complete example.
+
+### Streaming
+
+Sometimes you just want to handle the incoming data directly. For example, you
+might want to stream the incoming data out to a file. Rocket makes this as
+simple as possible via the
+[Data](https://api.rocket.rs/rocket/data/struct.Data.html) type:
+
+```rust
+#[post("/upload", format = "text/plain", data = "")]
+fn upload(data: Data) -> io::Result> {
+ data.stream_to_file("/tmp/upload.txt").map(|n| Plain(n.to_string()))
+}
+```
+
+The route above accepts any `POST` request to the `/upload` path with
+`Content-Type` `text/plain` The incoming data is streamed out to
+`tmp/upload.txt` file, and the number of bytes written is returned as a plain
+text response if the upload succeeds. If the upload fails, an error response is
+returned. The handler above is complete. It really is that simple! See the
+[GitHub example
+code](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/raw_upload)
+for the full crate.
+
+## Query Strings
+
+Query strings are handled similarly to `POST` forms. A query string can be
+parsed into any structure that implements the `FromForm` trait. They are matched
+against by appending a `?` followed by a dynamic parameter `` to the
+path.
+
+For instance, say you change your mind and decide to use query strings instead
+of `POST` forms for new todo tasks in the previous forms example, reproduced
+below:
+
+```rust
+#[derive(FromForm)]
+struct Task { .. }
+
+#[post("/todo", data = "")]
+fn new(task: Form) -> String { ... }
+```
+
+Rocket makes the transition simple: simply declare `` as a query parameter
+as follows:
+
+```rust
+#[get("/todo?")]
+fn new(task: Task) -> String { ... }
+```
+
+Rocket will parse the query string into the `Task` structure automatically by
+matching the structure field names to the query parameters. If the parse fails,
+the request is forwarded to the next matching route. To catch parse failures,
+you can use `Option` or `Result` as the type of the field to catch errors for.
+
+See [the GitHub
+example](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/query_params)
+for a complete illustration.
+
+## Error Catchers
+
+When Rocket wants to return an error page to the client, Rocket invokes the
+_catcher_ for that error. A catcher is like a route, except it only handles
+errors. Catchers are declared via the `error` attribute, which takes a single
+integer corresponding to the HTTP status code to catch. For instance, to declare
+a catcher for **404** errors, you'd write:
+
+```rust
+#[error(404)]
+fn not_found(req: &Request) -> String { }
+```
+
+As with routes, Rocket needs to know about a catcher before it is used to handle
+errors. The process is similar to mounting: call the `catch` method with a list
+of catchers via the `errors!` macro. The invocation to add the **404** catcher
+declared above looks like this:
+
+```rust
+rocket::ignite().catch(errors![not_found])
+```
+
+Unlike request handlers, error handlers can only take 0, 1, or 2 parameters of
+types [Request](https://api.rocket.rs/rocket/struct.Request.html) and/or
+[Error](https://api.rocket.rs/rocket/enum.Error.html). At present, the `Error`
+type is not particularly useful, and so it is often omitted. The
+[error catcher
+example](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/errors) on
+GitHub illustrates their use in full.
+
+Rocket has a default catcher for all of the standard HTTP error codes including
+**404**, **500**, and more.
diff --git a/site/guide/responses.md b/site/guide/responses.md
new file mode 100644
index 00000000..6a9fb3f0
--- /dev/null
+++ b/site/guide/responses.md
@@ -0,0 +1,169 @@
+# Responses
+
+You may have noticed that the return type of a handler appears to be arbitrary,
+and that's because it is! A value of any type that implements the
+[Responder](https://api.rocket.rs/rocket/response/trait.Responder.html) trait
+can be returned, including your own.
+
+## Responder
+
+Types that implement `Responder` know how to generate a
+[Response](https://api.rocket.rs/rocket/response/struct.Response.html) from
+their values. A `Response` includes the HTTP status, headers, and body of the
+response. Rocket implements `Responder` for many built-in types including
+`String`, `&str`, `File`, `Option`, `Result`, and others. Rocket also provides
+custom types, such as
+[Content](https://api.rocket.rs/rocket/response/struct.Content.html) and
+[Flash](https://api.rocket.rs/rocket/response/struct.Flash.html), which you can
+find in the [response](https://api.rocket.rs/rocket/response/index.html) module.
+
+The body of a `Response` may either be _fixed-sized_ or _streaming_. The given
+`Responder` implementation decides which to use. For instance, `String` uses a
+fixed-sized body, while `File` uses a streaming body.
+
+### Wrapping
+
+Responders can _wrap_ other responders. That is, responders can be of the
+following form, where `R: Responder`:
+
+```rust
+struct WrappingResponder(R);
+```
+
+When this is the case, the wrapping responder will modify the response returned
+by `R` in some way before responding itself. For instance, to override the
+status code of some response, you can use the types in the [status
+module](https://api.rocket.rs/rocket/response/status/index.html). In particular,
+to set the status code of a response for a `String` to **202 Accepted**, you can
+return a type of `status::Accepted`:
+
+```rust
+#[get("/")]
+fn accept() -> status::Accepted {
+ status::Accepted(Some("I accept!".to_string()))
+}
+```
+
+By default, the `String` responder sets the status to **200**. By using the
+`Accepted` type however, The client will receive an HTTP response with status
+code **202**.
+
+Similarly, the types in the [content
+module](https://api.rocket.rs/rocket/response/content/index.html) can be used to
+override the Content-Type of the response. For instance, to set the Content-Type
+of some `&'static str` to JSON, you can use the
+[content::JSON](https://api.rocket.rs/rocket/response/content/struct.JSON.html)
+type as follows:
+
+```rust
+#[get("/")]
+fn json() -> content::JSON<&'static str> {
+ content::JSON("{ 'hi': 'world' }")
+}
+```
+
+## Errors
+
+Responders need not _always_ generate a response. Instead, they can return an
+`Err` with a given status code. When this happens, Rocket forwards the request
+to the error catcher for the given status code. If none exists, which can only
+happen when using custom status codes, Rocket uses the **500** error catcher.
+
+### Result
+
+`Result` is one of the most commonly used responders. Returning a `Result` means
+one of two things. If the error type implements `Responder`, the `Ok` or `Err`
+value will be used, whichever the variant is. If the error type does _not_
+implement `Responder`, the error is printed to the console, and the request is
+forwarded to the **500** error catcher.
+
+### Option
+
+`Option` is another commonly used responder. If the `Option` is `Some`, the
+wrapped responder is used to respond to the client. Otherwise, the request is
+forwarded to the **404** error catcher.
+
+### Failure
+
+While not encouraged, you can also forward a request to a catcher manually by
+using the [Failure](https://api.rocket.rs/rocket/response/struct.Failure.html)
+type. For instance, to forward to the catcher for **406 Not Acceptable**, you
+would write:
+
+```rust
+#[get("/")]
+fn just_fail() -> Failure {
+ Failure(Status::NotAcceptable)
+}
+```
+
+## JSON
+
+Responding with JSON data is simple: return a value of type
+[JSON](https://api.rocket.rs/rocket_contrib/struct.JSON.html). For example, to
+respond with the JSON value of the `Task` structure from previous examples, we
+would write:
+
+```rust
+#[derive(Serialize)]
+struct Task { ... }
+
+#[get("/todo")]
+fn todo() -> JSON { ... }
+```
+
+The generic type in `JSON` must implement `Serialize`. The `JSON` type
+serializes the structure into JSON, sets the Content-Type to JSON, and emits the
+serialization in a fixed-sized body. If serialization fails, the request is
+forwarded to the **500** error catcher.
+
+For a complete example, see the [JSON example on
+GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/json).
+
+## Templates
+
+Rocket has built-in support for templating. To respond with a rendered template,
+simply return a
+[Template](https://api.rocket.rs/rocket_contrib/struct.Template.html) type.
+
+```rust
+#[get("/")]
+fn index() -> Template {
+ let context = /* object-like value */;
+ Template::render("index", &context)
+}
+```
+
+Templates are rendered with the `render` method. The method takes in the name of
+a template and a context to render the template with. Rocket searches for a
+template with that name in the configurable `template_dir` configuration
+parameter, which defaults to `templates/`. Templating support in Rocket is
+engine agnostic. The engine used to render a template depends on the template
+file's extension. For example, if a file ends with `.hbs`, Handlebars is used,
+while if a file ends with `.tera`, Tera is used.
+
+The context can be any type that implements `Serialize` and serializes to an
+`Object` value, such as structs, `HashMaps`, and others. The
+[Template](https://api.rocket.rs/rocket_contrib/struct.Template.html) API
+documentation contains more information about templates, while the [Handlebars
+Templates example on
+GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/handlebars_templates)
+is a fully composed application that makes use of Handlebars templates.
+
+## Streaming
+
+When a large amount of data needs to be sent to the client, it is better to
+stream the data to the client to avoid consuming large amounts of memory. Rocket
+provides the [Stream](https://api.rocket.rs/rocket/response/struct.Stream.html)
+type, making this easy. The `Stream` type can be created from any `Read` type.
+For example, to stream from a local Unix stream, we might write:
+
+```rust
+#[get("/stream")]
+fn stream() -> io::Result> {
+ UnixStream::connect("/path/to/my/socket").map(|s| Stream::from(s))
+}
+
+```
+
+Rocket takes care of the rest.
diff --git a/site/guide/state.md b/site/guide/state.md
new file mode 100644
index 00000000..ede89ee0
--- /dev/null
+++ b/site/guide/state.md
@@ -0,0 +1,144 @@
+# State
+
+Many web applications have a need to maintain state. This can be as simple as
+maintaining a counter for the number of visits or as complex as needing to
+access job queues and multiple databases. Rocket provides the tools to enable
+these kinds of interactions in a safe and simple manner.
+
+## Managed State
+
+The enabling feature for maintaining state is _managed state_. Managed state, as
+the name implies, is state that Rocket manages for your application. The state
+is managed on a per-type basis: Rocket will manage at most one value of a given
+type.
+
+The process for using managed state is simple:
+
+ 1. Call `manage` on the `Rocket` instance corresponding to your application
+ with the initial value of the state.
+ 2. Add a `State` type to any request handler, where `T` is the type of the
+ value passed into `manage`.
+
+### Adding State
+
+To instruct Rocket to manage state for your application, call the
+[manage](https://api.rocket.rs/rocket/struct.Rocket.html#method.manage) method
+on a `Rocket` instance. For example, to ask Rocket to manage a `HitCount`
+structure with an internal `AtomicUsize` with an initial value of `0`, we can
+write the following:
+
+```rust
+struct HitCount(AtomicUsize);
+
+rocket::ignite().manage(HitCount(AtomicUsize::new(0)));
+```
+
+The `manage` method can be called any number of times as long as each call
+refers to a value of a different type. For instance, to have Rocket manage both
+a `HitCount` value and a `Config` value, we can write:
+
+```rust
+rocket::ignite()
+ .manage(HitCount(AtomicUsize::new(0)))
+ .manage(Config::from(user_input));
+```
+
+### Retrieving State
+
+State that is being managed by Rocket can be retrieved via the
+[State](https://api.rocket.rs/rocket/struct.State.html) type: a [request
+guard](/guide/requests/#request-guards) for managed state. To use the request
+guard, add a `State` type to any request handler, where `T` is the
+type of the managed state. For example, we can retrieve and respond with the
+current `HitCount` in a `count` route as follows:
+
+```rust
+#[get("/count")]
+fn count(count: State) -> String {
+ let current_count = hit_count.0.load(Ordering::Relaxed);
+ format!("Number of visits: {}", current_count)
+}
+```
+
+You can retrieve more than one `State` type in a single route as well:
+
+```rust
+#[get("/state")]
+fn state(count: State, config: State) -> T { ... }
+```
+
+It can also be useful to retrieve managed state from a `FromRequest`
+implementation. To do so, invoke the `from_request` method of a `State` type
+directly, passing in the `req` parameter of `from_request`:
+
+```rust
+fn from_request(req: &'a Request<'r>) -> request::Outcome {
+ let count = match as FromRequest>::from_request(req) {
+ Outcome::Success(count) => count,
+ ...
+ };
+ ...
+}
+```
+
+### Unmanaged State
+
+If you request a `State` for a `T` that is not `managed`, Rocket won't call
+the offending route. Instead, Rocket will log an error message and return a
+**500** error to the client.
+
+While this behavior is 100% safe, it isn't fun to return **500** errors to
+clients, especially when the issue can be easily avoided. Because of this,
+Rocket tries to prevent an application with unmanaged state from ever running
+via the `unmanaged_state` lint. The lint reads through your code at compile-time
+and emits a warning when a `State` request guard is being used in a mounted
+route for a type `T` that isn't being managed.
+
+As an example, consider the following short application using our `HitCount`
+type from previous examples:
+
+```rust
+#[get("/count")]
+fn count(count: State) -> String {
+ let current_count = hit_count.0.load(Ordering::Relaxed);
+ format!("Number of visits: {}", current_count)
+}
+
+fn main() {
+ rocket::ignite()
+ .manage(Config::from(user_input))
+ .launch()
+}
+```
+
+The application is buggy: a value for `HitCount` isn't being `managed`, but a
+`State` type is being requested in the `count` route. When we compile
+this application, Rocket emits the following warning:
+
+```rust
+warning: HitCount is not currently being managed by Rocket
+ --> src/main.rs:2:17
+ |
+2 | fn count(count: State) -> String {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: this State request guard will always fail
+help: maybe add a call to 'manage' here?
+ --> src/main.rs:8:5
+ |
+8 | rocket::ignite()
+ | ^^^^^^^^^^^^^^^^
+```
+
+The `unmanaged_state` lint isn't perfect. In particular, it cannot track calls
+to `manage` across function boundaries. You can disable the lint on a per-route
+basis by adding `#[allow(unmanaged_state)]` to a route handler. If you wish to
+disable the lint globally, add `#![allow(unmanaged_state)]` to your crate
+attributes.
+
+You can find a complete example using the `HitCounter` structure in the [state
+example on
+GitHub](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/state) and
+learn more about the [manage
+method](https://api.rocket.rs/rocket/struct.Rocket.html#method.manage) and
+[State type](https://api.rocket.rs/rocket/struct.State.html) in the API docs.
diff --git a/site/guide/testing.md b/site/guide/testing.md
new file mode 100644
index 00000000..6144d5dc
--- /dev/null
+++ b/site/guide/testing.md
@@ -0,0 +1,136 @@
+# Testing
+
+Every application should be well tested. Rocket provides the tools to perform
+unit and integration tests on your application as well as inspect Rocket
+generated code.
+
+## Tests
+
+Rocket includes a built-in [testing](https://api.rocket.rs/rocket/testing/)
+module that allows you to unit and integration test your Rocket applications.
+Testing is simple:
+
+ 1. Construct a `Rocket` instance.
+ 2. Construct a `MockRequest`.
+ 3. Dispatch the request using the `Rocket` instance.
+ 4. Inspect, validate, and verify the `Response`.
+
+After setting up, we'll walk through each of these steps for the "Hello, world!"
+program below:
+
+```rust
+#![feature(plugin)]
+#![plugin(rocket_codegen)]
+
+extern crate rocket;
+
+#[get("/")]
+fn hello() -> &'static str {
+ "Hello, world!"
+}
+```
+
+### Setting Up
+
+For the `testing` module to be available, Rocket needs to be compiled with the
+_testing_ feature enabled. Since this feature should only be enabled when your
+application is compiled for testing, the recommended way to enable the _testing_
+feature is via Cargo's `[dev-dependencies]` section in the `Cargo.toml` file as
+follows:
+
+```toml
+[dev-dependencies]
+rocket = { version = "0.2.5", features = ["testing"] }
+```
+
+With this in place, running `cargo test` will result in Cargo compiling Rocket
+with the _testing_ feature, thus enabling the `testing` module.
+
+You'll also need a `test` module with the proper imports:
+
+```rust
+#[cfg(test)]
+mod test {
+ use super::rocket;
+ use rocket::testing::MockRequest;
+ use rocket::http::{Status, Method};
+
+ #[test]
+ fn hello_world() {
+ ...
+ }
+}
+```
+
+In the remainder of this section, we'll work on filling in the `hello_world`
+testing function to ensure that the `hello` route results in a `Response` with
+_"Hello, world!"_ in the body.
+
+### Testing
+
+We'll begin by constructing a `Rocket` instance with the `hello` route mounted
+at the root path. We do this in the same way we would normally with one
+exception: we need to refer to the `testing` route in the `super` namespace:
+
+```rust
+let rocket = rocket::ignite().mount("/", routes![super::hello]);
+```
+
+Next, we create a `MockRequest` that issues a `Get` request to the `"/"` path:
+
+```rust
+let mut req = MockRequest::new(Method::Get, "/");
+```
+
+We now ask Rocket to perform a full dispatch, which includes routing,
+pre-processing and post-processing, and retrieve the `Response`:
+
+```rust
+let mut response = req.dispatch_with(&rocket);
+```
+
+Finally, we can test the
+[Response](https://api.rocket.rs/rocket/struct.Response.html) values to ensure
+that it contains the information we expect it to. We want to ensure two things:
+
+ 1. The status is `200 OK`.
+ 2. The body is the string "Hello, world!".
+
+We do this by querying the `Response` object directly:
+
+```rust
+assert_eq!(response.status(), Status::Ok);
+
+let body_str = response.body().and_then(|b| b.into_string());
+assert_eq!(body_str, Some("Hello, world!".to_string()));
+```
+
+That's it! Run the tests with `cargo test`. The complete application, with
+testing, can be found in the [GitHub testing
+example](https://github.com/SergioBenitez/Rocket/tree/v0.2.5/examples/testing).
+
+## Codegen Debug
+
+It is sometimes useful to inspect the code that Rocket's code generation is
+emitting, especially when you get a strange type error. To have Rocket log the
+code that it is emitting to the console, set the `ROCKET_CODEGEN_DEBUG`
+environment variable when compiling:
+
+```rust
+ROCKET_CODEGEN_DEBUG=1 cargo build
+```
+
+During compilation, you should see output like this:
+
+```rust
+Emitting item:
+fn rocket_route_fn_hello<'_b>(_req: &'_b ::rocket::Request,
+ _data: ::rocket::Data)
+ -> ::rocket::handler::Outcome<'_b> {
+ let responder = hello();
+ ::rocket::handler::Outcome::of(responder)
+}
+```
+
+This corresponds to the facade request handler Rocket generated for the `hello`
+route.
diff --git a/site/index.toml b/site/index.toml
new file mode 100644
index 00000000..2e616274
--- /dev/null
+++ b/site/index.toml
@@ -0,0 +1,193 @@
+###############################################################################
+# Top features: displayed in the header under the introductory text.
+###############################################################################
+
+[release]
+url = "https://crates.io/crates/rocket"
+version = "0.2.5"
+date = "Apr 16, 2017"
+
+[[top_features]]
+title = "Type Safe"
+text = "From request to response Rocket ensures that your types mean something."
+image = "helmet"
+button = "Learn More"
+url = "/overview/#how-rocket-works"
+
+[[top_features]]
+title = "Boilerplate Free"
+text = "Spend your time writing code that really matters, and let Rocket generate the rest."
+image = "robot-free"
+button = "See Examples"
+url = "/overview/#anatomy-of-a-rocket-application"
+
+[[top_features]]
+title = "Easy To Use"
+text = "Rocket makes extensive use of Rust's code generation tools to provide a clean API."
+image = "sun"
+button = "Get Started"
+url = "/guide"
+margin = 2
+
+[[top_features]]
+title = "Extensible"
+text = "Easily create your own primitives that any Rocket application can use."
+image = "telescope"
+button = "See How"
+url = "/overview/#anatomy-of-a-rocket-application"
+margin = 9
+
+###############################################################################
+# Sections: make sure there are an odd number so colors work out.
+###############################################################################
+
+[[sections]]
+title = "Hello, Rocket!"
+code = '''
+ #![feature(plugin)]
+ #![plugin(rocket_codegen)]
+
+ extern crate rocket;
+
+ #[get("/hello//")]
+ fn hello(name: &str, age: u8) -> String {
+ format!("Hello, {} year old named {}!", age, name)
+ }
+
+ fn main() {
+ rocket::ignite().mount("/", routes![hello]).launch();
+ }
+'''
+text = '''
+ This is a **complete Rocket application**. It does exactly what you would
+ expect. If you were to visit **http://localhost:8000/hello/John/58**, you’d
+ see:
+
+ Hello, 58 year old named John!
+
+ If someone visits a path with an `` that isn’t a `u8`, Rocket doesn’t
+ blindly call `hello`. Instead, it tries other matching routes or returns a
+ **404**.
+'''
+
+[[sections]]
+title = "Forms? Check!"
+code = '''
+ #[derive(FromForm)]
+ struct Task {
+ description: String,
+ completed: bool
+ }
+
+ #[post("/", data = "")]
+ fn new(task: Form) -> Flash {
+ if task.get().description.is_empty() {
+ Flash::error(Redirect::to("/"), "Cannot be empty.")
+ } else {
+ Flash::success(Redirect::to("/"), "Task added.")
+ }
+ }
+'''
+text = '''
+ Handling forms **is simple and easy**. Simply derive `FromForm` for your
+ structure and let Rocket know which parameter to use. Rocket **parses and
+ validates** the form request, creates the structure, and calls your function.
+
+ Bad form request? Rocket doesn’t call your function! What if you want to know
+ if the form was bad? Simple! Change the type of `task` to `Option` or
+ `Result`!
+'''
+
+[[sections]]
+title = "JSON, out of the box."
+code = '''
+ #[derive(Serialize, Deserialize)]
+ struct Message {
+ contents: String,
+ }
+
+ #[put("/", data = "")]
+ fn update(id: ID, message: JSON) -> JSON {
+ if DB.contains_key(&id) {
+ DB.insert(id, &message.contents);
+ JSON(json!{ "status": "ok" })
+ } else {
+ JSON(json!{ "status": "error" })
+ }
+ }
+'''
+text = '''
+ Rocket has first-class support for JSON, right out of the box. Simply derive
+ `Deserialize` or `Serialize` to receive or return JSON, respectively.
+
+ Like other important features, JSON works through Rocket’s `FromData` trait,
+ Rocket’s approach to deriving types from body data. It works like this:
+ specify a `data` route parameter of any type that implements `FromData`. A
+ value of that type will then be created automatically from the incoming
+ request body. Best of all, you can implement `FromData` for your types!
+'''
+
+###############################################################################
+# Buttom features: displayed above the footer.
+###############################################################################
+
+[[bottom_features]]
+title = 'Templating'
+text = "Rocket makes rendering templates a breeze with built-in templating support."
+image = 'templating-icon'
+url = '/guide/responses/#templates'
+button = 'Learn More'
+color = 'blue'
+
+[[bottom_features]]
+title = 'Cookies'
+text = "Cookies are first-class in Rocket. View, add, or remove cookies without hassle."
+image = 'cookies-icon'
+url = '/guide/requests/#request-guards'
+button = 'Learn More'
+color = 'purple'
+margin = -6
+
+[[bottom_features]]
+title = 'Streams'
+text = "Rocket streams all incoming and outgoing data, so size isn't a concern."
+image = 'streams-icon'
+url = '/guide/requests/#streaming'
+button = 'Learn More'
+color = 'red'
+margin = -29
+
+[[bottom_features]]
+title = 'Config Environments'
+text = "Configure your application your way for development, staging, and production."
+image = 'config-icon'
+url = '/guide/overview/#configuration'
+button = 'Learn More'
+color = 'yellow'
+margin = -3
+
+[[bottom_features]]
+title = 'Query Params'
+text = "Handling query parameters isn’t an afterthought in Rocket."
+image = 'query-icon'
+url = '/guide/requests/#query-strings'
+button = 'Learn More'
+color = 'orange'
+margin = -3
+
+[[bottom_features]]
+title = 'Testing Library'
+text = "Unit test your applications with ease using the built-in testing library."
+image = 'testing-icon'
+url = '/guide/testing#testing'
+button = 'Learn More'
+color = 'green'
+
+# Blocked on Hyper/OpenSSL.
+# [[bottom_features]]
+# title = 'Signed Sessions'
+# text = "Safe, secure, signed sessions are built-in to Rocket so your users can stay safe."
+# image = 'sessions-icon'
+# url = '/overview'
+# button = 'Learn More'
+# color = 'green'
diff --git a/site/news.toml b/site/news.toml
new file mode 100644
index 00000000..bcf11e14
--- /dev/null
+++ b/site/news.toml
@@ -0,0 +1,15 @@
+[[articles]]
+title = "Rocket v0.2: Managed State & More"
+date = "February 06, 2017"
+snippet = """
+Today marks the first major release since Rocket's debut a little over a month
+ago. Rocket v0.2 packs a ton of new features, fixes, and general improvements.
+Much of the development in v0.2 was led by the community, either through reports
+via the [GitHub issue tracker](https://github.com/SergioBenitez/Rocket/issues)
+or via direct contributions. In fact, there have been **20 unique contributors**
+to Rocket's code since Rocket's initial introduction! Community feedback has
+been incredible. As a special thank you, we include the names of these
+contributors at the end of this article.
+"""
+slug = "2017-02-06-version-0.2"
+
diff --git a/site/news/2017-02-06-version-0.2.md b/site/news/2017-02-06-version-0.2.md
new file mode 100644
index 00000000..aa17f036
--- /dev/null
+++ b/site/news/2017-02-06-version-0.2.md
@@ -0,0 +1,392 @@
+# Rocket v0.2: Managed State & More
+
+**Posted by [Sergio Benitez](https://sergio.bz) on February 06, 2017**
+
+Today marks the first major release since Rocket's debut a little over a month
+ago. Rocket v0.2 packs a ton of new features, fixes, and general improvements.
+Much of the development in v0.2 was led by the community, either through reports
+via the [GitHub issue tracker](https://github.com/SergioBenitez/Rocket/issues)
+or via direct contributions. In fact, there have been **20 unique contributors**
+to Rocket's codebase since Rocket's initial introduction! Community feedback has
+been incredible. As a special thank you, we include the names of these
+contributors at the end of this article.
+
+## About Rocket
+
+Rocket is a web framework for Rust with a focus on ease of use, expressibility,
+and speed. Rocket makes it simple to write fast web applications without
+sacrificing flexibility or type safety. All with minimal code.
+
+> Rocket's so simple, you feel like you're doing something wrong. It's like if
+> you're making fire with rocks and suddently someone gives you a lighter. Even
+> though you know the lighter makes fire, and does it even faster and better and
+> with a simple flick, the rock's still in your brain.
+>
+> -- Artem "impowski" Biryukov, January 17, 2017, on **#rocket**
+
+## New Features
+
+Rocket v0.2 includes several new features that make developing Rocket
+applications simpler, faster, and safer than ever before.
+
+### Managed State
+
+Undoubtedly, the star feature of this release is **managed state**. Managed
+state allows you to pass state to Rocket prior to launching your application and
+later retrieve that state from any request handler by simply including the
+state's type in the function signature. It works in two easy steps:
+
+ 1. Call `manage` on the `Rocket` instance corresponding to your application
+ with the initial value of the state.
+ 2. Add a `State` type to any request handler, where `T` is the type of the
+ value passed into `manage`.
+
+Rocket takes care of the rest! `State` works through Rocket's [request
+guards](/guide/requests/#request-guards). You can call `manage` any number of
+times, as long as each call corresponds to a value of a different type.
+
+As a simple example, consider the following "hit counter" example application:
+
+```rust
+struct HitCount(AtomicUsize);
+
+#[get("/")]
+fn index(hit_count: State) -> &'static str {
+ hit_count.0.fetch_add(1, Ordering::Relaxed);
+ "Your visit has been recorded!"
+}
+
+#[get("/count")]
+fn count(hit_count: State) -> String {
+ hit_count.0.load(Ordering::Relaxed).to_string()
+}
+
+fn main() {
+ rocket::ignite()
+ .mount("/", routes![index, count])
+ .manage(HitCount(AtomicUsize::new(0)))
+ .launch()
+}
+```
+
+Visiting `/` will record a visit by incrementing the hit count by 1. Visiting
+the `/count` path will display the current hit count.
+
+One concern when using _managed state_ is that you might forget to call `manage`
+with some state's value before launching your application. Not to worry: Rocket
+has your back! Let's imagine for a second that we forgot to add the call to
+`manage` on line 17 in the example above. Here's what the compiler would emit
+when we compile our buggy application:
+
+```rust
+warning: HitCount is not currently being managed by Rocket
+ --> src/main.rs:4:21
+ |
+4 | fn index(hit_count: State) -> &'static str {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: this State request guard will always fail
+help: maybe add a call to 'manage' here?
+ --> src/main.rs:15:5
+ |
+15| rocket::ignite()
+ | ^^^^^^^^^^^^^^^^
+
+warning: HitCount is not currently being managed by Rocket
+ --> src/main.rs:10:21
+ |
+10 | fn count(hit_count: State) -> String {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: this State request guard will always fail
+help: maybe add a call to 'manage' here?
+ --> src/main.rs:15:5
+ |
+15 | rocket::ignite()
+ | ^^^^^^^^^^^^^^^^
+```
+
+You can read more about managed state in the [guide](/guide/state/), the API
+docs for
+[manage](https://api.rocket.rs/rocket/struct.Rocket.html#method.manage), and the
+API docs for [State](https://api.rocket.rs/rocket/struct.State.html).
+
+### Unmounted Routes Lint
+
+A common mistake that new Rocketeers make is forgetting to
+[mount](/guide/overview/#mounting) declared routes. In Rocket v0.2, Rocket adds
+a _lint_ that results in a compile-time warning for unmounted routes. As a
+simple illustration, consider the canonical "Hello, world!" Rocket application
+below, and note that we've forgotten to mount the `hello` route:
+
+```rust
+#[get("/")]
+fn hello() -> &'static str {
+ "Hello, world!"
+}
+
+fn main() {
+ rocket::ignite().launch();
+}
+```
+
+When this program is compiled, the compiler emits the following warning:
+
+```rust
+warning: the 'hello' route is not mounted
+ --> src/main.rs:2:1
+ |
+2 | fn hello() -> &'static str {
+ | _^ starting here...
+3 | | "Hello, world!"
+4 | | }
+ | |_^ ...ending here
+ |
+ = note: Rocket will not dispatch requests to unmounted routes.
+help: maybe add a call to 'mount' here?
+ --> src/main.rs:7:5
+ |
+7 | rocket::ignite().launch();
+ | ^^^^^^^^^^^^^^^^
+```
+
+The lint can be disabled selectively per route by adding an
+`#[allow(unmounted_route)]` annotation to a given route declaration. It can also
+be disabled globally by adding `#![allow(unmounted_route)]`. You can read more
+about this lint in the [codegen
+documentation](https://api.rocket.rs/rocket_codegen/index.html).
+
+### Configuration via Environment Variables
+
+A new feature that makes deploying Rocket apps to the cloud a little easier is
+configuration via environment variables. Simply put, any configuration parameter
+can be set via an environment variable of the form `ROCKET_{PARAM}`, where
+`{PARAM}` is the name of the configuration parameter. For example, to set the
+`port` Rocket listens on, simply set the `ROCKET_PORT` environment variable:
+
+```sh
+ROCKET_PORT=3000 cargo run --release
+```
+
+Configuration parameters set via environment variables take precedence over
+parameters set via the `Rocket.toml` configuration file. Note that _any_
+parameter can be set via an environment variable, include _extras_. For more
+about configuration in Rocket, see the [configuration section of the
+guide](/guide/overview/#configuration).
+
+### And Plenty More!
+
+Rocket v0.2 is full of many new features! In addition to the three features
+described above, v0.2 also includes the following:
+
+ * `Config` structures can be built via `ConfigBuilder`, which follows the
+ builder pattern.
+ * Logging can be enabled or disabled on custom configuration via a second
+ parameter to the `Rocket::custom` method.
+ * `name` and `value` methods were added to `Header` to retrieve the name and
+ value of a header.
+ * A new configuration parameter, `workers`, can be used to set the number of
+ threads Rocket uses.
+ * The address of the remote connection is available via `Request.remote()`.
+ Request preprocessing overrides remote IP with value from the `X-Real-IP`
+ header, if present.
+ * During testing, the remote address can be set via `MockRequest.remote()`.
+ * The `SocketAddr` request guard retrieves the remote address.
+ * A `UUID` type has been added to `contrib`.
+ * `rocket` and `rocket_codegen` will refuse to build with an incompatible
+ nightly version and emit nice error messages.
+ * Major performance and usability improvements were upstreamed to the `cookie`
+ crate, including the addition of a `CookieBuilder`.
+ * When a checkbox isn't present in a form, `bool` types in a `FromForm`
+ structure will parse as `false`.
+ * The `FormItems` iterator can be queried for a complete parse via `completed`
+ and `exhausted`.
+ * Routes for `OPTIONS` requests can be declared via the `options` decorator.
+ * Strings can be percent-encoded via `URI::percent_encode()`.
+
+## Breaking Changes
+
+This release includes several breaking changes. These changes are listed below
+along with a short note about how to handle the breaking change in existing
+applications.
+
+ * **`Rocket::custom` takes two parameters, the first being `Config` by
+ value.**
+
+ A call in v0.1 of the form `Rocket::custom(&config)` is now
+ `Rocket::custom(config, false)`.
+
+ * **Tera templates are named without their extension.**
+
+ A templated named `name.html.tera` is now simply `name`.
+
+ * **`JSON` `unwrap` method has been renamed to `into_inner`.**
+
+ A call to `.unwrap()` should be changed to `.into_inner()`.
+
+ * **The `map!` macro was removed in favor of the `json!` macro.**
+
+ A call of the form `map!{ "a" => b }` can be written as: `json!({ "a": b
+ })`.
+
+ * **The `hyper::SetCookie` header is no longer exported.**
+
+ Use the `Cookie` type as an `Into` type directly.
+
+ * **The `Content-Type` for `String` is now `text/plain`.**
+
+ Use `content::HTML` for HTML-based `String` responses.
+
+ * **`Request.content_type()` returns an `Option`.**
+
+ Use `.unwrap_or(ContentType::Any)` to get the old behavior.
+
+ * **The `ContentType` request guard forwards when the request has no
+ `Content-Type` header.**
+
+ Use an `Option` and `.unwrap_or(ContentType::Any)` for the old
+ behavior.
+
+ * **A `Rocket` instance must be declared _before_ a `MockRequest`.**
+
+ Change the order of the `rocket::ignite()` and `MockRequest::new()` calls.
+
+ * **A route with `format` specified only matches requests with the same
+ format.**
+
+ Previously, a route with a `format` would match requests without a format
+ specified. There is no workaround to this change; simply specify formats
+ when required.
+
+ * **`FormItems` can no longer be constructed directly.**
+
+ Instead of constructing as `FormItems(string)`, construct as
+ `FormItems::from(string)`.
+
+ * **`from_from_string(&str)` in `FromForm` removed in favor of
+ `from_form_items(&mut FormItems)`.**
+
+ Most implementation should be using `FormItems` internally; simply use the
+ passed in `FormItems`. In other cases, the form string can be retrieved via
+ the `inner_str` method of `FormItems`.
+
+ * **`Config::{set, default_for}` are deprecated.**
+
+ Use the `set_{param}` methods instead of `set`, and `new` or `build` in
+ place of `default_for`.
+
+ * **Route paths must be absolute.**
+
+ Prepend a `/` to convert a relative path into an absolute one.
+
+ * **Route paths cannot contain empty segments.**
+
+ Remove any empty segments, including trailing ones, from a route path.
+
+## Bug Fixes
+
+Three bugs were fixed in this release:
+
+ * Handlebars partials were not properly registered
+ ([#122](https://github.com/SergioBenitez/Rocket/issues/122)).
+ * `Rocket::custom` did not set the custom configuration as the `active`
+ configuration.
+ * Route path segments with more than one dynamic parameter were erroneously
+ allowed.
+
+## General Improvements
+
+In addition to new features, Rocket saw the following smaller improvements:
+
+ * Rocket no longer overwrites a catcher's response status.
+ * The `port` `Config` type is now a proper `u16`.
+ * Clippy issues injected by codegen are resolved.
+ * Handlebars was updated to `0.25`.
+ * The `PartialEq` implementation of `Config` doesn't consider the path or
+ session key.
+ * Hyper dependency updated to `0.10`.
+ * The `Error` type for `JSON as FromData` has been exposed as `SerdeError`.
+ * SVG was added as a known Content-Type.
+ * Serde was updated to `0.9`.
+ * Form parse failure now results in a **422** error code.
+ * Tera has been updated to `0.7`.
+ * `pub(crate)` is used throughout to enforce visibility rules.
+ * Query parameters in routes (`/path?`) are now logged.
+ * Routes with and without query parameters no longer _collide_.
+
+Rocket v0.2 also includes all of the new features, bug fixes, and improvements
+from versions 0.1.1 through 0.1.6. You can read more about these changes in the
+[v0.1
+CHANGELOG](https://github.com/SergioBenitez/Rocket/blob/v0.1/CHANGELOG.md).
+
+## What's next?
+
+Work now begins on Rocket v0.3! The focus of the next major release will be on
+security. In particular, three major security features are planned:
+
+ 1. **Automatic CSRF protection across all payload-based requests
+ ([#14](https://github.com/SergioBenitez/Rocket/issues/14)).**
+
+ Rocket will automatically check the origin of requests made for HTTP `PUT`,
+ `POST`, `DELETE`, and `PATCH` requests, allowing only authorized requests to
+ be dispatched. This includes checking `POST`s from form submissions and any
+ requests made via JavaScript.
+
+ 2. **Encryption and signing of session-based cookies
+ ([#20](https://github.com/SergioBenitez/Rocket/issues/20)).**
+
+ Built-in session support will encrypt and sign cookies using a user supplied
+ `session_key`. Encryption and signing will occur automatically for
+ session-based cookies.
+
+ 3. **Explicit typing of raw HTTP data strings
+ ([#43](https://github.com/SergioBenitez/Rocket/issues/43)).**
+
+ A present, the standard `&str` type is used to represent raw HTTP data
+ strings. In the next release, a new type, `&RawStr`, will be used for this
+ purpose. This will make it clear when raw data is being handled. The type
+ will expose convenient methods such as `.url_decode()` and `.html_escape()`.
+
+Work on Rocket v0.3 will also involve exploring built-in support for user
+authentication and authorization as well as automatic parsing of multipart
+forms.
+
+## Contributors to v0.2
+
+The following wonderful people helped make Rocket v0.2 happen:
+
+
+
Cliff H
+
Dru Sellers
+
Eijebong
+
Eric D. Reichert
+
Ernestas Poskus
+
FliegendeWurst
+
Garrett Squire
+
Giovanni Capuano
+
Greg Edwards
+
Joel Roller
+
Josh Holmer
+
Liigo Zhuang
+
Lori Holden
+
Marcus Ball
+
Matt McCoy
+
Reilly Tucker
+
Robert Balicki
+
Sean Griffin
+
Seth Lopez
+
tborsa
+
+
+Thank you all! Your contributions are greatly appreciated!
+
+Looking to help with Rocket's development? Head over to [Rocket's
+GitHub](https://github.com/SergioBenitez/Rocket#contributing) and start
+contributing!
+
+## Start using Rocket today!
+
+Not already using Rocket? Rocket is extensively documented, making it easy for
+you to start writing your web applications in Rocket! See the
+[overview](/overview) or start writing code immediately by reading through [the
+guide](/guide).
diff --git a/site/overview.toml b/site/overview.toml
new file mode 100644
index 00000000..232cd774
--- /dev/null
+++ b/site/overview.toml
@@ -0,0 +1,231 @@
+###############################################################################
+# Panels: displayed in a tabbed arrangement.
+###############################################################################
+
+[[panels]]
+name = "Routing"
+checked = true
+content = '''
+Rocket's main task is to route incoming requests to the appropriate request
+handler using your application's declared routes. Routes are declared using
+Rocket's _route_ attributes. The attribute describes the requests that match the
+route. The attribute is placed on top of a function that is the request handler
+for that route.
+
+As an example, consider the simple route below:
+
+```rust
+#[get("/")]
+fn index() -> &'static str {
+ "Hello, world!"
+}
+```
+
+This route, named `index`, will match against incoming HTTP `GET` requests to
+the `/` path, the index. The request handler returns a string. Rocket will use
+the string as the body of a fully formed HTTP response.
+'''
+
+[[panels]]
+name = "Dynamic Params"
+content = '''
+Rocket allows you to interpret segments of a request path dynamically. To
+illustrate, let's use the following route:
+
+```rust
+#[get("/hello//")]
+fn hello(name: &str, age: u8) -> String {
+ format!("Hello, {} year old named {}!", age, name)
+}
+```
+
+The `hello` route above matches two dynamic path segments declared inside
+brackets in the path: `` and ``. _Dynamic_ means that the segment can
+be _any_ value the end-user desires.
+
+Each dynamic parameter (`name` and `age`) must have a type, here `&str` and
+`u8`, respectively. Rocket will attempt to parse the string in the parameter's
+position in the path into that type. The route will only be called if parsing
+succeeds. To parse the string, Rocket uses the
+[FromParam](https://api.rocket.rs/rocket/request/trait.FromParam.html) trait,
+which you can implement for your own types!
+'''
+
+[[panels]]
+name = "Handling Data"
+content = '''
+Request body data is handled in a special way in Rocket: via the
+[FromData](https://api.rocket.rs/rocket/data/trait.FromData.html) trait. Any
+type that implements `FromData` can be derived from incoming body data. To tell
+Rocket that you're expecting request body data, the `data` route argument is
+used with the name of the parameter in the request handler:
+
+```rust
+#[post("/login", data = "")]
+fn login(user_form: Form) -> String {
+ // Use `user_form`, return a String.
+}
+```
+
+The `login` route above says that it expects `data` of type `Form` in
+the `user_form` parameter. The
+[Form](https://api.rocket.rs/rocket/request/struct.Form.html) type is a built-in
+Rocket type that knows how to parse web forms into structures. Rocket will
+automatically attempt to parse the request body into the `Form` and call the
+`login` handler if parsing succeeds. Other built-in `FromData` types include
+[Data](https://api.rocket.rs/rocket/struct.Data.html),
+[JSON](https://api.rocket.rs/rocket_contrib/struct.JSON.html), and
+[Flash](https://api.rocket.rs/rocket/response/struct.Flash.html)
+'''
+
+[[panels]]
+name = "Request Guards"
+content = '''
+In addition to dynamic path and data parameters, request handlers can also
+contain a third type of parameter: _request guards_. Request guards aren't
+declared in the route attribute, and any number of them can appear in the
+request handler signature.
+
+Request guards _protect_ the handler from running unless some set of conditions
+are met by the incoming request metadata. For instance, if you are writing an
+API that requires sensitive calls to be accompanied by an API key in the request
+header, Rocket can protect those calls via a custom `APIKey` request guard:
+
+```rust
+#[get("/sensitive")]
+fn sensitive(key: APIKey) -> &'static str { ... }
+```
+
+`APIKey` protects the `sensitive` handler from running incorrectly. In order for
+Rocket to call the `sensitive` handler, the `APIKey` type needs to be derived
+through a
+[FromRequest](https://api.rocket.rs/rocket/request/trait.FromRequest.html)
+implementation, which in this case, validates the API key header. Request guards
+are a powerful and unique Rocket concept; they centralize application policy and
+invariants through types.
+'''
+
+[[panels]]
+name = "Responders"
+content = '''
+The return type of a request handler can by any type that implements
+[Responder](https://api.rocket.rs/rocket/response/trait.Responder.html):
+
+```rust
+#[get("/")]
+fn route() -> T { ... }
+```
+
+Above, T must implement `Responder`. Rocket implements `Responder` for many of
+the standard library types including `&str`, `String`, `File`, `Option`, and
+`Result`. Rocket also implements custom responders such as
+[Redirect](https://api.rocket.rs/rocket/response/struct.Redirect.html),
+[Flash](https://api.rocket.rs/rocket/response/struct.Flash.html), and
+[Template](https://api.rocket.rs/rocket_contrib/struct.Template.html).
+
+The task of a `Reponder` is to generate a
+[Response](https://api.rocket.rs/rocket/response/struct.Response.html), if
+possible. `Responder`s can fail with a status code. When they do, Rocket calls
+the corresponding `error` route, which can be declared as follows:
+
+```rust
+#[error(404)]
+fn not_found() -> T { ... }
+```
+'''
+
+[[panels]]
+name = "Launching"
+content = '''
+Launching a Rocket application is the funnest part! For Rocket to begin
+dispatching requests to routes, the routes need to be _mounted_. After mounting,
+the application needs to be _launched_. These two steps, usually done in `main`,
+look like:
+
+```rust
+rocket::ignite()
+ .mount("/base", routes![index, another])
+ .launch()
+```
+
+The `mount` call takes a base path and a set of routes via the `routes!` macro.
+The base path (`/base` above) is prepended to the path of every route in the
+list. This effectively namespaces the routes, allowing for easier composition.
+
+The `launch` call starts the server. In development, Rocket prints useful
+information to the console to let you know everything is okay.
+
+```sh
+🚀 Rocket has launched from http://localhost:8000...
+```
+'''
+
+###############################################################################
+# Steps to "How Rocket Works"
+###############################################################################
+
+[[steps]]
+name = "Validation"
+color = "blue"
+content = '''
+First, Rocket validates a matching request by ensuring that all of the types in
+a given handler can be derived from the incoming request. If the types cannot be
+derived, the request is forwarded to the next matching route until a route’s
+types validate or there are no more routes to try. If all routes fail, a
+customizable **404** error is returned.
+
+```rust
+#[post("/user", data = "")]
+fn new_user(admin: AdminUser, new_user: Form) -> T {
+ ...
+}
+```
+
+For the `new_user` handler above to be called, the following conditions must
+hold:
+
+* The request method must be `POST`.
+* The request path must be `/user`.
+* The request must contain `data` in its body.
+* The request metadata must authenticate an `AdminUser`.
+* The request body must be a form that parses into a `User` struct.
+'''
+
+[[steps]]
+name = "Processing"
+color = "purple"
+content = '''
+Next, the request is processed by an arbitrary handler. This is where most of
+the business logic in an application resides, and the part of your applications
+you’ll likely spend the most time writing. In Rocket, handlers are simply
+functions - that’s it! The only caveat is that the function’s return type must
+implement the `Responder` trait. The `new_user` function above is an example of
+a handler.
+'''
+
+[[steps]]
+name = "Response"
+color = "red"
+content = '''
+Finally, Rocket responds to the client by transforming the return value of the
+handler into an HTTP response. The HTTP response generated from the returned
+value depends on the type’s specific `Responder` trait implementation.
+
+```rust
+fn route() -> T { ... }
+```
+
+If the function above is used as a handler, for instance, then the type `T` must
+implement `Responder`. Rocket provides many useful responder types out of the
+box. They include:
+
+ * `JSON`: Serializes the structure T into JSON and returns it to
+ the client.
+ * `Template`: Renders a template file and returns it to the client.
+ * `Redirect`: Returns a properly formatted HTTP redirect.
+ * `NamedFile`: Streams a given file to the client with the
+ Content-Type taken from the file’s extension.
+ * `Stream`: Streams data to the client from an arbitrary `Read` value.
+ * Many Primitive Types: `String`, `&str`, `File`, `Option`, `Result`, and
+ others all implement the `Responder` trait.
+'''