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     assertThrown!MaxRedirectsException(rq.get("https://httpbin.org/absolute-redirect/3"));
149     info("Check utf8 content");
150     globalLogLevel(LogLevel.info);
151     rq = HTTPRequest();
152     rs = rq.get("http://httpbin.org/encoding/utf8");
153     assert(rs.code==200);
154 
155     info("Check cookie");
156     rs = HTTPRequest().get("http://httpbin.org/cookies/set?A=abcd&b=cdef");
157     assert(rs.code == 200);
158     json = parseJSON(rs.responseBody.data).object["cookies"].object;
159     assert(json["A"].str == "abcd");
160     assert(json["b"].str == "cdef");
161     auto cookie = rq.cookie();
162     foreach(c; rq.cookie) {
163         final switch(c.attr) {
164             case "A":
165                 assert(c.value == "abcd");
166                 break;
167             case "b":
168                 assert(c.value == "cdef");
169                 break;
170         }
171     }
172 
173     info("Check chunked content");
174     globalLogLevel(LogLevel.info);
175     rq = HTTPRequest();
176     rq.keepAlive = true;
177     rs = rq.get("http://httpbin.org/range/1024");
178     assert(rs.code==200);
179     assert(rs.responseBody.length==1024);
180 
181     info("Check basic auth");
182     globalLogLevel(LogLevel.info);
183     rq = HTTPRequest();
184     rq.authenticator = new BasicAuthentication("user", "passwd");
185     rs = rq.get("http://httpbin.org/basic-auth/user/passwd");
186     assert(rs.code==200);
187  
188     globalLogLevel(LogLevel.info);
189     info("Check exception handling, error messages are OK");
190     rq = HTTPRequest();
191     rq.timeout = 1.seconds;
192     assertThrown!TimeoutException(rq.get("http://httpbin.org/delay/3"));
193 //    assertThrown!ConnectError(rq.get("http://0.0.0.0:65000/"));
194 //    assertThrown!ConnectError(rq.get("http://1.1.1.1/"));
195     //assertThrown!ConnectError(rq.get("http://gkhgkhgkjhgjhgfjhgfjhgf/"));
196 
197     globalLogLevel(LogLevel.info);
198     info("Check limits");
199     rq = HTTPRequest();
200     rq.maxContentLength = 1;
201     assertThrown!RequestException(rq.get("http://httpbin.org/"));
202     rq = HTTPRequest();
203     rq.maxHeadersLength = 1;
204     assertThrown!RequestException(rq.get("http://httpbin.org/"));
205     tracef("http tests - ok");

Meta