1 module requests.request; 2 import requests.http; 3 import requests.ftp; 4 import requests.streams; 5 import requests.base; 6 import requests.uri; 7 8 import std.datetime; 9 import std.conv; 10 import std.experimental.logger; 11 import requests.utils; 12 13 14 /** 15 This is simplest interface to both http and ftp protocols. 16 Request has methods get, post and exec which routed to proper concrete handler (http or ftp, etc). 17 To enable some protocol-specific featutes you have to use protocol interface directly (see docs for HTTPRequest or FTPRequest) 18 */ 19 public struct Request { 20 private { 21 URI _uri; 22 HTTPRequest _http; // route all http/https requests here 23 FTPRequest _ftp; // route all ftp requests here 24 } 25 /// Set timeout on IO operation. 26 /// $(B v) - timeout value 27 /// 28 public @property void timeout(Duration v) pure @nogc nothrow { 29 _http.timeout = v; 30 _ftp.timeout = v; 31 } 32 /// Set http keepAlive value 33 /// $(B v) - use keepalive requests - $(B true), or not - $(B false) 34 @property void keepAlive(bool v) pure @nogc nothrow { 35 _http.keepAlive = v; 36 } 37 /// Set limit on HTTP redirects 38 /// $(B v) - limit on redirect depth 39 @property void maxRedirects(uint v) pure @nogc nothrow { 40 _http.maxRedirects = v; 41 } 42 /// Set maximum content lenth both for http and ftp requests 43 /// $(B v) - maximum content length in bytes. When limit reached - throw RequestException 44 @property void maxContentLength(size_t v) pure @nogc nothrow { 45 _http.maxContentLength = v; 46 _ftp.maxContentLength = v; 47 } 48 /// Set maximum length for HTTP headers 49 /// $(B v) - maximum length of the HTTP response. When limit reached - throw RequestException 50 @property void maxHeadersLength(size_t v) pure @nogc nothrow { 51 _http.maxHeadersLength = v; 52 } 53 /// Set IO buffer size for http and ftp requests 54 /// $(B v) - buffer size in bytes. 55 @property void bufferSize(size_t v) { 56 _http.bufferSize = v; 57 _ftp.bufferSize = v; 58 } 59 /// Set verbosity for HTTP or FTP requests. 60 /// $(B v) - verbosity level (0 - no output, 1 - headers to stdout, 2 - headers and body progress to stdout). default = 0. 61 @property void verbosity(uint v) { 62 _http.verbosity = v; 63 _ftp.verbosity = v; 64 } 65 /// Set authenticator for http requests. 66 /// $(B v) - Auth instance. 67 @property void authenticator(Auth v) { 68 _http.authenticator = v; 69 _ftp.authenticator = v; 70 } 71 /// Set Cookie for http requests. 72 /// $(B v) - array of cookie. 73 @property void cookie(Cookie[] v) pure @nogc nothrow { 74 _http.cookie = v; 75 } 76 /// Get Cookie for http requests. 77 /// $(B v) - array of cookie. 78 @property Cookie[] cookie() pure @nogc nothrow { 79 return _http.cookie; 80 } 81 /// 82 /// set "streaming" property 83 /// Params: 84 /// v = value to set (true - use streaming) 85 /// 86 @property void useStreaming(bool v) pure @nogc nothrow { 87 _http.useStreaming = v; 88 _ftp.useStreaming = v; 89 } 90 /// 91 /// get length og actually received content. 92 /// this value increase over time, while we receive data 93 /// 94 @property long contentReceived() pure @nogc nothrow { 95 final switch ( _uri.scheme ) { 96 case "http", "https": 97 return _http.contentReceived; 98 case "ftp": 99 return _ftp.contentReceived; 100 } 101 } 102 /// get contentLength of the responce 103 @property long contentLength() pure @nogc nothrow { 104 final switch ( _uri.scheme ) { 105 case "http", "https": 106 return _http.contentLength; 107 case "ftp": 108 return _ftp.contentLength; 109 } 110 } 111 @property void sslSetVerifyPeer(bool v) { 112 _http.sslSetVerifyPeer(v); 113 } 114 @property void sslSetKeyFile(string path, SSLOptions.filetype type = SSLOptions.filetype.pem) pure @safe nothrow @nogc { 115 _http.sslSetKeyFile(path, type); 116 } 117 @property void sslSetCertFile(string path, SSLOptions.filetype type = SSLOptions.filetype.pem) pure @safe nothrow @nogc { 118 _http.sslSetCertFile(path, type); 119 } 120 @property void sslSetCaCert(string path) pure @safe nothrow @nogc { 121 _http.sslSetCaCert(path); 122 } 123 @property auto sslOptions() { 124 return _http.sslOptions(); 125 } 126 /// Add headers to request 127 /// Params: 128 /// headers = headers to send. 129 void addHeaders(in string[string] headers) { 130 _http.addHeaders(headers); 131 } 132 void clearHeaders() { 133 _http.clearHeaders(); 134 } 135 /// Execute GET for http and retrieve file for FTP. 136 /// You have to provide at least $(B uri). All other arguments should conform to HTTPRequest.get or FTPRequest.get depending on the URI scheme. 137 /// 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) 138 /// you will receive Exception("Operation not supported for ftp") 139 /// 140 Response get(A...)(string uri, A args) { 141 if ( uri ) { 142 _uri = URI(uri); 143 } 144 final switch ( _uri.scheme ) { 145 case "http", "https": 146 _http.uri = _uri; 147 static if (__traits(compiles, _http.get(null, args))) { 148 return _http.get(null, args); 149 } else { 150 throw new Exception("Operation not supported for http"); 151 } 152 case "ftp": 153 static if (args.length == 0) { 154 return _ftp.get(uri); 155 } else { 156 throw new Exception("Operation not supported for ftp"); 157 } 158 } 159 } 160 /// Execute POST for http and STOR file for FTP. 161 /// You have to provide $(B uri) and data. Data should conform to HTTPRequest.post or FTPRequest.post depending on the URI scheme. 162 /// When arguments do not conform scheme you will receive Exception("Operation not supported for ftp") 163 /// 164 Response post(A...)(string uri, A args) { 165 if ( uri ) { 166 _uri = URI(uri); 167 } 168 final switch ( _uri.scheme ) { 169 case "http", "https": 170 _http.uri = _uri; 171 static if (__traits(compiles, _http.post(null, args))) { 172 return _http.post(null, args); 173 } else { 174 throw new Exception("Operation not supported for http"); 175 } 176 case "ftp": 177 static if (__traits(compiles, _ftp.post(uri, args))) { 178 return _ftp.post(uri, args); 179 } else { 180 throw new Exception("Operation not supported for ftp"); 181 } 182 } 183 } 184 Response exec(string method="GET", A...)(A args) { 185 return _http.exec!(method)(args); 186 } 187 }