WebServer documentation

Authors

Richard Frith-Macdonald (rfm@gnu.org)

Date: Generated at 2025-04-12 16:42:20 -0600

Copyright: (C) 2004-2010 Free Software Foundation, Inc.


Contents -

  1. The WebServer class
  2. What is the WebServer class?
  3. Performance and threading
  4. Software documentation for the WebServer class
  5. Software documentation for the WebServerRequest class
  6. Software documentation for the WebServerResponse class
  7. Software documentation for the NSObject(WebServerDelegate) informal protocol
  8. Software documentation for the WebServerDelegate protocol

The WebServer class

What is the WebServer class?

The WebServer class provides the framework for a GNUstep program to act as an HTTP or HTTPS server for simple applications.
It does not attempt to be a general-purpose web server, but is rather intended to permit a program to easily handle requests from automated systems which are intended to control, monitor, or use the services provided by the program in which the class is embedded.
The emphasis is on making it robust/reliable/simple, so you can rapidly develop software using it.
By default, it is a single-threaded, single-process system using asynchronous I/O, so you can easily run it under debug in gdb to fix any bugs in your delegate object.
For performance, it can also operate as a massively multi-threaded process, with separate I/O threads handling groups of hundreds or thousands of simultaneous connections, and a pool of processing threads handling parsing of incoming requests.

The class is controlled by a few straightforward settings and basically operates by handing over requests to its delegate. The delegate must at least implement the [<WebServerDelegate>-processRequest:response:for:] method.

Built-in facilities include -

Performance and threading

The WebServer class essentially works using asynchronous I/O in a single thread. The asynchronous I/O mechanism is capably of reading a request of up to the operating systems network buffer size in a single operation and similarly writing out a response of up to the operating system's network buffer size.
As long as requests and responses are within those limits, it can be assumed that slow processing of a request in the [<WebServerDelegate>-processRequest:response:for:] method will have little impact on efficiency as the WebServer read request and write responses as rapidly as the delegates processing can handle them.
If however the I/O sizes are larger than the buffers, then writing a response will need to be multiple operations and each buffer full of data may need to wait for the next call to the processing method before it can be sent.
So, for large request/response sizes, or other cases where processing a single request at a time is a problem, the WebServer class provides a simple mechanism for supporting multithreaded use.

To use multiple threads, all you need to do is have the delegate implementation of [<WebServerDelegate>-processRequest:response:for:] pass processing to another thread and return NO. When processing is complete, the delegate calls -completedWithResponse: to pass the response back to the WebServer instance for delivery to the client.
NB. the -completedWithResponse: method is safe to call from any thread but all other methods of the class should be called only from the master thread. If a delegate needs to call methods of the WebServer instance in order to handle a request, it should do so in the [<WebServerDelegate>-processRequest:response:for:] method before handing control to another thread.

If the simple threading outlined above is not sufficient for your appplication, a more agressive threading scheme is available.
You may call the -setIOThreads:andPool: method to ask the WebServer instance to use threading internally itself. In this case the low-level I/O operations will be shared across the specified number of I/O threads instead of occurring in the master thread (makes sense if you need to handle a very large number of simultaneous connections). In addition, the parsing of the incoming HTTP request and the generation of the raw data of the outgoing response are performed using threads from the thread pool, so that the I/O threads can concentrate on the low level communications.

With the use of a thread pool, you muse be aware that the -preProcessRequest:response:for: method will be executed by a thread from the pool rather than by the master thread.
This may be useful if you wish to split the processing into part which is thread-safe, and part which uses complex interacting data structures which are hard to make safe (done in the main processing method).

Software documentation for the WebServer class

WebServer : NSObject

Declared in:
WebServer.h

You create an instance of the WebServer class in order to handle incoming HTTP or HTTPS requests on a single port.

Before use, it must be configured using the -setAddress:port:secure: method to specify the address and port and if/how SSL is to be used.

You must also set a delegate to handle incoming requests, and may specify a maximum number of simultaneous connections which may be in progress etc.

In addition to the options which may be set directly in the class, you can provide some configuration via the standard NSDefaults class. This information is set at initialisation of an instance and the class recognises the following defaults keys -

WebServerFrameOptions
A string defining the frame options setting for responses produced by the server (application code can always override this).
If this is not defined, the value DENY is used to prevent responses from being presented inside frames.
If this is defined as an empty string, no X-Frame-Options header is set (unless application code explicitly sets the header in the response).
Unless you use this option (or your application code explicitly sets/removes the header), all responses will have the frame option DENY, which will at least tend to keep security auditors who are afraid of click-jacking attacks happy, even if it serves no other purpose.
WebServerHosts
An array of host IP addresses to list the hosts permitted to send requests to the server. If defined, requests from other hosts will be rejected (with an HTTP 403 response). It may be better to use firewalling to control this sort of thing.
WebServerQuiet
An array of host IP addresses to refrain from logging ... this is useful if (for instance) you have a monitoring process which sends requests to the server to be sure it's alive, and don't want to log all the connections from this monitor.
Not only do we refrain from logging anything but exceptional events about these hosts, connections and requests by these hosts are not counted in statistics we generate.
ReverseHostLookup
A boolean (default NO) which specifies whether the server should lookup the host name for each incoming connection, and refuse connections where no host can be found. The downside of enabling this is that host lookups can be slow and cause performance problems.

To shut down the WebServer, you must call -setAddress:port:secure: with nil arguments. This will stop the server listening for incoming connections and wait for any existing connections to be closed (or to time out).
NB. Once a WebServer instance has been started listening on a port, it is not OK to simply release it without shutting it down... doing that will cause a leak of memory and resources as the instance will continue to operate.

Method summary


baseURLForRequest: 

+ (NSURL*) baseURLForRequest: (WebServerRequest*)request;
Returns the base URL used by the remote client to send the request.

decodeURLEncodedForm: into: 

+ (NSUInteger) decodeURLEncodedForm: (NSData*)data into: (NSMutableDictionary*)dict;
Same as the instance method of the same name.

encodeURLEncodedForm: charset: into: 

+ (NSUInteger) encodeURLEncodedForm: (NSDictionary*)dict charset: (NSString*)charset into: (NSMutableData*)data;
Same as the instance method of the same name.

encodeURLEncodedForm: into: 

+ (NSUInteger) encodeURLEncodedForm: (NSDictionary*)dict into: (NSMutableData*)data;
DEPRECATED... use +encodeURLEncodedForm:charset:into: instead.
Same as the instance method of the same name.

escapeHTML: 

+ (NSString*) escapeHTML: (NSString*)str;
Same as the instance method of the same name.

linkPath: relative: query: ,...

+ (NSURL*) linkPath: (NSString*)newPath relative: (NSURL*)oldURL query: (NSDictionary*)fields,...;
Returns a new URL formed by putting the newPath in the oldURL and appending a query string containing the fields specified in the fields argument (optionally extended/overridden by any other fields defined as key/value pairs in the nil terminated list of additional arguments.
If the oldURL is nil, then the new URL will be a relative URL containing just the path and query string.
If newPath is an absolute path, it replaces the path from oldURL, otherwise it replaces the last path component from uldURL.

matchIP: to: 

+ (BOOL) matchIP: (NSString*)address to: (NSString*)pattern;
Convenience function to check to see if a particular IP address matches anything in a comma separated list of IP addresses or masks.
This currently handles simple IPv4 addresses, and masks in the format nnn.nnn.nnn.nnn/bb where bb is the number of bits of the mask to match against the address (eg. 192.168.11.0/24).

parameter: at: from: 

+ (NSData*) parameter: (NSString*)name at: (NSUInteger)index from: (NSDictionary*)params;
Same as the instance method of the same name.

parameterString: at: from: charset: 

+ (NSString*) parameterString: (NSString*)name at: (NSUInteger)index from: (NSDictionary*)params charset: (NSString*)charset;
Same as the instance method of the same name.

redirectRequest: response: to: 

+ (BOOL) redirectRequest: (WebServerRequest*)request response: (WebServerResponse*)response to: (id)destination;
Convenience method to set up a temporary redirect to the specified URL using the supplied response data. The method returns YES so that it is reasonable to pass its return value back directly as the return value for a call to the [<WebServerDelegate>-processRequest:response:for:] method.
If destination is an NSURL, the redirection is done to the specified location, otherwise arguments description is taken as a local path to be used with the base URL of the request.

accessRequest: response: 

- (BOOL) accessRequest: (WebServerRequest*)request response: (WebServerResponse*)response;
This method is called for each incoming request, and checks that the requested resource is accessible (basic user/password access control).
The method returns YES if access is granted, or returns NO and sets the appropriate response values if access is refused.
If access is refused by this method, the delegate is not informed of the request at all... so this forms an initial access control mechanism, but if it is passed, the delegate is still free to implement its own additional access control within the [<WebServerDelegate>-processRequest:response:for:] method.
The access control is managed by the WebServerAccess user default, which is a dictionary whose keys are paths, and whose values are dictionaries specifying the access control for those paths. Access control is done on the basis of the longest matching path.
Each access control dictionary contains an authentication realm string (keyed on Realm) and a dictionary containing username/password pairs (keyed on Users).
eg.
 WebServerAccess = {
   "" = {
     Realm = "general";
     Users = {
       Fred = 1942;
     };
   };
 };
 

address 

- (NSString*) address;
Return the address the receiver listens for connections on, or nil if it is not listening.

blockOnAuthenticationFailure 

- (NSTimeInterval) blockOnAuthenticationFailure;
If greater than zero, the returned value is the number of seconds for which the server should block subsequent requests from the offending address, otherwise (returned value is zero) bocking is not performed when an authentication attem,pt fails.
Blocked requests will get a 429 response.

closeConnectionAfter: 

- (void) closeConnectionAfter: (WebServerResponse*)response;
Instructs the server that the connection handlind the current request should be closed once the response has been sent back to the client.

completedWithResponse: 

- (void) completedWithResponse: (WebServerResponse*)response;

This may only be called in the case where a call to the delegate's [<WebServerDelegate>-processRequest:response:for:] method to process a request returned NO, indicating that the delegate would handle the request asynchronously and complete it later.

In such a case, the thread handling the request in the delegate must call this method upon completion (passing in the same request parameter that was passed to the delegate) to inform the WebServer instance that processing of the request has been completed and that it should now take over the job of sending the response to the client process.

If the -streamData:withResponse: method has been called with the supplied response object, calling this method terminated the streamed response to the client.


connections 

- (NSArray*) connections;
Returns an array containing an object representing each connection currently active for this server instance.

decodeURLEncodedForm: into: 

- (NSUInteger) decodeURLEncodedForm: (NSData*)data into: (NSMutableDictionary*)dict;
Decode an application/x-www-form-urlencoded form and store its contents into the supplied dictionary.
The resulting dictionary keys are strings.
The resulting dictionary values are arrays of NSData objects.
You probably don't need to call this method yourself... more likely you will use the -parameters: method instead.
NB. For forms POST-ed using multipart/form-data you don't need to perform any explicit decoding as this will already have been done for you and the decoded form will be presented as the request GSMimeDocument subclass. The fields of the form will be the component parts of the content of the request and can be accessed using the standard GSMimeDocument methods.
This method returns the number of fields actually decoded.

delegate 

- (id) delegate;
Return this web server's delegate.

encodeURLEncodedForm: charset: into: 

- (NSUInteger) encodeURLEncodedForm: (NSDictionary*)dict charset: (NSString*)charset into: (NSMutableData*)data;
Encode an application/x-www-form-urlencoded form and store its representation in the supplied data object.
The dictionary contains the form, with keys as data objects or strings, and values as arrays of values to be placed in the data. Each value in the array may be a data object or a string.
As a special case, a value may be a data object or a string rather than an array... this is treated like an array of one value.
All non data keys and values are converted to data using the specified charset (or utf-8 if charset is nil/unrecognized or where the key/value cannot be represented using the specified charset).
This method returns the number of values actually encoded.

encodeURLEncodedForm: into: 

- (NSUInteger) encodeURLEncodedForm: (NSDictionary*)dict into: (NSMutableData*)data;
DEPRECATED... use -encodeURLEncodedForm:charset:into: instead.

escapeHTML: 

- (NSString*) escapeHTML: (NSString*)str;
Escapes special characters in str for use in an HTML page.
This converts & to &amp; for instance, and replaces non-ascii characters with the appropriate numeric entity references.

incrementalDataForRequest: 

- (NSData*) incrementalDataForRequest: (WebServerRequest*)request;
Returns a data object containing any data read for the body of a partially read request since the last call for the same request.

init 

- (id) init;
Initialises the receiver to run on the processes main thread (as returned by [NSThread +mainThread] .

initForThread: 

- (id) initForThread: (NSThread*)aThread;
This is a designated initialiser for the class.
Initialises the WebServer instance to operate using the specified thread as the 'master' thread. If aThread is nil, [NSThread +mainThread] is used as the master thread for the newly initialised instance.
If the current thread is not the same as the specified master thread, this method will not return until the master thread's run loop had run to handle the initialisation.

isCompletedRequest: 

- (BOOL) isCompletedRequest: (WebServerRequest*)request;
Returns YES if the request has been completely read, NO if it still needs more data to be read from the client and parsed before it is complete (ie incremental parsing is in progress).

isSecure 

- (BOOL) isSecure;
Returns YES if the server is for HTTPS (encrypted connections), NO otherwise.

isTrusted 

- (BOOL) isTrusted;
Returns YES if the server is running behind a secure proxy inside a demilitarised zone (DMZ).

parameter: at: from: 

- (NSData*) parameter: (NSString*)name at: (NSUInteger)index from: (NSDictionary*)params;
Returns the index'th data parameter for the specified name.
Matching of names is case-insensitive
If there are no data items for the name, or if the index is too large for the number of items which exist, this returns nil.

parameter: from: 

- (NSData*) parameter: (NSString*)name from: (NSDictionary*)params;
Calls -parameter:at:from: with an index of zero.

parameterString: at: from: 

- (NSString*) parameterString: (NSString*)name at: (NSUInteger)index from: (NSDictionary*)params;
Calls -parameterString:at:from:charset: with a nil charset so that UTF-8 encoding is used for string conversion.

parameterString: at: from: charset: 

- (NSString*) parameterString: (NSString*)name at: (NSUInteger)index from: (NSDictionary*)params charset: (NSString*)charset;
Calls -parameter:at:from: and, if the result is non-nil converts the data to a string using the specified mime characterset, (if charset is nil, UTF-8 is used).

parameterString: from: 

- (NSString*) parameterString: (NSString*)name from: (NSDictionary*)params;
Calls -parameterString:at:from:charset: with an index of zero and a nil value for charset (which causes data to be treated as UTF-8).

parameterString: from: charset: 

- (NSString*) parameterString: (NSString*)name from: (NSDictionary*)params charset: (NSString*)charset;
Calls -parameterString:at:from:charset: with an index of zero.

parameters: 

- (NSMutableDictionary*) parameters: (WebServerRequest*)request;
Extracts request parameters from the HTTP query string and from the request body (if it was application/x-www-form-urlencoded or multipart/form-data) and return the extracted parameters as a mutable dictionary whose keys are the parameter names and whose values are arrays containing the data for each parameter.
You should call this no more than once per request, storing the result and using it as an argument to the methods used to extract particular parameters.
Parameters from the request data are added to any found in the query string.
Values provided as multipart/form-data are also available in a more flexible format (see GSMimeDocument ) as the content of the request.

port 

- (NSString*) port;
Return the port the receiver listens for connections on, or nil if it is not listening.

produceResponse: fromStaticPage: using: 

- (BOOL) produceResponse: (WebServerResponse*)aResponse fromStaticPage: (NSString*)aPath using: (NSDictionary*)map;
Loads a template file from disk and places it in aResponse as content whose mime type is determined from the file extension using the provided mapping (or a simple built-in default mapping if map is nil).
Text responses use utf-8 enmcoding.
If you have a dedicated web server for handling static pages (eg images) it is better to use that rather than vending static pages using this method. It's unlikely that this method can be as efficient as a dedicated server. However this mechanism is adequate for moderate throughputs.

produceResponse: fromTemplate: using: 

- (BOOL) produceResponse: (WebServerResponse*)aResponse fromTemplate: (NSString*)aPath using: (NSDictionary*)map;
Loads a template file from disk and places it in aResponse as content of type 'text/html' with a charset of 'utf-8'.
The argument aPath is a path relative to the root path set using the -setRoot: method.
Substitutes values into the template from map using the -substituteFrom:using:into:depth: method.
Returns NO if the template could not be read or if any substitution failed. In this case no value is set in the response.
If the response is actually text of another type, or you want another characterset used, you can change the content type header in the request after you call this method.
Note that, although the map is nominally an NSDictionary instance, it can in fact be any object which responds to the [NSDictionary -objectForKey:] message by returning a string or nil.

setAddress: port: secure: 

- (BOOL) setAddress: (NSString*)anAddress port: (NSString*)aPort secure: (NSDictionary*)secure;
Sets the listenng address, port and security information for the receiver... without this the receiver will not listen for incoming requests.
If anAddress is nil or empty, the receiver will listen on all available network interfaces.
If secure is nil then the receiver listens on aPort for HTTP requests.
If secure is a dictionary, it must either contain Proxy with the value set to YES (to configure the receiver to accept HTTP connections but treat them as coming via a secure proxy), or it must contain CertificateFile, KeyFile and Password to configure the server to use the specified certificate and key files (which it will access using the password) to support HTTPS rather than HTTP. Alternatively both may be specified (if the connections are coming from a secure proxy and the connection between the proxy and the server is also secure.
If the dictionary also contains HSTS then this must be a non-negative integer value specifying the number of seconds to set in the Strict-Transport-Security header (defaults to 1 year).
The secure dictionary may also contain other dictionaries keyed on IP addresses, and if the address that an incoming connection arrived on matches the key of a dictionary, that dictionary is used to provide the certificate information, with the top-level values being used as a fallback.
This method returns YES on success, NO on failure... if it returns NO then the receiver will not be capable of handling incoming web requests!
Typically a failure will be due to an invalid address or port being specified... a port may not already be in use and may not be in the range up to 1024 (unless running as the super-user).
Call this with a nil/empty port argument to shut the server down as soon as all current connections are closed (and refuse new incoming connections).
NB. Changing of this configuration must only occur in the master thread so this method, if called from another thread, will need to perform some internal operations in the master thread before it returns.

setBlockOnAuthenticationFailure: 

- (void) setBlockOnAuthenticationFailure: (NSTimeInterval)ti;
Sets the time for which requests from the same host should be blocked if a request from the host attempts to authenticate and fails.
The default is 1 second but setting a value of zero or less turns this feature off (sets the blocking interval to zero).
The -[WebServerResponse block:] method may be used to set a different timeout in response to a particular request.

setConnectionTimeout: 

- (void) setConnectionTimeout: (NSTimeInterval)aDelay;
Sets the time after which an idle connection should be shut down.
Default is 30.0

setDelegate: 

- (void) setDelegate: (id)anObject;
Sets the delegate object which processes requests for the receiver.

setDurationLogging: 

- (void) setDurationLogging: (BOOL)aFlag;
Sets a flag to determine whether logging of request and connection durations is to be performed.
If this is YES then the duration of requests and connections will be logged using the [<WebServerDelegate>-webLog:for:] method.
The request duration is calculated from the point where the first byte of data in the request is read to the point where the response has been completely written.
This is useful for debugging and where a full audit trail is required.

setFoldHeaders: 

- (void) setFoldHeaders: (BOOL)aFlag;
Sets a flag to determine whether the header lines in responses are folded if they are over 78 characters (off by default).
Some buggy clients don't support folding, but do accept long header lines, and this compatibility setting may be used to allow such clients to handle the server's responses (though this may of course break things for other clients).
This setting applies to any connection established after the setting is changed.
Because use of this setting could result in a faulty response (one with a long header) being sent to a client which correctly handles folded headers, it's also controllable individually for each response, so the same process can respond both to clients which expect folded headers and clients which expect long headers (see [WebServerResponse -setFoldHeaders:] ).

setIOThreads: andPool: 

- (void) setIOThreads: (NSUInteger)threads andPool: (NSInteger)poolSize;
Sets the number of threads used to process basic I/O and the size of the thread pool used by the receiver for handling parsing of incoming requests, generation of outgoing responses, and pre/post processing of requests by the delegate.
This defaults to no use of threads .
NB. Since each thread typically uses two file descriptors to handle any inter-thread message dispatch, enabling threading will use at least two extra file descriptors per thread... this may easily cause you to go beyound the per-process limit imposed by the operating system and you may wish to configure a smaller connection limit or tune the O/S to allow more descriptors.

setLogRawIO: 

- (void) setLogRawIO: (BOOL)aFlag;
Sets a flag to determine whether I/O logging is to be performed.
If this is YES then all incoming requests and their responses will be logged using the [<WebServerDelegate>-webLog:for:] method.

setMaxBodySize: 

- (void) setMaxBodySize: (NSUInteger)max;
Sets the maximum size of an uploaded request body.
The default is 4M bytes.
The HTTP failure response for too large a body is 413.

setMaxConnectionDuration: 

- (void) setMaxConnectionDuration: (NSTimeInterval)max;
Sets the maximum total duration of the incoming requests handled on an individual connection. After this many requests are handled, the connection is closed (so another client may get a chance to connect).
The default is 10.0 seconds.

setMaxConnectionRequests: 

- (void) setMaxConnectionRequests: (NSUInteger)max;
Sets the maximum size number of incoming requests to be handled on an individual connection. After this many requests are handled, the connection is closed (so another client may get a chance to connect).
The default is 100 requests.

setMaxConnections: 

- (void) setMaxConnections: (NSUInteger)max;
Sets the maximum number of simultaneous connections with clients.
The default is 128.
A value of zero permits unlimited connections.
If this limit is reached, the behavior of the software depends upon the value set by the -setMaxConnectionsReject: method.

setMaxConnectionsPerHost: 

- (void) setMaxConnectionsPerHost: (NSUInteger)max;
Sets the maximum number of simultaneous connections with a particular remote host.
The default is 32.
A value of zero permits unlimited connections.
If this value is greater than that of -setMaxConnections: then it will have no effect as the maximum number of connections from one host cannot be reached.
The HTTP failure response for too many connections from a host is 503.

setMaxConnectionsReject: 

- (void) setMaxConnectionsReject: (BOOL)reject;

This setting (default value NO) determines the behavior of the software when the number of simultaneous incoming connections exceeds the value set by the -setMaxConnections: method.

If reject is NO, the software will simply not accept the incoming connections until some earlier connection is terminated, so the incoming connections will be queued by the operating system and may time-out if no connections become free quickly enough for them to be handled. In the case of a huge number of incoming connections the 'listen' queue of the operating system may fill up and connections may be lost altogether.

If reject is yes, then the service will set aside a slot for one extra connection and, when the number of permitted connections is exceeded, the server will accept the first additional connection, send back an HTTP 503 response, and drop the additional connection again. This means that clients should receive a 503 response rather than finding that their connection attempts block and possible time out.


setMaxKeepalives: 

- (void) setMaxKeepalives: (NSUInteger)max;
Sets the maximum number of connections in each I/O thread which are to be kept in a 'keepalive' state waiting for a new request once a request completes.
The permitted range is currently from 0 to 1000, with settings being limited to that range. The default value is 0, which means that the number of idle connections per thread is unlimited (though the total number of connections and number per host is still constrained).

setMaxRequestSize: 

- (void) setMaxRequestSize: (NSUInteger)max;
Sets the maximum size of an incoming request (including all headers, but not the body).
The default is 8K bytes.
The HTTP failure response for too large a request is 413.

setPermittedMethods: 

- (void) setPermittedMethods: (NSSet*)s;
Sets the HTTP methods which may be used by the server.
Any incoming request using a method not listed in the permitted set is rejected with an HTTP 405 response and an Allow header saying which methods ARE allowed.
The default set contains only the GET and POST methods.

setPort: secure: 

- (BOOL) setPort: (NSString*)aPort secure: (NSDictionary*)secure;
Deprecated... use -setAddress:port:secure: instead.

setRoot: 

- (void) setRoot: (NSString*)aPath;
Set root path for loading template files from.
Templates may only be loaded from within this directory.

setSecureProxy: 

- (void) setSecureProxy: (BOOL)aFlag;
Configures a flag to say whether the receiver is running behind a secure proxy (in a DMZ) and all connections are to be considered as having come in via https.
If this is not set, requests are not trusted and some headers may be deleted from them.

setStrictTransportSecurity: 

- (void) setStrictTransportSecurity: (NSUInteger)seconds;
Specifies the number of seconds HSTS is to be turned on for when responding to a request on a secure connection (including via a secure proxy).
The Strict-Transport-Security header is automatically set in the response to any incoming request (but code handling the request may alter that).
The default setting is 1 year (31536000 seconds), while a setting of zero turns off HSTS.

setSubstitutionLimit: 

- (void) setSubstitutionLimit: (NSUInteger)depth;
Sets the maximum recursion depth allowed for substitutions into templates. This defaults to 4.

setUserInfo: forRequest: 

- (void) setUserInfo: (NSObject*)info forRequest: (WebServerRequest*)request;
Stores additional user information with a request.
This information may be retrieved later using the -userInfoForRequest: method.

setVerbose: 

- (void) setVerbose: (BOOL)aFlag;
Sets a flag to determine whether verbose logging is to be performed.
If this is YES then all incoming requests and their responses will be logged using the [<WebServerDelegate>-webLog:for:] method.
Setting this to YES automatically sets duration logging to YES as well, though you can then call -setDurationLogging: to set it back to NO.
This is useful for debugging and where a full audit trail is required.

streamData: withResponse: 

- (BOOL) streamData: (NSData*)data withResponse: (WebServerResponse*)response;

This may only be called in the case where a call to the delegate's [<WebServerDelegate>-processRequest:response:for:] method to process a request returned NO, indicating that the delegate would handle the request asynchronously and complete it later.

In this case the response content should be empty, and instead of sending the response in one go the server will send the response header followed by the supplied data. Subsequent calls to this method using the same response object will send more data to the client.
The code which calls this method must terminate the sequence of calls with a call to the -completedWithResponse: method.

The method returns YES is the data is scheduled for sending to the client, NO if the client has already dropped the connection and there is no point attempting to stream more data.


strictTransportSecurity 

- (NSUInteger) strictTransportSecurity;
Returns the number of seconds set for HSTS for this server.
This will be zero if the server is not using a secure connection or if HSTS has been disabled by the -setStrictTransportSecurity: method.

substituteFrom: using: into: depth: 

- (BOOL) substituteFrom: (NSString*)aTemplate using: (NSDictionary*)map into: (NSMutableString*)result depth: (NSUInteger)depth;
Perform substitutions replacing the markup in aTemplate with the values supplied by map and appending the results to the result.
Substitutions are recursive, and the depth argument is used to specify the current recursion depth (you should normally call this method with a depth of zero at the start of processing a template).
Any value inside SGML comment delimiters ('<!--' and '-->') is treated as a possible key in map and the entire comment is replaced by the corresponding map value (unless it is nil). Recursive substitution is done unless the mapped value starts with an SGML comment.
While the map is nominally a dictionary, in fact it may be any object which responds to the objectForKey: method by returning an NSString or nil, you can therefore use it to dynamically replace tokens within a template page in an intelligent manner.
The method returns YES on success, NO on failure (depth too great).
You don't normally need to use this method directly... call the -produceResponse:fromTemplate:using: method instead.

threadPool 

- (GSThreadPool*) threadPool;
Returns the thread pool used by this instance.

userInfoForRequest: 

- (NSObject*) userInfoForRequest: (WebServerRequest*)request;
Retrieves additional user information (previously set using the -setUserInfo:forRequest: method) from a request.

Software documentation for the WebServerRequest class

WebServerRequest : GSMimeDocument

Declared in:
WebServer.h
Do not attempt to subclass the WebServerRequest class to add instance variables... the public interface is intended to keep your compiler happy, but does not guarantee that the instance variable layout is actually what it seems.

Method summary


address 

- (NSString*) address;
Convenience method returning the address of the client.
This is taken from the x-forwarded-for header if possible, but from the x-remote-address header if the request was not forwarded through a proxy.

Software documentation for the WebServerResponse class

WebServerResponse : GSMimeDocument

Declared in:
WebServer.h
Do not attempt to subclass the WebServerResponse class to add instance variables... the public interface is intended to keep your compiler happy, but does not guarantee that the instance variable layout is actually what it seems.

Method summary


block: 

- (void) block: (NSTimeInterval)ti;
Blocks (for the time interval specified) further incoming requests from the same source as the one we are responding to.
A ti value more than zero establishes a new blocking.
A ti value of zero cancels any existing blocking.
A ti value of less than zero is ignored and the value returned by the -[WebServer blockOnAuthenticationFailure] method is used instead.
Subsequent requests from the blocked source will be responded to with a 429 status code until the blocking expires.

setFoldHeaders: 

- (void) setFoldHeaders: (BOOL)aFlag;
Behaves as [WebServer -setFoldHeaders:] but applies only to the headers in the receiver.

setUserInfo: 

- (void) setUserInfo: (NSObject*)info;
Sets additional information attached to the response which may then be retrieved with the -userInfo method.

userInfo 

- (NSObject*) userInfo;
Returns the obect previously set with the -setUserInfo: method or nil if nothing has been set.

Software documentation for the NSObject(WebServerDelegate) informal protocol

NSObject(WebServerDelegate)

Declared in:
WebServer.h
This is an informal protocol documenting optional methods which will be used if implemented by the delegate.

Method summary


completedResponse: duration: 

- (void) completedResponse: (WebServerResponse*)response duration: (NSTimeInterval)timeInterval;
Informs the handler (if any) associated with the response that the server has written the response to the network. The timeInterval is measured between the point when the server started reading the request and the point at which it finished writing the response.

incrementalRequest: for: 

- (uint32_t) incrementalRequest: (WebServerRequest*)request for: (WebServer*)http;
If your delegate implements this method, it will be called before the first call to handle a request (ie before -preProcessRequest:response:for: or -processRequest:response:for:) to provide the delegate with the request header information and allow it to decide whether the request body should be processed incrementally (return value is non-zero) or not (return value is zero). The returned value is treated as a guide to how much request data should be buffered at a time.
This method is called before any HTTP basic authentication is done, and may (if threading is turned on) be called from a thread other than the master one.
If your delegate turns on incremental parsing for a request, then any time that more incoming data is read, the web server class will look at how much data it has and decide (based on the return value from this method) to call your -processRequest:response:for: method (preceded by -preProcessRequest:response:for: if it is implemented) so that you can handle the new request data.
Your code can check to see if the request is complete by using the -isCompletedRequest: method, and can check for the latest data added to the request body using the * -incrementalDataForRequest: method.

postProcessRequest: response: for: 

- (void) postProcessRequest: (WebServerRequest*)request response: (WebServerResponse*)response for: (WebServer*)http;
If your delegate implements this method, it will be called by the -completedWithResponse: method before the response data is actually written to the client.
This method may re-write the response, changing the result of the earlier methods.
You may use the [WebServer -userInfoForRequest:] method to obtain any information passed from an earlier stage of processing.
NB. if threading is turned on this method may be called from a thread other than the master one.

preProcessRequest: response: for: 

- (BOOL) preProcessRequest: (WebServerRequest*)request response: (WebServerResponse*)response for: (WebServer*)http;
If your delegate implements this method, it will be called before the [<WebServerDelegate>-processRequest:response:for:] method and with the same parameters.
If this method returns YES, then it is assumed to have completed the processing of the request and the main [<WebServerDelegate>-processRequest:response:for:] method is not called. Otherwise processing continues as normal.
You may use the [WebServer -setUserInfo:forRequest:] method to pass information to the [<WebServerDelegate>-processRequest:response:for:] and/or -postProcessRequest:response:for: methods.
NB. This method is called before any HTTP basic authentication is done, and may (if threading is turned on) be called from a thread other than the master one.

webAlert: for: 

- (void) webAlert: (NSString*)message for: (WebServer*)http;
Log an error or warning... if the delegate does not implement this method, the message is logged to stderr using the NSLog function.

webAudit: for: 

- (void) webAudit: (NSString*)message for: (WebServer*)http;
Log an audit record... if the delegate does not implement this method, the message is logged to stderr.
The logged record is similar to the Apache common log format, though it differs after the timestamp:
ip address
the address of the client host making the request
ident
not currently implemented... '-' as placeholder
user
the remote user name from the authorization header, or '-'
timestamp
the date/time enclosed in square brackets
command
The command sent in the request... as a quoted string
agent
The user-agent header from the request... as a quoted string
result
The initial response line... as a quoted string

webLog: for: 

- (void) webLog: (NSString*)message for: (WebServer*)http;
Log a debug... if the delegate does not implement this method, no logging is done.

Software documentation for the WebServerDelegate protocol

WebServerDelegate

Declared in:
WebServer.h
This protocol is implemented by a delegate of a WebServer instance in order to allow the delegate to process requests which arrive at the server.

Method summary


processRequest: response: for: 

- (BOOL) processRequest: (WebServerRequest*)request response: (WebServerResponse*)response for: (WebServer*)http;
Process the HTTP request whose headers and data are provided in a GSMimeDocument subclass.
Extra headers are created as follows -
x-http-method
The method from the HTTP request (eg. GET or POST)
x-http-path
The path from the HTTP request, or an empty string if there was no path.
x-http-query
The query string from the HTTP request or an empty string if there was no query.
x-http-scheme
Returns the URL scheme used (http or https) to access the server. This is https if the request arrived on an encrypted connection or if the server is configured as being behind a secure proxy.
x-http-version
The version from the HTTP request.
x-local-address
The IP address of the local host receiving the request.
x-local-port
The port of the local host receiving the request.
x-remote-address
The IP address of the host that the request came from.
x-remote-port
The port of the host that the request came from.
x-http-username
The username from the 'authorization' header if the request supplied HTTP basic authentication.
x-http-password
The password from the 'authorization' header if the request supplied HTTP basic authentication.
x-cert-issuer
The certificate issuer (RFC4514) if the request connection was authenticated with a TLS/SSL certificate or if a secure proxy is in use and the proxy set this header. NB the header from a secure proxy takes precedence.
x-cert-owner
The certificate subject/owner (RFC4514) if the request connection was authenticated with a TLS/SSL certificate or if a secure proxy is in use and the proxy set this header. NB the header from a secure proxy takes precedence.
x-cert-owner-proxy
Used if the proxy provides a certificate to identify itself.
x-cert-issuer-proxy
Used if the proxy provides a certificate to identify itself.
x-count-requests
The number of requests being processed at the point when this request started (includes this request).
x-count-connections
The number of connections established to the WebServer at the point when this request started (including the connection this request arrived on).
x-count-connected-hosts
The number of connected hosts (IP addresses) at the point when this request started (including the host which sent this request).
x-count-host-connections
The number of connections to the web server from the host which sent this request at the point when this request started (includes the connection that this request arrived on).
On completion, the method must modify response (an instance of a subclass of GSMimeDocument) to contain the data and headers to be sent out.
The 'content-length' header need not be set in the response as it will be overridden anyway.
The special 'HTTP' header will be used as the response/status line. If not supplied, 'HTTP/1.1 200 Success' or 'HTTP/1.1 204 No Content' will be used as the response line, depending on whether the data is empty or not.
If an exception is raised by this method, the response produced will be set to 'HTTP/1.0 500 Internal Server Error' and the connection will be closed.
If the method returns YES, the WebServer instance sends the response to the client process which made the request.
If the method returns NO, the WebServer instance assumes that the delegate is processing the request asynchronously, either in another thread or with completion being triggered by an asynchronous I/O event. The server takes no action respond to the request until the delegate calls [WebServer -completedWithResponse:] to let it know that processing is complete and the response should at last be sent out.
This method is always called in the master thread of your WebServer instance (usually the main thread of your application).