1 2 /** Small helpers for libCURL 3 * 4 * This module contains all the CURL related helpers. 5 */ 6 module acme.curl_helpers; 7 8 import etc.c.curl; 9 10 import std.conv; 11 import std.net.curl; 12 import std.stdio; 13 import std.string; 14 import std.typecons; 15 16 /** Current release number - FIXME Derive this from Git Tag. How in D? */ 17 enum acmeClientVersion = "0.0.1"; 18 19 /** Compose an error msg from custom and CURL error 20 * 21 * Params: 22 * msg - custom message 23 */ 24 string getCurlError(string s, CURLcode c) 25 { 26 import std.format; 27 auto errorstring = curl_easy_strerror(c).to!string; 28 auto resultstring = format( "%s\nErrorcode: %d (%s)", s, c, errorstring); 29 return resultstring; 30 } 31 32 /* ---------------------------------------------------------------------------- */ 33 34 /** Get just the http receive headers with a given name from an URL 35 36 Params: 37 url - Url to query 38 headerKey - headerline to query 39 Returns: 40 the value of a given header or null 41 */ 42 string getResponseHeader(string url, string headerKey) 43 { 44 string headerVal; 45 46 auto http = HTTP(url); 47 http.setUserAgent = "acme-lw-d/" ~ acmeClientVersion ~ " " ~ HTTP.defaultUserAgent(); 48 http.method = HTTP.Method.head; 49 http.onReceiveHeader = 50 (in char[] key, in char[] value) 51 { 52 writeln( "Response Header : ", key, " = ", value); 53 if (key.toLower == headerKey.toLower) 54 headerVal = value.idup; 55 }; 56 http.perform(); 57 return headerVal; 58 } 59 60 /* ---------------------------------------------------------------------------- */ 61 62 /** Do some posting, filter for some headerkey 63 * 64 * Params: 65 * url - url to pst to 66 * postBody - data to post 67 * rheaders - responseheader to return 68 * nonce - pointer to nonce string, so that we can update it. 69 * 70 * Returns: 71 * the received payload of the POST operation 72 */ 73 string doPost(string url, char[] postBody, HTTP.StatusLine* status, 74 string[string]* rheaders, 75 string* nonce) 76 { 77 string response; 78 string headerVal; 79 80 auto http = HTTP(url); 81 http.setUserAgent = "acme-lw-d/" ~ acmeClientVersion ~ " " ~ HTTP.defaultUserAgent(); 82 http.verbose = true; 83 http.method = HTTP.Method.post; 84 http.addRequestHeader("Content-Type", "application/jose+json"); 85 86 http.onReceiveHeader = 87 (in char[] key, in char[] value) 88 { 89 if (key.toLower == "replay-nonce") { 90 *nonce = value.idup; 91 writeln("Setting new NOnce: ", *nonce); 92 } 93 }; 94 http.onReceive = 95 (ubyte[] data) 96 { 97 //writefln( "data: %s", to!string(data)); 98 response ~= data; 99 return data.length; 100 }; 101 http.postData = postBody; 102 103 http.perform(); 104 105 if (status !is null) *status = http.statusLine; 106 107 if (rheaders !is null) 108 *rheaders = http.responseHeaders; 109 110 return response; 111 } 112 113 /* ---------------------------------------------------------------------------- */ 114