2 * shortener - Page.java - Copyright © 2010 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.web.page;
20 import java.io.ByteArrayInputStream;
21 import java.io.InputStream;
22 import java.io.UnsupportedEncodingException;
24 import java.util.HashMap;
27 import freenet.clients.http.ToadletContext;
28 import freenet.support.api.HTTPRequest;
31 * A page is responsible for handling HTTP requests and creating appropriate
34 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
36 public interface Page {
39 * Returns the path of this toadlet.
41 * @return The path of this toadlet
43 public String getPath();
49 * The request to handle
50 * @return The response
52 public Response handleRequest(Request request);
55 * Container for request data.
57 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
59 public class Request {
61 /** The URI that was accessed. */
62 private final URI uri;
64 /** The HTTP method that was used. */
65 private final String method;
67 /** The HTTP request. */
68 private final HTTPRequest httpRequest;
70 /** The toadlet context. */
71 private final ToadletContext toadletContext;
74 * Creates a new request that holds the given data.
77 * The URI of the request
79 * The HTTP method of the request
82 * @param toadletContext
83 * The toadlet context of the request
85 public Request(URI uri, String method, HTTPRequest httpRequest, ToadletContext toadletContext) {
88 this.httpRequest = httpRequest;
89 this.toadletContext = toadletContext;
93 * Returns the URI that was accessed.
95 * @return The accessed URI
102 * Returns the HTTP method that was used to access the page.
104 * @return The HTTP method
106 public String getMethod() {
111 * Returns the HTTP request.
113 * @return The HTTP request
115 public HTTPRequest getHttpRequest() {
120 * Returns the toadlet context.
122 * @return The toadlet context
124 public ToadletContext getToadletContext() {
125 return toadletContext;
131 * Container for the HTTP response of a {@link Page}.
133 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
135 public class Response {
137 /** The HTTP status code of the response. */
138 private final int statusCode;
140 /** The HTTP status text of the response. */
141 private final String statusText;
143 /** The content type of the response. */
144 private final String contentType;
146 /** The headers of the response. */
147 private final Map<String, String> headers;
149 /** The content of the response body. */
150 private final InputStream content;
153 * Creates a new response.
156 * The HTTP status code of the response
158 * The HTTP status text of the response
160 * The content type of the response
162 * The text in the response body
164 public Response(int statusCode, String statusText, String contentType, String text) {
165 this(statusCode, statusText, contentType, getBytes(text));
169 * Creates a new response.
172 * The HTTP status code of the response
174 * The HTTP status text of the response
176 * The content type of the response
178 * The content of the reponse body
180 public Response(int statusCode, String statusText, String contentType, byte[] content) {
181 this(statusCode, statusText, contentType, null, content);
185 * Creates a new response.
188 * The HTTP status code of the response
190 * The HTTP status text of the response
192 * The content type of the response
194 * The headers of the response
196 public Response(int statusCode, String statusText, String contentType, Map<String, String> headers) {
197 this(statusCode, statusText, contentType, headers, (InputStream) null);
201 * Creates a new response.
204 * The HTTP status code of the response
206 * The HTTP status text of the response
208 * The content type of the response
210 * The headers of the response
212 * The content of the reponse body
214 public Response(int statusCode, String statusText, String contentType, Map<String, String> headers, byte[] content) {
215 this(statusCode, statusText, contentType, headers, new ByteArrayInputStream(content));
219 * Creates a new response.
222 * The HTTP status code of the response
224 * The HTTP status text of the response
226 * The content type of the response
228 * The headers of the response
230 * The content of the reponse body
232 public Response(int statusCode, String statusText, String contentType, Map<String, String> headers, InputStream content) {
233 this.statusCode = statusCode;
234 this.statusText = statusText;
235 this.contentType = contentType;
236 this.headers = headers;
237 this.content = content;
241 * Returns the HTTP status code of the response.
243 * @return The HTTP status code
245 public int getStatusCode() {
250 * Returns the HTTP status text.
252 * @return The HTTP status text
254 public String getStatusText() {
259 * Returns the content type of the response.
261 * @return The content type of the reponse
263 public String getContentType() {
268 * Returns HTTP headers of the response. May be {@code null} if no
269 * headers are returned.
271 * @return The response headers, or {@code null} if there are no
274 public Map<String, String> getHeaders() {
279 * Returns the content of the response body. May be {@code null} if the
280 * response does not have a body.
282 * @return The content of the response body
284 public InputStream getContent() {
293 * Returns the UTF-8 representation of the given text.
297 * @return The encoded text
299 private static byte[] getBytes(String text) {
301 return text.getBytes("UTF-8");
302 } catch (UnsupportedEncodingException uee1) {
303 /* every JVM needs to support UTF-8. */
309 * Creates a header map containing a single header.
312 * The name of the header
314 * The value of the header
315 * @return The map containing the single header
317 protected static Map<String, String> createHeader(String name, String value) {
318 Map<String, String> headers = new HashMap<String, String>();
319 headers.put(name, value);
326 * {@link Response} implementation that performs an HTTP redirect.
328 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
330 public class RedirectResponse extends Response {
333 * Creates a new redirect response to the new location.
338 public RedirectResponse(String newLocation) {
339 this(newLocation, true);
343 * Creates a new redirect response to the new location.
348 * Whether the redirect should be marked as permanent
350 public RedirectResponse(String newLocation, boolean permanent) {
351 super(permanent ? 302 : 307, "Redirected", null, createHeader("Location", newLocation));