1 /* 2 * Archttp - A highly performant web framework written in D. 3 * 4 * Copyright (C) 2021-2022 Kerisy.com 5 * 6 * Website: https://www.kerisy.com 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module archttp.HttpResponse; 13 14 import archttp.HttpStatusCode; 15 import archttp.HttpContext; 16 17 import gear.util.DateTime; 18 19 import std.format; 20 import std.array; 21 import std.conv : to; 22 import std.json; 23 24 class HttpResponse 25 { 26 alias string[string] headerList; 27 28 ushort _status = HttpStatusCode.OK; 29 headerList _headers; 30 string _body; 31 string _buffer; 32 HttpContext _httpContext; 33 34 public: 35 /* 36 * Construct an empty response. 37 */ 38 this(HttpContext ctx) 39 { 40 _httpContext = ctx; 41 } 42 43 /* 44 * Sets a header field. 45 * 46 * Setting the same header twice will overwrite the previous, and header keys are case 47 * insensitive. When sent to the client the header key will be as written here. 48 * 49 * @param header the header key 50 * @param value the header value 51 */ 52 HttpResponse header(string header, string value) 53 { 54 _headers[header] = value; 55 56 return this; 57 } 58 59 /* 60 * Set the HTTP status of the response. 61 * 62 * @param status_code the status code 63 */ 64 HttpResponse status(HttpStatusCode status_code) 65 { 66 _status = status_code; 67 68 return this; 69 } 70 71 /* 72 * Set the entire body of the response. 73 * 74 * Sets the body of the response, overwriting any previous data stored in the body. 75 * 76 * @param body the response body 77 */ 78 HttpResponse body(string body) 79 { 80 _body = body; 81 82 header("Content-Type", "text/plain"); 83 84 return this; 85 } 86 87 /* 88 * Set the entire body of the response. 89 * 90 * Sets the body of the response, overwriting any previous data stored in the body. 91 * 92 * @param json the response body 93 */ 94 HttpResponse json(JSONValue json) 95 { 96 _body = json.toString(); 97 98 header("Content-Type", "application/json"); 99 100 return this; 101 } 102 103 /* 104 * Get the status of the response. 105 * 106 * @return the status of the response 107 */ 108 ushort status() 109 { 110 return _status; 111 } 112 113 // ----- serializer ----- 114 115 /* 116 * Generate an HTTP response from this object. 117 * 118 * Uses the configured parameters to generate a full HTTP response and returns it as a 119 * string. 120 * 121 * @return the HTTP response 122 */ 123 string ToBuffer() 124 { 125 header("Content-Length", _body.length.to!string); 126 header("Date", DateTime.GetTimeAsGMT()); 127 128 auto text = appender!string; 129 text ~= format!"HTTP/1.1 %d %s\r\n"(_status, getHttpStatusMessage(_status)); 130 foreach (name, value; _headers) { 131 text ~= format!"%s: %s\r\n"(name, value); 132 } 133 text ~= "\r\n"; 134 135 text ~= _body; 136 137 return text[]; 138 } 139 }