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