• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef PROXY_SERVER_H
16 #define PROXY_SERVER_H
17 
18 #include "map"
19 #include <atomic>
20 #include <chrono>
21 #include <condition_variable>
22 #include <functional>
23 #include <mutex>
24 #include <netinet/in.h>
25 #include <queue>
26 #include <string>
27 #include <thread>
28 #include <unordered_map>
29 #include <vector>
30 
31 namespace OHOS {
32 namespace NetManagerStandard {
33 
34 #define LOCAL_PROXY_9000 "local_proxy_9000"
35 #define LOCAL_PROXY_9001 "local_proxy_9001"
36 #define ALL_DIRECT "local_proxy_all"
37 
38 struct Stats {
39     std::atomic<uint64_t> totalConnections;
40     std::atomic<uint64_t> activeConnections;
41     std::atomic<uint64_t> httpRequests;
42     std::atomic<uint64_t> httpsRequests;
43     std::atomic<uint64_t> bytesReceived;
44     std::atomic<uint64_t> bytesSent;
45     std::chrono::time_point<std::chrono::steady_clock> startTime;
46 
StatsStats47     Stats()
48         : totalConnections(0),
49           activeConnections(0),
50           httpRequests(0), httpsRequests(0), bytesReceived(0), bytesSent(0)
51     {
52     }
53 };
54 class ProxyServer {
55 public:
56     explicit ProxyServer(int32_t port = 8080, int32_t numThreads = 0);
57 
58     ~ProxyServer();
59 
60     void SetFindPacProxyFunction(std::function<std::string(std::string, std::string)> pac);
61 
62     bool Start();
63 
64     void Stop();
65 
66     bool IsRunning() const;
67 
68     std::shared_ptr<Stats> GetStats();
69 
70     void ResetStats();
71 
72     double GetThroughput() const;
73 
74     int32_t FindAvailablePort(int32_t startPort = 1024, int32_t endPort = 65535);
75 
76     static std::string proxServerTargetUrl;
77     static int32_t proxServerPort;
78     static std::map<std::string, std::string> pacScripts;
79 private:
80     bool IsPortAvailable(int32_t port);
81     void ForwardResponseToClient(int32_t clientSocket, int32_t serverSocket);
82     void SendErrorResponse(int32_t clientSocket, const char *response);
83     bool SetSocketTimeout(int32_t socket);
84     bool ReadRequestHeader(int32_t clientSocket, std::string &requestHeader);
85     void CleanupConnection(int32_t clientSocket);
86     void HandleConnectRequest(int32_t clientSocket, const std::string &requestHeader, const std::string &url);
87     void HandleHttpRequest(int32_t clientSocket, std::string &requestHeader, const std::string &url);
88     bool ParsePacResult(const std::string &pacResult, std::string &proxyType,
89                 std::string &proxyHost, int32_t &proxyPort);
90     int32_t EstablishServerConnection(const std::string &url, const std::string &host, int32_t port,
91                                   const std::string &requestType, std::string &requestHeader);
92     bool ParseProxyInfo(std::string url, std::string host, std::string &proxyType, std::string &proxyHost,
93                         int32_t &proxyPort);
94 
95     struct ClientTask {
96         int32_t clientSocket;
97         struct sockaddr_in clientAddr;
98 
ClientTaskClientTask99         ClientTask(int32_t socket, const struct sockaddr_in &addr) : clientSocket(socket), clientAddr(addr) {}
100     };
101 
102     void HandleClient(int32_t clientSocket);
103 
104     std::string GetRequestUrl(const std::string &header);
105 
106     std::string GetRequestMethod(const std::string &header);
107 
108     bool ParseConnectRequest(const std::string &header, std::string &host, int32_t &port);
109 
110     bool ParseHttpRequest(const std::string &header, std::string &host, int32_t &port);
111 
112     void TunnelData(int32_t client, int32_t server);
113 
114     int ConnectToServer(const std::string &host, int port);
115 
116     int ConnectViaUpstreamProxy(const std::string &targetHost, int targetPort, const std::string &originalRequest,
117                                 std::string proxyHost, int proxyPort);
118 
119     int ConnectViaUpstreamProxyHttps(const std::string &targetHost, int targetPort, std::string proxyHost,
120                                      int proxyPort);
121 
122     void AcceptLoop();
123 
124     void WorkerThread();
125 
126     void AddTask(const ClientTask &task);
127 
128     std::string ReceiveResponseHeader(int32_t socket);
129 
130     int port_;
131     int serverSocket_;
132     int numThreads_;
133     std::atomic<bool> running_;
134     std::thread acceptThread_;
135     std::vector<std::thread> workers_;
136 
137     std::function<std::string(std::string, std::string)> pacFunction_;
138     std::queue<ClientTask> taskQueue_;
139     std::mutex queueMutex_;
140     std::condition_variable queueCondition_;
141 
142     mutable std::mutex statsMutex_;
143     std::shared_ptr<Stats> stats_;
144 
145     static const int bufferSize = 8192;
146     static const int backlog = 128;
147     static const int maxHeaderSize = 8192;
148 };
149 } // namespace NetManagerStandard
150 } // namespace OHOS
151 #endif // PROXY_SERVER_H
152