pragma(lib, "ws2_32.lib"); import std.string, std.conv, std.stream; import std.socket, std.socketstream; class HTTP { this(){ headers = "Accept: text/*" ~ NL; headers ~= "User-Agent: DHTTPC/1.0" ~ NL; } this(char[] url){ this(); GET(url); } this(char[] url, char[][char[]] headers){ this(); foreach(char[] name, char[] value; headers){ setHeader(name, value); } GET(url); } ~this(){ // ? } public{ void setHeader(char[] name, char[] value){ // Check if header already exists? headers ~= name ~": " ~ value ~ NL; } char[] getHeaders(){ return headers; } bool GET(char[] url){ // Assumes response is 200 OK, can't handle redirects (should be easily implemented if needed though) // Parse URL int i; // Check for HTTP protocol in URL i = std.string.find(url, "://"); if(i != -1){ if(icmp(url[0 .. i], "http")) throw new Exception("URL Protocol is not HTTP."); }else{ throw new Exception("URL has no protocol."); } // Remove anchor i = std.string.find(url, '#'); if(i != -1) url = url[0 .. i]; // Split URL into domain and URI char[] domain; i = std.string.find(url, '/'); if(i == -1){ domain = url; url = "/"; }else{ domain = url[0 .. i]; url = url[i .. url.length]; } // Find port uint port; i = std.string.find(domain, ':'); if(i == -1){ port = 80; }else{ port = std.conv.toUshort(domain[i + 1 .. domain.length]); domain = domain[0 .. i]; } // Set HOST header setHeader("Host", domain ~ ":" ~ std.string.toString(port)); // Open socket sock = new Socket(cast(AddressFamily)(new InternetAddress(domain, port)), SocketType.STREAM, ProtocolType.TCP); sockstream = new SocketStream(sock); // Do request sockstream.writeString("GET " ~ url ~ " HTTP/1.1" ~ NL ~ headers ~ NL); // Store headers char[] line; headers = ""; for(;;){ line = sockstream.readLine(); if(!line.length) break; headers ~= line; } // Store data data = ""; while(!sockstream.eof()){ line = sockstream.readLine(); data ~= line; } // Close socket sockstream.close(); return true; } bool GET(char[] url, char[][char[]] parameters){ char[] p = "?"; foreach(char[] n, char[] v; parameters){ if(p.length != 1) p ~= "&"; p ~= n ~ "=" ~ v; } return GET(url ~ p); } bool POST(char[] url, char[][char[]] parameters){ char[] p = "?"; foreach(char[] n, char[] v; parameters){ if(p.length != 1) p ~= "&"; p ~= n ~ "=" ~ v; } // Parse URL int i; // Check for HTTP protocol in URL i = std.string.find(url, "://"); if(i != -1){ if(icmp(url[0 .. i], "http")) throw new Exception("URL Protocol is not HTTP."); }else{ throw new Exception("URL has no protocol."); } // Remove anchor i = std.string.find(url, '#'); if(i != -1) url = url[0 .. i]; // Split URL into domain and URI char[] domain; i = std.string.find(url, '/'); if(i == -1){ domain = url; url = "/"; }else{ domain = url[0 .. i]; url = url[i .. url.length]; } // Find port uint port; i = std.string.find(domain, ':'); if(i == -1){ port = 80; }else{ port = std.conv.toUshort(domain[i + 1 .. domain.length]); domain = domain[0 .. i]; } // Set HOST header setHeader("Host", domain ~ ":" ~ std.string.toString(port)); // Open socket sock = new Socket(cast(AddressFamily)(new InternetAddress(domain, port)), SocketType.STREAM, ProtocolType.TCP); sockstream = new SocketStream(sock); // Do request sockstream.writeString("POST " ~ url ~ " HTTP/1.1" ~ NL ~ headers ~ NL ~ p ~ NL); // Store headers char[] line; headers = ""; for(;;){ line = sockstream.readLine(); if(!line.length) break; headers ~= line; } // Store data data = ""; while(!sockstream.eof()){ line = sockstream.readLine(); data ~= line; } // Close socket sockstream.close(); return true; } char[] getData(){ return data; } } private{ auto Socket sock; Stream sockstream; char[] data; char[] headers; const char[] NL = "\r\n"; } }