HTTPRequest

Request. Configurable parameters: method - string, method to use (GET, POST, ...) headers - stringstring, add any additional headers you'd like to send. authenticator - class Auth, class to send auth headers. keepAlive - bool, set true for keepAlive requests. default true. maxRedirects - uint, maximum number of redirects. default 10. maxHeadersLength - size_t, maximum length of server response headers. default = 32KB. maxContentLength - size_t, maximun content length. delault - 0 = unlimited. bufferSize - size_t, send and receive buffer size. default = 16KB. verbosity - uint, level of verbosity(0 - nothing, 1 - headers, 2 - headers and body progress). default = 0. proxy - string, set proxy url if needed. default - null. cookie - Tuple Cookie, Read/Write cookie You can get cookie setted by server, or set cookies before doing request. timeout - Duration, Set timeout value for connect/receive/send.

Constructors

this
this(string uri)
Undocumented in source.

Destructor

~this
~this()
Undocumented in source.

Members

Functions

addHeaders
void addHeaders(string[string] headers)

Add headers to request

exec
HTTPResponse exec(string url, MultipartForm sources)

Send multipart for request. You would like to use this method for sending large portions of mixed data or uploading files to forms. Content of the posted form consist of sources. Each source have at least name and value (can be string-like object or opened file, see more docs for MultipartForm struct)

exec
HTTPResponse exec(string url, R content, string contentType)

POST/PUT/... data from some string(with Content-Length), or from range of strings/bytes (use Transfer-Encoding: chunked). When rank 1 (flat array) used as content it must have length. In that case "content" will be sent directly to network, and Content-Length headers will be added. If you are goung to send some range and do not know length at the moment when you start to send request, then you can send chunks of chars or ubyte. Try not to send too short chunks as this will put additional load on client and server. Chunks of length 2048 or 4096 are ok.

exec
HTTPResponse exec(string url, QueryParam[] params)

Send request with pameters. If used for POST or PUT requests then application/x-www-form-urlencoded used. Request parameters will be encoded into request string or placed in request body for POST/PUT requests.

exec
HTTPResponse exec(string url, PostFile[] files)

WRAPPERS

exec
HTTPResponse exec(string url, string[string] params)

exec request with parameters when you can use dictionary (when you have no duplicates in parameter names) Consider switch to exec(url, QueryParams) as it more generic and clear.

get
HTTPResponse get(A args)

GET request. Simple wrapper over exec!"GET"

post
HTTPResponse post(string uri, A args)

POST request. Simple wrapper over exec!"POST"

removeHeaders
void removeHeaders(string[] headers)

Remove headers from request

Properties

cookie
Cookie[] cookie [@property setter]
Undocumented in source. Be warned that the author may not have intended to support it.
cookie
Cookie[] cookie [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.
uri
URI uri [@property setter]
Undocumented in source. Be warned that the author may not have intended to support it.

Variables

_response
HTTPResponse _response;
Undocumented in source.

Examples

1     import std.json;
2     globalLogLevel(LogLevel.info);
3     tracef("http tests - start");
4 
5     auto rq = HTTPRequest();
6     auto rs = rq.get("https://httpbin.org/");
7     assert(rs.code==200);
8     assert(rs.responseBody.length > 0);
9     rs = HTTPRequest().get("http://httpbin.org/get", ["c":" d", "a":"b"]);
10     assert(rs.code == 200);
11     auto json = parseJSON(rs.responseBody.data).object["args"].object;
12     assert(json["c"].str == " d");
13     assert(json["a"].str == "b");
14 
15     globalLogLevel(LogLevel.info);
16     rq = HTTPRequest();
17     rq.keepAlive = true;
18     // handmade json
19     info("Check POST json");
20     rs = rq.post("http://httpbin.org/post?b=x", `{"a":"☺ ", "c":[1,2,3]}`, "application/json");
21     assert(rs.code==200);
22     json = parseJSON(rs.responseBody.data).object["args"].object;
23     assert(json["b"].str == "x");
24     json = parseJSON(rs.responseBody.data).object["json"].object;
25     assert(json["a"].str == "☺ ");
26     assert(json["c"].array.map!(a=>a.integer).array == [1,2,3]);
27     {
28         import std.file;
29         import std.path;
30         auto tmpd = tempDir();
31         auto tmpfname = tmpd ~ dirSeparator ~ "request_test.txt";
32         auto f = File(tmpfname, "wb");
33         f.rawWrite("abcdefgh\n12345678\n");
34         f.close();
35         // files
36         globalLogLevel(LogLevel.info);
37         info("Check POST files");
38         PostFile[] files = [
39                         {fileName: tmpfname, fieldName:"abc", contentType:"application/octet-stream"}, 
40                         {fileName: tmpfname}
41                     ];
42         rs = rq.post("http://httpbin.org/post", files);
43         assert(rs.code==200);
44         info("Check POST chunked from file.byChunk");
45         f = File(tmpfname, "rb");
46         rs = rq.post("http://httpbin.org/post", f.byChunk(3), "application/octet-stream");
47         assert(rs.code==200);
48         auto data = parseJSON(rs.responseBody.data).object["data"].str;
49         assert(data=="abcdefgh\n12345678\n");
50         f.close();
51     }
52     {
53         // string
54         info("Check POST utf8 string");
55         rs = rq.post("http://httpbin.org/post", "привiт, свiт!", "application/octet-stream");
56         assert(rs.code==200);
57         auto data = parseJSON(rs.responseBody.data).object["data"].str;
58         assert(data=="привiт, свiт!");
59     }
60     // ranges
61     {
62         info("Check POST chunked from lineSplitter");
63         auto s = lineSplitter("one,\ntwo,\nthree.");
64         rs = rq.exec!"POST"("http://httpbin.org/post", s, "application/octet-stream");
65         assert(rs.code==200);
66         auto data = parseJSON(rs.responseBody.toString).object["data"].str;
67         assert(data=="one,two,three.");
68     }
69     {
70         info("Check POST chunked from array");
71         auto s = ["one,", "two,", "three."];
72         rs = rq.post("http://httpbin.org/post", s, "application/octet-stream");
73         assert(rs.code==200);
74         auto data = parseJSON(rs.responseBody.data).object["data"].str;
75         assert(data=="one,two,three.");
76     }
77     {
78         info("Check POST chunked using std.range.chunks()");
79         auto s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
80         rs = rq.post("http://httpbin.org/post", s.representation.chunks(10), "application/octet-stream");
81         assert(rs.code==200);
82         auto data = parseJSON(rs.responseBody.data).object["data"].str;
83         assert(data==s);
84     }
85     {
86         info("Check POST from AA");
87         rs = rq.post("http://httpbin.org/post", ["a":"b", "c":"d"]);
88         assert(rs.code==200);
89         auto data = parseJSON(rs.responseBody.data).object["form"].object;
90         assert(data["a"].str == "b");
91         assert(data["c"].str == "d");
92     }
93     {
94         info("Check POST from QueryParams");
95         rs = rq.post("http://httpbin.org/post", queryParams("name[]", "first", "name[]", 2));
96         assert(rs.code==200);
97         auto data = parseJSON(rs.responseBody.data).object["form"].object;
98         assert((data["name[]"].array[0].str == "first"));
99         assert((data["name[]"].array[1].str == "2"));
100     }
101     // associative array
102     rs = rq.post("http://httpbin.org/post", ["a":"b ", "c":"d"]);
103     assert(rs.code==200);
104     auto form = parseJSON(rs.responseBody.data).object["form"].object;
105     assert(form["a"].str == "b ");
106     assert(form["c"].str == "d");
107     info("Check HEAD");
108     rs = rq.exec!"HEAD"("http://httpbin.org/");
109     assert(rs.code==200);
110     info("Check DELETE");
111     rs = rq.exec!"DELETE"("http://httpbin.org/delete");
112     assert(rs.code==200);
113     info("Check PUT");
114     rs = rq.exec!"PUT"("http://httpbin.org/put",  `{"a":"b", "c":[1,2,3]}`, "application/json");
115     assert(rs.code==200);
116     info("Check PATCH");
117     rs = rq.exec!"PATCH"("http://httpbin.org/patch", "привiт, свiт!", "application/octet-stream");
118     assert(rs.code==200);
119 
120     info("Check compressed content");
121     globalLogLevel(LogLevel.info);
122     rq = HTTPRequest();
123     rq.keepAlive = true;
124     rs = rq.get("http://httpbin.org/gzip");
125     assert(rs.code==200);
126     info("gzip - ok");
127     rs = rq.get("http://httpbin.org/deflate");
128     assert(rs.code==200);
129     info("deflate - ok");
130 
131     info("Check redirects");
132     globalLogLevel(LogLevel.info);
133     rq = HTTPRequest();
134     //rq.verbosity = 3;
135     rq.keepAlive = true;
136     rs = rq.get("http://httpbin.org/relative-redirect/2");
137     assert(rs.history.length == 2);
138     assert(rs.code==200);
139 //    rq = Request();
140 //    rq.keepAlive = true;
141 //    rq.proxy = "http://localhost:8888/";
142     rs = rq.get("http://httpbin.org/absolute-redirect/2");
143     assert(rs.history.length == 2);
144     assert(rs.code==200);
145 //    rq = Request();
146     rq.maxRedirects = 2;
147     rq.keepAlive = false;
148     rs = rq.get("https://httpbin.org/absolute-redirect/3");
149     assert(rs.history.length == 2);
150     assert(rs.code==302);
151     info("Check utf8 content");
152     globalLogLevel(LogLevel.info);
153     rq = HTTPRequest();
154     rs = rq.get("http://httpbin.org/encoding/utf8");
155     assert(rs.code==200);
156 
157     info("Check cookie");
158     rs = HTTPRequest().get("http://httpbin.org/cookies/set?A=abcd&b=cdef");
159     assert(rs.code == 200);
160     json = parseJSON(rs.responseBody.data).object["cookies"].object;
161     assert(json["A"].str == "abcd");
162     assert(json["b"].str == "cdef");
163     auto cookie = rq.cookie();
164     foreach(c; rq.cookie) {
165         final switch(c.attr) {
166             case "A":
167                 assert(c.value == "abcd");
168                 break;
169             case "b":
170                 assert(c.value == "cdef");
171                 break;
172         }
173     }
174 
175     info("Check chunked content");
176     globalLogLevel(LogLevel.info);
177     rq = HTTPRequest();
178     rq.keepAlive = true;
179     rs = rq.get("http://httpbin.org/range/1024");
180     assert(rs.code==200);
181     assert(rs.responseBody.length==1024);
182 
183     info("Check basic auth");
184     globalLogLevel(LogLevel.info);
185     rq = HTTPRequest();
186     rq.authenticator = new BasicAuthentication("user", "passwd");
187     rs = rq.get("http://httpbin.org/basic-auth/user/passwd");
188     assert(rs.code==200);
189  
190     globalLogLevel(LogLevel.info);
191     info("Check exception handling, error messages are OK");
192     rq = HTTPRequest();
193     rq.timeout = 1.seconds;
194     assertThrown!TimeoutException(rq.get("http://httpbin.org/delay/3"));
195 //    assertThrown!ConnectError(rq.get("http://0.0.0.0:65000/"));
196 //    assertThrown!ConnectError(rq.get("http://1.1.1.1/"));
197     //assertThrown!ConnectError(rq.get("http://gkhgkhgkjhgjhgfjhgfjhgf/"));
198 
199     globalLogLevel(LogLevel.info);
200     info("Check limits");
201     rq = HTTPRequest();
202     rq.maxContentLength = 1;
203     assertThrown!RequestException(rq.get("http://httpbin.org/"));
204     rq = HTTPRequest();
205     rq.maxHeadersLength = 1;
206     assertThrown!RequestException(rq.get("http://httpbin.org/"));
207     tracef("http tests - ok");

Meta