1 module telega.drivers.requests;
2 
3 version(TelegaRequestsDriver) enum HaveRequestsDriver = true;
4 else enum HaveRequestsDriver = false;
5 
6 static if(HaveRequestsDriver):
7 
8 import telega.http;
9 import requests;
10 import socks.socks5;
11 import vibe.core.log;
12 
13 class RequestsHttpClient: HttpClient
14 {
15     import core.time;
16 
17     protected:
18         string proxyHost;
19         ushort proxyPort;
20 
21     private:
22         Request rq;
23 
24     public:
25         this()
26         {
27             rq.socketFactory = &createNetworkStream;
28             rq.timeout = 0.seconds;
29         }
30 
31         string sendGetRequest(string url)
32         {
33             Response rs = rq.get(url);
34 
35             return rs.responseBody.toString();
36         }
37 
38         string sendPostRequestJson(string url, string bodyJson)
39         {
40             rq.addHeaders(["Content-Type": "application/json"]);
41             Response rs = rq.post(url, bodyJson);
42 
43             return rs.responseBody.toString();
44         }
45 
46         void setProxy(string host, ushort port)
47         {
48             proxyHost = host;
49             proxyPort = port;
50         }
51 
52     private:
53         NetworkStream createNetworkStream(string scheme, string host, ushort port)
54         {
55             NetworkStream stream = new TCPStream();
56             stream.readTimeout = 0.seconds;
57 
58             if (proxyHost !is null) {
59                 proxyConnect(stream, host, port);
60             }
61 
62             final switch (scheme) {
63                 case "http":
64                     stream.connect(host, port);
65                     break;
66 
67                 case "https":
68                     auto sslOptions = SSLOptions();
69                     sslOptions.setVerifyPeer(false); // TODO enable ssl check
70                     stream = new SSLStream(stream, sslOptions);
71                     stream.readTimeout = 0.seconds;
72                     break;
73             }
74 
75             return stream;
76         }
77 
78         void proxyConnect(NetworkStream stream, string host, ushort port)
79         {
80             const Socks5Options options = {
81                 host: proxyHost,
82                 port: proxyPort,
83                 resolveHost: true
84             };
85 
86             SocksTCPConnector connector = (in string host, in ushort port)
87             {
88                 stream.connect(host, port);
89 
90                 return true;
91             };
92             SocksDataReader reader = (ubyte[] data)
93             {
94                 stream.receive(data);
95             };
96             SocksDataWriter writer = (in ubyte[] data)
97             {
98                 stream.send(data);
99             };
100 
101             Socks5 proxy = Socks5(connector, reader, writer);
102             proxy.connect(options, host, port);
103         }
104 }