1 module dweb.utils; 2 3 import std.conv; 4 import std.array; 5 import std.stdio; 6 import std.socket; 7 import dweb.view_engine : Options; 8 import dweb.server : HttpServer; 9 10 public class Request{ 11 public string Method; 12 public string Path; 13 public string[string] Params; 14 public string Body; 15 public Header[] Headers; 16 } 17 18 public class Response{ 19 private string Status; 20 private Socket client; 21 private Header[string] Headers; 22 private char[] Body; 23 public bool isSended; 24 private HttpServer server; 25 this(Socket client, HttpServer server){ 26 this.Status = "200 OK"; 27 this.client = client; 28 this.Body = []; 29 this.isSended = false; 30 this.server = server; 31 } 32 public void setHeader(string Name, string Value){ 33 Header header; 34 header.Name = Name; 35 header.Value = Value; 36 this.Headers[Name] = header; 37 } 38 public void setStatus(int status){ 39 this.Status = status.to!string(); 40 } 41 public void write(string val){ 42 this.Body ~= val; 43 } 44 public void fhtml(string name){ 45 Header head; 46 head.Name = "Content-Type"; 47 head.Value = "text/html; charset=utf-8"; 48 this.Headers[head.Name] = head; 49 auto f = File(name, "r"); 50 string str; 51 f.readf!"%s"(str); 52 this.Body ~= str; 53 f.close(); 54 } 55 public void send(){ 56 char[] data = this.serializeResponse(); 57 ptrdiff_t sended = this.client.sendTo(data); 58 this.isSended = true; 59 } 60 public void send(string b){ 61 this.Body ~= b.dup; 62 char[] data = this.serializeResponse(); 63 ptrdiff_t sended = this.client.sendTo(data); 64 this.isSended = true; 65 } 66 public void send(int b){ 67 this.Status = b.to!string(); 68 char[] data = this.serializeResponse(); 69 ptrdiff_t sended = this.client.sendTo(data); 70 this.isSended = true; 71 } 72 private char[] serializeResponse(){ 73 string text = "HTTP/1.1 " ~ this.Status ~ "\r\n"; 74 Header head; 75 head.Name = "Content-Length"; 76 head.Value ~= this.Body.length.to!string(); 77 this.Headers[head.Name] = head; 78 79 foreach(header; this.Headers){ 80 text ~= header.Name ~ ": " ~ header.Value ~ "\r\n"; 81 } 82 text ~= "\r\n"; 83 text ~= this.Body; 84 85 char[] res = cast(char[])text; 86 return res; 87 } 88 public void render(string data, Options options = null){ 89 if(options !is null) 90 this.server.view_engine.setOptions(options); 91 this.Body ~= this.server.view_engine.render(data); 92 } 93 public void frender(string filename, Options options = null){ 94 if(options !is null) 95 this.server.view_engine.setOptions(options); 96 auto f = File(filename, "r"); 97 98 string str; 99 f.readf!"%s"(str); 100 f.close(); 101 102 this.Body ~= this.server.view_engine.render(str); 103 } 104 } 105 public struct Header{ 106 string Name; 107 string Value; 108 } 109 110 Request parseRequest(char[] buffer){ 111 Request req = new Request(); 112 string raw_path; 113 char[] Name; 114 char[] Value; 115 ubyte mode; // 0 - name; 1 - value 116 string rawtext = text(buffer); 117 string[] raw = rawtext.split("\r\n"); 118 req.Method = raw[0].split(' ')[0]; 119 req.Path = raw[0].split(' ')[1].split("?")[0]; 120 raw_path = raw[0].split(' ')[1]; 121 string[] raw_ = raw[1 .. raw.length]; 122 uint last = 0; 123 for(uint i = 0; i < raw_.length; i++){ 124 string raw_str = raw_[i]; 125 if(raw_str == ""){ 126 last = i + 1; 127 break; 128 } 129 string[] s = raw_str.split(": "); 130 if(s.length > 1){ 131 Header header; 132 header.Name = s[0]; 133 header.Value = s[1]; 134 req.Headers ~= [header]; 135 } 136 } 137 if(last != 0){ 138 req.Body = raw_[last .. raw_.length].join("\r\n"); 139 if(req.Method == "GET" && raw_path.split("?").length > 1){ 140 string[] val = raw_path.split("?")[1].split("&"); 141 142 foreach(v; val){ 143 string[] keyval = v.split("="); 144 if(keyval.length <= 1){ 145 req.Params[keyval[0]] = ""; 146 } 147 else if(keyval.length > 1){ 148 req.Params[keyval[0]] = keyval[1]; 149 } 150 } 151 } 152 } 153 154 return req; 155 } 156 157 158 159 bool containsKeyAssoc(TKey, TValue)(TKey need, TValue[TKey] arr){ 160 foreach(pair; arr.byPair){ 161 if(pair.key == need) 162 return true; 163 } 164 return false; 165 } 166