1 module hunt.trace.v2api.HttpClient; 2 import std.net.curl; 3 import hunt.trace.Span; 4 import hunt.trace.Constrants; 5 import hunt.trace.Plugin; 6 import hunt.logging; 7 8 9 10 //// b3 header 11 /// https://github.com/openhunt.trace/b3-propagation 12 13 enum CONTENT_PLAIN = "plain/text"; 14 enum CONTENT_JSON = "application/json"; 15 enum CONTENT_ENCODE = "application/x-www-form-urlencoded"; 16 17 18 19 20 bool b3Get(string url , out string result , string[string] in_headers = string[string].init) 21 { 22 string[string] out_headers; 23 return b3Get(url ,in_headers ,out_headers, result); 24 } 25 26 bool b3Get(string url , string[string] in_headers , out string[string] out_headers , out string result ) 27 { 28 auto http = HTTP(url); 29 import std.array; 30 import std.conv; 31 import std.string; 32 auto w = appender!string; 33 34 string[string] tags; 35 string path = url; 36 auto pos = url.indexOf('?'); 37 if(pos != -1) 38 { 39 path = url[0 .. pos]; 40 } 41 42 tags[HTTP_HOST] = url; 43 tags[HTTP_URL] = path; 44 tags[HTTP_PATH] = path; 45 tags[HTTP_REQUEST_SIZE] = "0"; 46 tags[HTTP_METHOD] = "GET"; 47 auto span = traceSpanBefore(path); 48 if(span !is null) 49 in_headers["b3"] = span.traceId ~ "-" ~ span.parentId ~ "-" ~ "1" ~ "-" ~ span.id; 50 51 foreach( k , v ; in_headers) 52 http.addRequestHeader(k , v); 53 http.onReceiveHeader =(in char[] key, in char[] value) { out_headers[cast(string)key] =cast(string) value; }; 54 http.onReceive = (ubyte[] data) { w.put(cast(string)data); return data.length; }; 55 CurlCode code = http.perform(ThrowOnError.no); 56 bool flag = (code == 0); 57 string error = ""; 58 if(!flag) 59 { 60 logError(url , " " , http.statusLine , " code " , code); 61 error = "curl code " ~ to!string(code); 62 } 63 result = w.data; 64 65 tags[HTTP_STATUS_CODE] = to!string(http.statusLine.code); 66 tags[HTTP_RESPONSE_SIZE] = to!string(result.length); 67 68 traceSpanAfter(span , tags , error); 69 70 return flag; 71 } 72 73 74 75 bool b3Post(string url , 76 string text , 77 out string result, 78 string content_type = CONTENT_PLAIN, 79 string[string] in_headers = string[string].init 80 ) 81 { 82 string[string] out_header; 83 return b3Post(url , text,content_type, in_headers , result, out_header); 84 } 85 86 87 88 bool b3Post(string url , 89 string text , 90 string content_type, 91 string[string] in_headers , 92 out string result, 93 out string[string] out_headers , 94 ) 95 { 96 import std.conv; 97 import std.string; 98 auto http = HTTP(url); 99 import std.array; 100 auto w = appender!string; 101 102 string[string] tags; 103 string path = url; 104 auto pos = url.indexOf('?'); 105 if(pos != -1) 106 { 107 path = url[0 .. pos]; 108 } 109 110 tags[HTTP_HOST] = url; 111 tags[HTTP_URL] = path; 112 tags[HTTP_PATH] = path; 113 tags[HTTP_REQUEST_SIZE] = to!string(text.length); 114 tags[HTTP_METHOD] = "POST"; 115 auto span = traceSpanBefore(path); 116 if(span !is null) 117 in_headers["b3"] = span.traceId ~ "-" ~ span.parentId ~ "-" ~ "1" ~ "-" ~ span.id; 118 119 if(content_type != "") 120 http.setPostData(text , content_type); 121 122 foreach( k , v ; in_headers) 123 http.addRequestHeader(k , v); 124 http.onReceiveHeader =(in char[] key, in char[] value) { out_headers[cast(string)key] = cast(string)value; }; 125 http.onReceive = (ubyte[] data) { w.put(cast(string)data); return data.length; }; 126 CurlCode code = http.perform(); 127 result = w.data; 128 string error = ""; 129 bool flag = (code == 0); 130 if(!flag) 131 { 132 logError(url , " " , http.statusLine , " code " , code); 133 error = "curl code:" ~ to!string(code); 134 } 135 136 tags[HTTP_STATUS_CODE] = to!string(http.statusLine.code); 137 tags[HTTP_RESPONSE_SIZE] = to!string(result.length); 138 139 140 traceSpanAfter(span , tags , error); 141 142 return flag; 143 }