The main interface with the web request

class Cgi {
CgiConnectionHandle _outputFileHandle;
BufferedInputRange idlol;
bool acceptsGzip;
bool keepAliveRequested;
string responseLocation;
bool autoBuffer;
bool autoBuffer;
ubyte[] outputBuffer;
CgiTester testInProcess;
immutable(ubyte)[] originalPostData;
string postJson;
const(string[string]) environmentVariables;
immutable(char[]) host;
immutable(char[]) origin;
immutable(char[]) userAgent;
immutable(char[]) pathInfo;
immutable(char[]) scriptName;
immutable(char[]) scriptFileName;
immutable(char[]) authorization;
immutable(char[]) accept;
immutable(char[]) lastEventId;
immutable(RequestMethod) requestMethod;
immutable(char[]) queryString;
immutable(char[]) cookie;
immutable(char[]) requestUri;
immutable(char[]) remoteAddress;
bool https;
int port;
immutable(string[string]) post;
immutable(string[string]) cookies;
immutable(UploadedFile[string]) files;
immutable(string[][string]) postArray;
immutable(string[][string]) cookiesArray;


this(string[] args, void delegate(const(ubyte)[]) _rawDataOutput = null)

Initializes it with command line arguments (for easy testing)

this(long maxContentLength = defaultMaxContentLength, in string[string] env = null, const(ubyte)[] delegate() readdata = null, void delegate(const(ubyte)[]) _rawDataOutput = null, void delegate() _flush = null)

Initializes it using a CGI or CGI-like interface

this(BufferedInputRange ir, bool* closeConnection)

Initializes the cgi from completely raw HTTP data. The ir must have a Socket source. *closeConnection will be set to true if you should close the connection after handling this request

this(BufferedInputRange inputData, string address, ushort _port, int pathInfoStarts = 0, bool _https = false, void delegate(const(ubyte)[]) _rawDataOutput = null, void delegate() _flush = null, bool* closeConnection = null)

Initializes it from raw HTTP request data. GenericMain uses this when you compile with -version=embedded_httpd.



enum RequestMethod

the methods a request can be


bool canOutputHeaders()

Returns true if it is still possible to output headers

void clearCookie(string name, string path = null, string domain = null)

Clears a previously set cookie with the given name, path, and domain.

void close()

Flushes the buffers to the network, signifying that you are done. You should always call this explicitly when you are done outputting data.

void dispose()

Cleans up any temporary files. Do not use the object after calling this.

string getCurrentCompleteUri()

This gets a full url for the current request, including port, protocol, host, path, and query

Session!Data getSessionObject()

Gets a session object associated with the cgi request. You can use different type throughout your application.

void header(string h)

Adds a custom header. It should be the name: value, but without any line terminator. For example: header("X-My-Header: Some value"); Note you should use the specialized functions in this object if possible to avoid duplicates in the output.

bool isClosed()

Is the output already closed?

string logicalScriptName()

You can override this if your site base url isn't the same as the script name

void onRequestBodyDataReceived(size_t receivedSoFar, size_t totalExpected)

you can override this function to somehow react to an upload in progress.

T request(in string name, in T def = T.init)

Gets a request variable as a specific type, or the default value of it isn't there or isn't convertible to the request type.

void requireBasicAuth(string user, string pass, string message = null)

Very simple method to require a basic auth username and password. If the http request doesn't include the required credentials, it throws a HTTP 401 error, and an exception.

void setCache(bool allowCaching)

Very simple caching controls - setCache(false) means it will never be cached. Good for rapidly updated or sensitive sites. setCache(true) means it will always be cached for as long as possible. Best for static content. Use setResponseExpires and updateResponseExpires for more control

void setCookie(string name, string data, long expiresIn = 0, string path = null, string domain = null, bool httpOnly = false, bool secure = false)

Sets an HTTP cookie, automatically encoding the data to the correct string. expiresIn is how many milliseconds in the future the cookie will expire. TIP: to make a cookie accessible from subdomains, set the domain to Note setCookie() must be called *before* you write() any data to the output.

void setResponseContentType(string ct)

Sets the content type of the response, for example "text/html" (the default) for HTML, or "image/png" for a PNG image

void setResponseExpires(long when, bool isPublic = false)

Sets the Expires: http header. See also: updateResponseExpires, setPublicCaching The parameter is in unix_timestamp * 1000. Try setResponseExpires(getUTCtime() + SOME AMOUNT) for normal use. Note: the when parameter is different than setCookie's expire parameter.

void setResponseExpiresRelative(int whenFromNow, bool isPublic = false)

Sets a cache-control max-age header for whenFromNow, in seconds.

void setResponseLocation(string uri, bool important = true, string status = null)

Sets the location header, which the browser will redirect the user to automatically. Note setResponseLocation() must be called *before* you write() any data to the output. The optional important argument is used if it's a default suggestion rather than something to insist upon.

void setResponseStatus(string status)

Sets the HTTP status of the response. For example, "404 File Not Found" or "500 Internal Server Error". It assumes "200 OK", and automatically changes to "302 Found" if you call setResponseLocation(). Note setResponseStatus() must be called *before* you write() any data to the output.

void updateResponseExpires(long when, bool isPublic)

This is like setResponseExpires, but it can be called multiple times. The setting most in the past is the one kept. If you have multiple functions, they all might call updateResponseExpires about their own return value. The program output as a whole is as cacheable as the least cachable part in the chain. setCache(false) always overrides this - it is, by definition, the strictest anti-cache statement available. If your site outputs sensitive user data, you should probably call setCache(false) when you do, to ensure no other functions will cache the content, as it may be a privacy risk. Conversely, setting here overrides setCache(true), since any expiration date is in the past of infinity.

void write(const(void)[] t, bool isAll = false, bool maybeAutoClose = true)

Writes the data to the output, flushing headers if they have not yet been sent.


struct UploadedFile

This represents a file the user uploaded via a POST request.


immutable(UploadedFile[][string]) filesArray;

Represents user uploaded files.

immutable(string[string]) get;

Here come the parsed request variables - the things that come close to PHP's _GET, _POST, etc. superglobals in content.

immutable(string[][string]) getArray;

Use these if you expect multiple items submitted with the same name. btw, assert(getname is getArrayname[$-1); should pass. Same for post and cookies. the order of the arrays is the order the data arrives

bool gzipResponse;

Set to true and use cgi.write(data, true); to send a gzipped response to browsers who can accept it

bool isCalledWithCommandLineArguments;

Set to true if and only if this was initialized with command line arguments

immutable(char[]) referrer;

The Referer header from the request. (It is misspelled in the HTTP spec, and thus the actual request and cgi specs too, but I spelled the word correctly here because that's sane. The spec's misspelling is an implementation detail.) It contains the site url that referred the user to your program; the site that linked to you, or if you're serving images, the site that has you as an image. Also, if you're in an iframe, the referrer is the site that is framing you.

immutable(string[string]) requestHeaders;

What follows is data gotten from the HTTP request. It is all fully immutable, partially because it logically is (your code doesn't change what the user requested...) and partially because I hate how bad programs in PHP change those superglobals to do all kinds of hard to follow ugliness. I don't want that to ever happen in D.