Cgi

The main interface with the web request

class Cgi {
CgiConnectionHandle _outputFileHandle;
BufferedInputRange idlol;
immutable
bool acceptsGzip;
immutable
bool keepAliveRequested;
protected
string responseLocation;
version(autoBuffer)
bool autoBuffer;
version(!autoBuffer)
bool autoBuffer;
ubyte[] outputBuffer;
version(preserveData)
immutable(ubyte)[] originalPostData;
const(string[string]) environmentVariables;
immutable(UploadedFile[string]) files;
}

Constructors

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

Initializes it with command line arguments (for easy testing)

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

Initializes it using a CGI or CGI-like interface

this
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
this(BufferedInputRange inputData, string address, ushort _port, int pathInfoStarts, bool _https, void delegate(const(ubyte)[]) _rawDataOutput, void delegate() _flush, bool* closeConnection)

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

Members

Aliases

query
alias query = get

added later

setResponseHeader
alias setResponseHeader = header

I named the original function header after PHP, but this pattern more fits the rest of the Cgi object.

Enums

RequestMethod
enum RequestMethod

the methods a request can be

SameSitePolicy
enum SameSitePolicy

Functions

canOutputHeaders
bool canOutputHeaders()

Returns true if it is still possible to output headers

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

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

close
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.

dispose
void dispose()

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

flush
void flush()

Flushes the pending buffer, leaving the connection open so you can send more.

getCurrentCompleteUri
string getCurrentCompleteUri()

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

getSessionObject
Session!Data getSessionObject()

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

header
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.

isClosed
bool isClosed()

Is the output already closed?

logicalScriptName
string logicalScriptName()

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

onRequestBodyDataReceived
void onRequestBodyDataReceived(size_t receivedSoFar, size_t totalExpected)

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

request
T request(string name, T def)

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.

requireBasicAuth
void requireBasicAuth(string user, string pass, string message, string file, size_t line)

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 to cancel your handler. Do NOT catch the AuthorizationRequiredException exception thrown by this if you want the http basic auth prompt to work for the user!

setCache
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

setCookie
void setCookie(string name, string data, long expiresIn, string path, string domain, bool httpOnly, bool secure, SameSitePolicy sameSitePolicy)

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 .yourdomain.com. Note setCookie() must be called *before* you write() any data to the output.

setResponseContentType
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

setResponseExpires
void setResponseExpires(long when, bool isPublic)

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.

setResponseExpiresRelative
void setResponseExpiresRelative(int whenFromNow, bool isPublic)

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

setResponseLocation
void setResponseLocation(string uri, bool important, string status)

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.

setResponseStatus
void setResponseStatus(string status)
void setResponseStatus(int statusCode)

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.

updateResponseExpires
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.

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

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

writeJson
void writeJson(string json)

Convenience method to set content type to json and write the string as the complete response.

Structs

UploadedFile
struct UploadedFile

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

Variables

accept
immutable(char[]) accept;

The HTTP accept header is the user agent telling what content types it is willing to accept. This is often */*; they accept everything, so it's not terribly useful. (The similar sounding Accept-Encoding header is handled automatically for chunking and gzipping. Simply set gzipResponse = true and cgi.d handles the details, zipping if the user's browser is willing to accept it.)

authorization
immutable(char[]) authorization;

The full authorization string from the header, undigested. Useful for implementing auth schemes such as OAuth 1.0. Note that some web servers do not forward this to the app without taking extra steps. See requireBasicAuth's comment for more info.

cookie
immutable(char[]) cookie;

The unparsed content of the Cookie: header in the request. See also the cookiesstring member for a parsed view of the data.

cookies
immutable(string[string]) cookies;

Separates out the cookie header into individual name/value pairs (which is how you set them!)

cookiesArray
immutable(string[][string]) cookiesArray;

ditto for cookies

filesArray
immutable(UploadedFile[][string]) filesArray;

Represents user uploaded files.

get
immutable(string[string]) get;

Here come the parsed request variables - the things that come close to PHP's _GET, _POST, etc. superglobals in content. *//// The data from your query string in the url, only showing the last string of each name. If you want to handle multiple values with the same name, use getArray. This only works right if the query string is x-www-form-urlencoded; the default you see on the web with name=value pairs separated by the & character

getArray
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 +//// like get, but an array of values per nam

gzipResponse
bool gzipResponse;

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

host
immutable(char[]) host;

The hostname in the request. If one program serves multiple domains, you can use this to differentiate between them.

https
bool https;

Was the request encrypted via https?

isCalledWithCommandLineArguments
bool isCalledWithCommandLineArguments;

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

lastEventId
immutable(char[]) lastEventId;

The HTML 5 draft includes an EventSource() object that connects to the server, and remains open to take a stream of events. My arsd.rtud module can help with the server side part of that. The Last-Event-Id http header is defined in the draft to help handle loss of connection. When the browser reconnects to you, it sets this header to the last event id it saw, so you can catch it up. This member has the contents of that header.

origin
immutable(char[]) origin;

The origin header in the request, if present. Some HTML5 cross-domain apis set this and you should check it on those cross domain requests and websockets.

pathInfo
immutable(char[]) pathInfo;

This is any stuff sent after your program's name on the url, but before the query string. For example, suppose your program is named "app". If the user goes to site.com/app, pathInfo is empty. But, he can also go to site.com/app/some/sub/path; treating your program like a virtual folder. In this case, pathInfo == "/some/sub/path".

port
int port;

On what TCP port number did the server receive the request?

post
immutable(string[string]) post;

The data from the request's body, on POST requests. It parses application/x-www-form-urlencoded data (used by most web requests, including typical forms), and multipart/form-data requests (used by file uploads on web forms) into the same container, so you can always access them the same way. It makes no attempt to parse other content types. If you want to accept an XML Post body (for a web api perhaps), you'll need to handle the raw data yourself.

postArray
immutable(string[][string]) postArray;

ditto for post

postBody
string postBody;

This holds the posted body data if it has not been parsed into post and postArray.

queryString
immutable(char[]) queryString;

The unparsed content of the request query string - the stuff after the ? in your URL. See get[] and getArray[] for a parse view of it. Sometimes, the unparsed string is useful though if you want a custom format of data up there (probably not a good idea, unless it is really simple, like "?username" perhaps.)

referrer
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.

remoteAddress
immutable(char[]) remoteAddress;

The IP address of the user, as we see it. (Might not match the IP of the user's computer due to things like proxies and NAT.)

requestHeaders
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.

requestMethod
immutable(RequestMethod) requestMethod;

The HTTP request verb: GET, POST, etc. It is represented as an enum in cgi.d (which, like many enums, you can convert back to string with std.conv.to()). A HTTP GET is supposed to, according to the spec, not have side effects; a user can GET something over and over again and always have the same result. On all requests, the get[] and getArray[] members may be filled in. The post[] and postArray[] members are only filled in on POST methods.

requestUri
immutable(char[]) requestUri;

The full url if the current request, excluding the protocol and host. requestUri == scriptName ~ pathInfo ~ (queryString.length ? "?" ~ queryString : "");

scriptFileName
immutable(char[]) scriptFileName;

The physical filename of your script

scriptName
immutable(char[]) scriptName;

The full base path of your program, as seen by the user. If your program is located at site.com/programs/apps, scriptName == "/programs/apps".

userAgent
immutable(char[]) userAgent;

The browser's user-agent string. Can be used to identify the browser.

Meta