1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is the MozJSHTTP server.
15 *
16 * The Initial Developer of the Original Code is
17 * Mozilla Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2006
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Jeff Walden <jwalden+code@mit.edu> (original author)
23 * Robert Sayre <sayrer@gmail.com>
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39 #include "nsIServerSocket.idl"
40 #include "nsIPropertyBag.idl"
41
42 interface nsILocalFile;
43 interface nsISimpleEnumerator;
44 interface nsIOutputStream;
45
46 interface nsIHttpServer;
47 interface nsIHttpRequestHandler;
48 interface nsIHttpRequestMetadata;
49 interface nsIHttpResponse;
50
51 /**
52 * An interface which represents an HTTP server.
53 */
54 [scriptable, uuid(5520f79e-ecd5-4c40-843b-97ee13a23747)]
55 interface nsIHttpServer : nsIServerSocketListener
56 {
57 /**
58 * Starts up this server, listening upon the given port. This method may
59 * throw if the process does not have sufficient privileges to open a socket
60 * for the given port, and it also throws when called upon a server which has
61 * already been started.
62 *
63 * @param port
64 * the port upon which listening should happen, or -1 if no specific port is
65 * desired
66 */
67 void start(in long port);
68
69 /**
70 * Shuts down this server if it is running; if it is not, this method is a
71 * no-op.
72 *
73 * This method will do its best to return after the socket in this
74 * server has been closed and all pending requests have completed being
75 * served, but this may or may not actually happen, since in some
76 * implementations this may not actually be possible. Implementations which
77 * can make this promise should make it explicit in implementation
78 * documentation.
79 */
80 void stop();
81
82 /**
83 * Associates the local file represented by the string file with all requests
84 * which match request.
85 *
86 * @param path
87 * the path which is to be mapped to the given file; must begin with "/" and
88 * be a valid URI path (i.e., no query string, hash reference, etc.)
89 * @param file
90 * the file to serve for the given path, or null to remove any mapping that
91 * might exist; this file must exist for the lifetime of the server
92 */
93 void registerFile(in string path, in nsILocalFile file);
94
95 /**
96 * Registers a custom path handler.
97 *
98 * @param path
99 * the path on the server (beginning with a "/") which is to be handled by
100 * handler; this path must not include a query string or hash component; it
101 * also should usually be canonicalized, since most browsers will do so
102 * before sending otherwise-matching requests
103 * @param handler
104 * an object which will handle any requests for the given path, or null to
105 * remove any existing handler; if while the server is running the handler
106 * throws an exception while responding to a request, an HTTP 500 response
107 * will be returned
108 * @throws NS_ERROR_INVALID_ARG
109 * if path does not begin with a "/"
110 */
111 void registerPathHandler(in string path, in nsIHttpRequestHandler handler);
112
113 /**
114 * Registers a custom error page handler.
115 *
116 * @param code
117 * the error code which is to be handled by handler
118 * @param handler
119 * an object which will handle any requests which generate the given status
120 * code, or null to remove any existing handler. If the handler throws an
121 * exception during server operation, fallback is to the genericized error
122 * handler (the x00 version), then to 500, using a user-defined error
123 * handler if one exists or the server default handler otherwise. Fallback
124 * will never occur from a user-provided handler that throws to the same
125 * handler as provided by the server, e.g. a throwing user 404 falls back to
126 * 400, not a server-provided 404 that might not throw.
127 * @note
128 * If the error handler handles HTTP 500 and throws, behavior is undefined.
129 */
130 void registerErrorHandler(in unsigned long code, in nsIHttpRequestHandler handler);
131
132 /**
133 * Maps all requests to paths beneath path to the corresponding file beneath
134 * dir.
135 *
136 * @param path
137 * the absolute path on the server against which requests will be served
138 * from dir (e.g., "/", "/foo/", etc.); must begin and end with a forward
139 * slash
140 * @param dir
141 * the directory to be used to serve all requests for paths underneath path
142 * (except those further overridden by another, deeper path registered with
143 * another directory); if null, any current mapping for the given path is
144 * removed
145 * @throws NS_ERROR_INVALID_ARG
146 * if dir is non-null and does not exist or is not a directory, or if path
147 * does not begin with and end with a forward slash
148 */
149 void registerDirectory(in string path, in nsILocalFile dir);
150
151 /**
152 * Associates files with the given extension with the given Content-Type when
153 * served by this server, in the absence of any file-specific information
154 * about the desired Content-Type. If type is empty, removes any extant
155 * mapping, if one is present.
156 *
157 * @throws NS_ERROR_INVALID_ARG
158 * if the given type is not a valid header field value, i.e. if it doesn't
159 * match the field-value production in RFC 2616
160 * @note
161 * No syntax checking is done of the given type, beyond ensuring that it is
162 * a valid header field value. Behavior when not given a string matching
163 * the media-type production in RFC 2616 section 3.7 is undefined.
164 * Implementations may choose to define specific behavior for types which do
165 * not match the production, such as for CGI functionality.
166 * @note
167 * Implementations MAY treat type as a trusted argument; users who fail to
168 * generate this string from trusted data risk security vulnerabilities.
169 */
170 void registerContentType(in string extension, in string type);
171
172 /**
173 * Sets the handler used to display the contents of a directory if
174 * the directory contains no index page.
175 *
176 * @param handler
177 * an object which will handle any requests for directories which
178 * do not contain index pages, or null to reset to the default
179 * index handler; if while the server is running the handler
180 * throws an exception while responding to a request, an HTTP 500
181 * response will be returned. An nsIFile corresponding to the
182 * directory is available from the metadata object passed to the
183 * handler, under the key "directory".
184 */
185 void setIndexHandler(in nsIHttpRequestHandler handler);
186 };
187
188 /**
189 * A representation of a handler for HTTP requests. The handler is used by
190 * calling its .handle method with data for an incoming request; it is the
191 * handler's job to use that data as it sees fit to make the desired response.
192 *
193 * @note
194 * This interface uses the [function] attribute, so you can pass a
195 * script-defined function with the functionality of handle() to any
196 * method which has a nsIHttpRequestHandler parameter, instead of wrapping
197 * it in an otherwise empty object.
198 */
199 [scriptable, function, uuid(2bbb4db7-d285-42b3-a3ce-142b8cc7e139)]
200 interface nsIHttpRequestHandler : nsISupports
201 {
202 /**
203 * Processes the HTTP request represented by metadata and initializes the
204 * passed-in response to reflect the correct HTTP response.
205 *
206 * Note that in some uses of nsIHttpRequestHandler, this method is required to
207 * not throw an exception; in the general case, however, this method may throw
208 * an exception (causing an HTTP 500 response to occur).
209 *
210 * @param metadata
211 * data representing an HTTP request
212 * @param response
213 * an initially-empty response which must be modified to reflect the data
214 * which should be sent as the response to the request described by metadata
215 */
216 void handle(in nsIHttpRequestMetadata metadata, in nsIHttpResponse response);
217 };
218
219
220 /**
221 * A representation of the data included in an HTTP request.
222 */
223 [scriptable, uuid(3a899b17-b6eb-4333-8ef4-912df454a551)]
224 interface nsIHttpRequestMetadata : nsIPropertyBag
225 {
226 /**
227 * The request type for this request (see RFC 2616, section 5.1.1).
228 */
229 readonly attribute string method;
230
231 /**
232 * The host of the data being requested (e.g. "localhost" for the
233 * http://localhost:8080/file resource). Note that the relevant port on the
234 * host is specified in this.port.
235 */
236 readonly attribute string host;
237
238 /**
239 * The port on the server on which the request was received.
240 */
241 readonly attribute unsigned long port;
242
243 /**
244 * The requested path, without any query string (e.g. "/dir/file.txt"). It is
245 * guaranteed to begin with a "/". This string is in the
246 */
247 readonly attribute string path;
248
249 /**
250 * The URL-encoded query string associated with this request, not including
251 * the initial "?".
252 */
253 readonly attribute string queryString;
254
255 /**
256 * A string containing the HTTP version of the request (i.e., "1.1"). Leading
257 * zeros for either component of the version will be omitted. (In other
258 * words, if the request contains the version "1.01", this attribute will be
259 * "1.1"; see RFC 2616, section 3.1.)
260 */
261 readonly attribute string httpVersion;
262
263 /**
264 * Returns the value for the header in this request specified by fieldName.
265 *
266 * @param fieldName
267 * the name of the field whose value is to be gotten; note that since HTTP
268 * header field names are case-insensitive, this method produces equivalent
269 * results for "HeAdER" and "hEADer" as fieldName
270 * @returns
271 * the field value for the given header; note that this value may be
272 * normalized (e.g., leading/trailing whitespace removed from the value [or
273 * from the values which make this up, if the header is a comma-separated
274 * list of values], whitespace runs compressed to single spaces, etc.)
275 * @throws NS_ERROR_INVALID_ARG
276 * if fieldName does not constitute a valid header field name
277 * @throws NS_ERROR_NOT_AVAILABLE
278 * if the given header does not exist in this
279 */
280 string getHeader(in string fieldName);
281
282 /**
283 * Returns true if a header with the given field name exists in this, false
284 * otherwise.
285 *
286 * @param fieldName
287 * the field name whose existence is to be determined in this; note that
288 * since HTTP header field names are case-insensitive, this method produces
289 * equivalent results for "HeAdER" and "hEADer" as fieldName
290 * @throws NS_ERROR_INVALID_ARG
291 * if fieldName does not constitute a valid header field name
292 */
293 boolean hasHeader(in string fieldName);
294
295 /**
296 * An nsISimpleEnumerator of nsISupportsStrings over the names of the headers
297 * in this request. The header field names in the enumerator may not
298 * necessarily have the same case as they do in the request itself.
299 */
300 readonly attribute nsISimpleEnumerator headers;
301
302 // XXX expose request body here!
303 };
304
305
306 /**
307 * Represents an HTTP response, as described in RFC 2616, section 6.
308 */
309 [scriptable, uuid(a2aaaff7-03bd-43b6-b460-94671e288093)]
310 interface nsIHttpResponse : nsISupports
311 {
312 /**
313 * Sets the status line for this. If this method is never called on this, the
314 * status line defaults to "HTTP/", followed by the server's default HTTP
315 * version (e.g. "1.1"), followed by " 200 OK".
316 *
317 * @param httpVersion
318 * the HTTP version of this, as a string (e.g. "1.1"); if null, the server
319 * default is used
320 * @param code
321 * the numeric HTTP status code for this
322 * @param description
323 * a human-readable description of code; may be null if no description is
324 * desired
325 * @throws NS_ERROR_INVALID_ARG
326 * if httpVersion is not a valid HTTP version string, statusCode is greater
327 * than 999, or description contains invalid characters
328 */
329 void setStatusLine(in string httpVersion,
330 in unsigned short statusCode,
331 in string description);
332
333 /**
334 * Sets the specified header in this.
335 *
336 * @param name
337 * the name of the header; must match the field-name production per RFC 2616
338 * @param value
339 * the value of the header; must match the field-value production per RFC
340 * 2616
341 * @param merge
342 * when true, if the given header already exists in this, the values passed
343 * to this function will be merged into the existing header, per RFC 2616
344 * header semantics; when false, if the given header already exists in this,
345 * it is overwritten with the passed-in values; if the header doesn't exist
346 * in this, it is set regardless of the value of this parameter
347 * @throws NS_ERROR_INVALID_ARG
348 * if name or value is not a valid header component
349 */
350 void setHeader(in string name, in string value, in boolean merge);
351
352 /**
353 * A stream to which data appearing in the body of this response should be
354 * written.
355 */
356 readonly attribute nsIOutputStream bodyOutputStream;
357
358 /**
359 * Write a string to the response's output stream.
360 *
361 * @note
362 * This method is only guaranteed to work with ASCII data.
363 */
364 void write(in string data);
365 };