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 }