1 module handy_httpd.response;
2 
3 import std.array;
4 import std.string : format, representation;
5 import std.conv;
6 
7 /** 
8  * The data that the HTTP server will send back to clients.
9  */
10 struct HttpResponse {
11     /** 
12      * The status code.
13      */
14     ushort status;
15 
16     /** 
17      * A short textual representation of the status.
18      */
19     string statusText;
20 
21     /** 
22      * An associative array of headers.
23      */
24     string[string] headers;
25 
26     /** 
27      * The body of the message.
28      */
29     ubyte[] messageBody;
30 
31     HttpResponse setStatus(ushort status) {
32         this.status = status;
33         return this;
34     }
35 
36     HttpResponse setStatusText(string statusText) {
37         this.statusText = statusText;
38         return this;
39     }
40 
41     HttpResponse addHeader(string name, string value) {
42         this.headers[name] = value;
43         return this;
44     }
45 
46     HttpResponse setBody(string messageBody) {
47         this.messageBody = cast(ubyte[]) messageBody;
48         return this;
49     }
50 
51     /** 
52      * Converts this response to a byte array in HTTP format.
53      * Returns: A byte array containing the response content.
54      */
55     ubyte[] toBytes() {
56         auto a = appender!(ubyte[]);
57         auto statusLine = format!"HTTP/1.1 %d %s\r\n"(status, statusText);
58         a ~= cast(ubyte[]) statusLine;
59         if (messageBody.length > 0) {
60             headers["Content-Length"] = messageBody.length.to!string;
61         }
62         foreach (name, value; headers) {
63             a ~= cast(ubyte[]) (name ~ ": " ~ value ~ "\r\n");
64         }
65         a ~= cast(ubyte[]) "\r\n";
66         if (messageBody.length > 0) {
67             a ~= messageBody;
68         }
69         return a[];
70     }
71 }