Execute GET for http and retrieve file for FTP. You have to provide at least uri. All other arguments should conform to HTTPRequest.get or FTPRequest.get depending on the URI scheme. When arguments do not conform scheme (for example you try to call get("ftp://somehost.net/pub/README", {"a":"b"}) which doesn't make sense) you will receive Exception("Operation not supported for ftp")
Execute POST for http and STOR file for FTP. You have to provide uri and data. Data should conform to HTTPRequest.post or FTPRequest.post depending on the URI scheme. When arguments do not conform scheme you will receive Exception("Operation not supported for ftp")
Set authenticator for http requests. v - Auth instance.
Set IO buffer size for http and ftp requests v - buffer size in bytes.
Set http keepAlive value v - use keepalive requests - true, or not - false
Set maximum content lenth both for http and ftp requests v - maximum content length in bytes. When limit reached - throw RequestException
Set maximum length for HTTP headers v - maximum length of the HTTP response. When limit reached - throw RequestException
Set limit on HTTP redirects v - limit on redirect depth
Set timeout on IO operation. v - timeout value
Set verbosity for HTTP or FTP requests. v - verbosity level (0 - no output, 1 - headers to stdout, 2 - headers and body progress to stdout). default = 0.
1 import std.algorithm; 2 import std.range; 3 import std.array; 4 import std.json; 5 import std.stdio; 6 import std.string; 7 import std.exception; 8 9 globalLogLevel(LogLevel.info); 10 11 infof("testing Request"); 12 Request rq; 13 Response rs; 14 // 15 rs = rq.get("https://httpbin.org/"); 16 assert(rs.code==200); 17 assert(rs.responseBody.length > 0); 18 rs = rq.get("http://httpbin.org/get", ["c":" d", "a":"b"]); 19 assert(rs.code == 200); 20 auto json = parseJSON(rs.responseBody.data).object["args"].object; 21 assert(json["c"].str == " d"); 22 assert(json["a"].str == "b"); 23 24 globalLogLevel(LogLevel.info); 25 rq = Request(); 26 rq.keepAlive = true; 27 // handmade json 28 info("Check POST json"); 29 rs = rq.post("http://httpbin.org/post?b=x", `{"a":"☺ ", "c":[1,2,3]}`, "application/json"); 30 assert(rs.code==200); 31 json = parseJSON(rs.responseBody.data).object["args"].object; 32 assert(json["b"].str == "x"); 33 json = parseJSON(rs.responseBody.data).object["json"].object; 34 assert(json["a"].str == "☺ "); 35 assert(json["c"].array.map!(a=>a.integer).array == [1,2,3]); 36 { 37 import std.file; 38 import std.path; 39 auto tmpd = tempDir(); 40 auto tmpfname = tmpd ~ dirSeparator ~ "request_test.txt"; 41 auto f = File(tmpfname, "wb"); 42 f.rawWrite("abcdefgh\n12345678\n"); 43 f.close(); 44 // files 45 globalLogLevel(LogLevel.info); 46 info("Check POST files"); 47 PostFile[] files = [ 48 {fileName: tmpfname, fieldName:"abc", contentType:"application/octet-stream"}, 49 {fileName: tmpfname} 50 ]; 51 rs = rq.post("http://httpbin.org/post", files); 52 assert(rs.code==200); 53 info("Check POST chunked from file.byChunk"); 54 f = File(tmpfname, "rb"); 55 rs = rq.post("http://httpbin.org/post", f.byChunk(3), "application/octet-stream"); 56 assert(rs.code==200); 57 auto data = parseJSON(rs.responseBody.data).object["data"].str; 58 assert(data=="abcdefgh\n12345678\n"); 59 f.close(); 60 } 61 { 62 // string 63 info("Check POST utf8 string"); 64 rs = rq.post("http://httpbin.org/post", "привiт, свiт!", "application/octet-stream"); 65 assert(rs.code==200); 66 auto data = parseJSON(rs.responseBody.data).object["data"].str; 67 assert(data=="привiт, свiт!"); 68 } 69 // ranges 70 { 71 info("Check POST chunked from lineSplitter"); 72 auto s = lineSplitter("one,\ntwo,\nthree."); 73 rs = rq.exec!"POST"("http://httpbin.org/post", s, "application/octet-stream"); 74 assert(rs.code==200); 75 auto data = parseJSON(rs.responseBody.toString).object["data"].str; 76 assert(data=="one,two,three."); 77 } 78 { 79 info("Check POST chunked from array"); 80 auto s = ["one,", "two,", "three."]; 81 rs = rq.post("http://httpbin.org/post", s, "application/octet-stream"); 82 assert(rs.code==200); 83 auto data = parseJSON(rs.responseBody.data).object["data"].str; 84 assert(data=="one,two,three."); 85 } 86 { 87 info("Check POST chunked using std.range.chunks()"); 88 auto s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 89 rs = rq.post("http://httpbin.org/post", s.representation.chunks(10), "application/octet-stream"); 90 assert(rs.code==200); 91 auto data = parseJSON(rs.responseBody.data).object["data"].str; 92 assert(data==s); 93 } 94 // associative array 95 rs = rq.post("http://httpbin.org/post", ["a":"b ", "c":"d"]); 96 assert(rs.code==200); 97 auto form = parseJSON(rs.responseBody.data).object["form"].object; 98 assert(form["a"].str == "b "); 99 assert(form["c"].str == "d"); 100 info("Check HEAD"); 101 rs = rq.exec!"HEAD"("http://httpbin.org/"); 102 assert(rs.code==200); 103 info("Check DELETE"); 104 rs = rq.exec!"DELETE"("http://httpbin.org/delete"); 105 assert(rs.code==200); 106 info("Check PUT"); 107 rs = rq.exec!"PUT"("http://httpbin.org/put", `{"a":"b", "c":[1,2,3]}`, "application/json"); 108 assert(rs.code==200); 109 info("Check PATCH"); 110 rs = rq.exec!"PATCH"("http://httpbin.org/patch", "привiт, свiт!", "application/octet-stream"); 111 assert(rs.code==200); 112 113 info("Check compressed content"); 114 globalLogLevel(LogLevel.info); 115 rq = Request(); 116 rq.keepAlive = true; 117 rs = rq.get("http://httpbin.org/gzip"); 118 assert(rs.code==200); 119 info("gzip - ok"); 120 rs = rq.get("http://httpbin.org/deflate"); 121 assert(rs.code==200); 122 info("deflate - ok"); 123 124 info("Check redirects"); 125 globalLogLevel(LogLevel.info); 126 rq = Request(); 127 rq.keepAlive = true; 128 rs = rq.get("http://httpbin.org/relative-redirect/2"); 129 assert((cast(HTTPResponse)rs).history.length == 2); 130 assert((cast(HTTPResponse)rs).code==200); 131 // rq = Request(); 132 // rq.keepAlive = true; 133 // rq.proxy = "http://localhost:8888/"; 134 rs = rq.get("http://httpbin.org/absolute-redirect/2"); 135 assert((cast(HTTPResponse)rs).history.length == 2); 136 assert((cast(HTTPResponse)rs).code==200); 137 // rq = Request(); 138 rq.maxRedirects = 2; 139 rq.keepAlive = false; 140 rs = rq.get("https://httpbin.org/absolute-redirect/3"); 141 assert((cast(HTTPResponse)rs).history.length == 2); 142 assert((cast(HTTPResponse)rs).code==302); 143 144 info("Check utf8 content"); 145 globalLogLevel(LogLevel.info); 146 rq = Request(); 147 rs = rq.get("http://httpbin.org/encoding/utf8"); 148 assert(rs.code==200); 149 150 info("Check chunked content"); 151 globalLogLevel(LogLevel.info); 152 rq = Request(); 153 rq.keepAlive = true; 154 rq.bufferSize = 16*1024; 155 rs = rq.get("http://httpbin.org/range/1024"); 156 assert(rs.code==200); 157 assert(rs.responseBody.length==1024); 158 159 info("Check basic auth"); 160 globalLogLevel(LogLevel.info); 161 rq = Request(); 162 rq.authenticator = new BasicAuthentication("user", "passwd"); 163 rs = rq.get("http://httpbin.org/basic-auth/user/passwd"); 164 assert(rs.code==200); 165 166 globalLogLevel(LogLevel.info); 167 info("Check exception handling, error messages are OK"); 168 rq = Request(); 169 rq.timeout = 1.seconds; 170 assertThrown!TimeoutException(rq.get("http://httpbin.org/delay/3")); 171 assertThrown!ConnectError(rq.get("http://0.0.0.0:65000/")); 172 assertThrown!ConnectError(rq.get("http://1.1.1.1/")); 173 //assertThrown!ConnectError(rq.get("http://gkhgkhgkjhgjhgfjhgfjhgf/")); 174 175 globalLogLevel(LogLevel.info); 176 info("Check limits"); 177 rq = Request(); 178 rq.maxContentLength = 1; 179 assertThrown!RequestException(rq.get("http://httpbin.org/")); 180 rq = Request(); 181 rq.maxHeadersLength = 1; 182 assertThrown!RequestException(rq.get("http://httpbin.org/")); 183 // 184 info("ftp post ", "ftp://speedtest.tele2.net/upload/TEST.TXT"); 185 rs = rq.post("ftp://speedtest.tele2.net/upload/TEST.TXT", "test, ignore please\n".representation); 186 assert(rs.code == 226); 187 info("ftp get ", "ftp://speedtest.tele2.net/nonexistent", ", in same session."); 188 rs = rq.get("ftp://speedtest.tele2.net/nonexistent"); 189 assert(rs.code != 226); 190 info("ftp get ", "ftp://speedtest.tele2.net/1KB.zip", ", in same session."); 191 rs = rq.get("ftp://speedtest.tele2.net/1KB.zip"); 192 assert(rs.code == 226); 193 assert(rs.responseBody.length == 1024); 194 info("ftp get ", "ftp://ftp.uni-bayreuth.de/README"); 195 rs = rq.get("ftp://ftp.uni-bayreuth.de/README"); 196 assert(rs.code == 226); 197 info("ftp post ", "ftp://speedtest.tele2.net/upload/TEST.TXT"); 198 rs = rq.post("ftp://speedtest.tele2.net/upload/TEST.TXT", "another test, ignore please\n".representation); 199 assert(rs.code == 226); 200 info("ftp get ", "ftp://ftp.iij.ad.jp/pub/FreeBSD/README.TXT"); 201 rs = rq.get("ftp://ftp.iij.ad.jp/pub/FreeBSD/README.TXT"); 202 assert(rs.code == 226); 203 info("testing ftp - done.");
This is simplest interface to both http and ftp protocols. Request has methods get, post and exec which routed to proper concrete handler (http or ftp, etc). To enable some protocol-specific featutes you have to use protocol interface directly (see docs for HTTPRequest or FTPRequest)