This is NOT ACTUALLY an input range! It is too different. Historical mistake kinda.
The main interface with the web request
To use this thing:
WEBSOCKET SUPPORT:
breaks down a url encoded string
breaks down a url encoded string, but only returns the last value of any array
use this for testing or other isolated things
url encodes the whole string
url encodes a whole string
Makes a data:// uri that can be used as links in most newer browsers (IE8+).
Encodes all but the explicitly unreserved characters per rfc 3986 Alphanumeric and -_.~ are the only ones left unencoded name is borrowed from php
You can customize your server by subclassing the appropriate server. Then, register your subclass at compile time with the registerEventIoServer template, or implement your own main function and call it yourself.
If you want to use a subclass of Cgi with generic main, use this mixin.
If you are doing a custom cgi class, mixing this in can take care of the required constructors for you
Use this instead of writing your own main
Represents a url that can be broken down or built up through properties
-version=plain_cgi The default - a traditional, plain CGI executable will be generated. -version=fastcgi A FastCGI executable will be generated. -version=scgi A SCGI (SimpleCGI) executable will be generated. -version=embedded_httpd A HTTP server will be embedded in the generated executable. -version=embedded_httpd_threads The embedded HTTP server will use a single process with a thread pool. -version=embedded_httpd_processes The embedded HTTP server will use a prefork style process pool.
-version=cgi_with_websocket The CGI class has websocket server support.
-version=with_openssl # not currently used
-version=embedded_httpd_processes_accept_after_fork It will call accept() in each child process, after forking. This is currently the only option, though I am experimenting with other ideas.
-version=cgi_embedded_sessions The session server will be embedded in the cgi.d server process -version=cgi_session_server_process The session will be provided in a separate process, provided by cgi.d.
For CGI, dmd yourfile.d cgi.d then put the executable in your cgi-bin directory.
For FastCGI: dmd yourfile.d cgi.d -version=fastcgi and run it. spawn-fcgi helps on nginx. You can put the file in the directory for Apache. On IIS, run it with a port on the command line.
For SCGI: dmd yourfile.d cgi.d -version=scgi and run the executable, providing a port number on the command line.
For an embedded HTTP server, run dmd yourfile.d cgi.d -version=embedded_httpd and run the generated program. It listens on port 8085 by default. You can change this on the command line with the --port option when running your program.
You can also simulate a request by passing parameters on the command line, like:
./yourprogram GET / name=adr
And it will print the result to stdout.
On Apache, you may do SetHandler cgi-script in your .htaccess file.
cgi.d works well with dom.d for generating html. You may also use web.d for other utilities and automatic api wrapping.
dom.d usage:
1 import arsd.cgi; 2 import arsd.dom; 3 4 void hello_dom(Cgi cgi) { 5 auto document = new Document(); 6 7 static import std.file; 8 // parse the file in strict mode, requiring it to be well-formed UTF-8 XHTML 9 // (You'll appreciate this if you've ever had to deal with a missing </div> 10 // or something in a php or erb template before that would randomly mess up 11 // the output in your browser. Just check it and throw an exception early!) 12 // 13 // You could also hard-code a template or load one at compile time with an 14 // import expression, but you might appreciate making it a regular file 15 // because that means it can be more easily edited by the frontend team and 16 // they can see their changes without needing to recompile the program. 17 // 18 // Note on CTFE: if you do choose to load a static file at compile time, 19 // you *can* parse it in CTFE using enum, which will cause it to throw at 20 // compile time, which is kinda cool too. Be careful in modifying that document, 21 // though, as it will be a static instance. You might want to clone on on demand, 22 // or perhaps modify it lazily as you print it out. (Try element.tree, it returns 23 // a range of elements which you could send through std.algorithm functions. But 24 // since my selector implementation doesn't work on that level yet, you'll find that 25 // harder to use. Of course, you could make a static list of matching elements and 26 // then use a simple e is e2 predicate... :) ) 27 document.parseUtf8(std.file.read("your_template.html"), true, true); 28 29 // fill in data using DOM functions, so placing it is in the hands of HTML 30 // and it will be properly encoded as text too. 31 // 32 // Plain html templates can't run server side logic, but I think that's a 33 // good thing - it keeps them simple. You may choose to extend the html, 34 // but I think it is best to try to stick to standard elements and fill them 35 // in with requested data with IDs or class names. A further benefit of 36 // this is the designer can also highlight data based on sources in the CSS. 37 // 38 // However, all of dom.d is available, so you can format your data however 39 // you like. You can do partial templates with innerHTML too, or perhaps better, 40 // injecting cloned nodes from a partial document. 41 // 42 // There's a lot of possibilities. 43 document["#name"].innerText = cgi.request("name", "default name"); 44 45 // send the document to the browser. The second argument to `cgi.write` 46 // indicates that this is all the data at once, enabling a few small 47 // optimizations. 48 cgi.write(document.toString(), true); 49 }
Concepts: Input: Cgi.get, Cgi.post, Cgi.request, Cgi.files, Cgi.cookies, Cgi.pathInfo, Cgi.requestMethod, and HTTP headers (Cgi.headers, Cgi.userAgent, Cgi.referrer, Cgi.accept, Cgi.authorization, Cgi.lastEventId)
Output: Cgi.write, Cgi.header, Cgi.setResponseStatus, Cgi.setResponseContentType, Cgi.gzipResponse
Cookies: Cgi.setCookie, Cgi.clearCookie, Cgi.cookie, Cgi.cookies
Caching: Cgi.setResponseExpires, Cgi.updateResponseExpires, Cgi.setCache
Redirections: Cgi.setResponseLocation
Other Information: Cgi.remoteAddress, Cgi.https, Cgi.port, Cgi.scriptName, Cgi.requestUri, Cgi.getCurrentCompleteUri, Cgi.onRequestBodyDataReceived
Overriding behavior: Cgi.handleIncomingDataChunk, Cgi.prepareForIncomingDataChunks, Cgi.cleanUpPostDataState
Installing: Apache, IIS, CGI, FastCGI, SCGI, embedded HTTPD (not recommended for production use)
If you are coming from PHP, here's a quick guide to help you get started:
1 <?php 2 $foo = $_POST["foo"]; 3 $bar = $_GET["bar"]; 4 $baz = $_COOKIE["baz"]; 5 6 $user_ip = $_SERVER["REMOTE_ADDR"]; 7 $host = $_SERVER["HTTP_HOST"]; 8 $path = $_SERVER["PATH_INFO"]; 9 10 setcookie("baz", "some value"); 11 12 echo "hello!"; 13 ?> | 1 import arsd.cgi; 2 void app(Cgi cgi) { 3 string foo = cgi.post["foo"]; 4 string bar = cgi.get["bar"]; 5 string baz = cgi.cookies["baz"]; 6 7 string user_ip = cgi.remoteAddress; 8 string host = cgi.host; 9 string path = cgi.pathInfo; 10 11 cgi.setCookie("baz", "some value"); 12 13 cgi.write("hello!"); 14 } 15 16 mixin GenericMain!app |
In PHP, you can give a form element a name like "something[]", and then $_POST["something"] gives an array. In D, you can use whatever name you want, and access an array of values with the cgi.getArray["name"] and cgi.postArray["name"] members.
PHP has a lot of stuff in its standard library. cgi.d doesn't include most of these, but the rest of my arsd repository has much of it. For example, to access a MySQL database, download database.d and mysql.d from my github repo, and try this code (assuming, of course, your database is set up):
1 import arsd.cgi; 2 import arsd.mysql; 3 4 void app(Cgi cgi) { 5 auto database = new MySql("localhost", "username", "password", "database_name"); 6 foreach(row; mysql.query("SELECT count(id) FROM people")) 7 cgi.write(row[0] ~ " people in database"); 8 } 9 10 mixin GenericMain!app;
Similar modules are available for PostgreSQL, Microsoft SQL Server, and SQLite databases, implementing the same basic interface.
You may also want to see arsd.dom, arsd.web, and arsd.html for more code for making web applications.
For working with json, try arsd.jsvar.
arsd.database, arsd.mysql, arsd.postgres, arsd.mssql, and arsd.sqlite can help in accessing databases.
If you are looking to access a web application via HTTP, try std.net.curl, arsd.curl, or arsd.http2.
cgi.d copyright 2008-2019, Adam D. Ruppe. Provided under the Boost Software License.
Yes, this file is almost ten years old, and yes, it is still actively maintained and used.
Provides a uniform server-side API for CGI, FastCGI, SCGI, and HTTP web applications.