• 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 <atomic>
19 #include <chrono>
20 #include <condition_variable>
21 #include <functional>
22 #include <mutex>
23 #include <netinet/in.h>
24 #include <queue>
25 #include <string>
26 #include <thread>
27 #include <vector>
28 namespace OHOS {
29 namespace NetManagerStandard {
30 
31 class ProxyServer {
32 public:
33     ProxyServer(int port, int numThreads);
34     ~ProxyServer();
35     void SetFindPacProxyFunction(std::function<std::string(std::string, std::string)> pac);
36     bool Start();
37     void Stop();
38     bool IsRunning() const;
39     double GetThroughput() const;
40     static int FindAvailablePort(int startPort, int endPort);
41 private:
42     struct ProxyConfig {
43         std::string type;
44         std::string host;
45         int port;
46     };
47     ssize_t SendAll(int sockfd, const void* buffer, size_t length, int32_t flag);
48     static bool IsPortAvailable(int port);
49     void ParsePacResult(const std::string &pacResult, std::vector<ProxyConfig> &proxyList);
50     int HandleDirectConnection(const std::string &targetHost, int targetPort, bool isHttps,
51                                const std::string &requestHeader);
52     int HandleProxyConnection(const std::string &targetHost, int targetPort, const std::string &proxyHost,
53                               int proxyPort, bool isHttps, const std::string &requestHeader);
54     void LogSuccessfulConnection(const std::string &proxyType,
55                             const std::string &targetHost, int targetPort,
56                             const std::string &proxyHost, int proxyPort);
57     void LogFailedConnection(const std::string &proxyType,
58                             const std::string &targetHost, int targetPort,
59                             const std::string &proxyHost, int proxyPort);
60     void GetProxyList(std::string url, std::string host, std::vector<ProxyConfig> &proxyList);
61     bool ReadRequestHeader(int clientSocket, std::string &requestHeader);
62     int TryConnectWithProxyList(const std::string &targetHost, int targetPort,
63                                 const std::vector<ProxyConfig> &proxyList, bool isHttps,
64                                 const std::string &requestHeader = "");
65     void HandleConnectRequest(int clientSocket, const std::string &requestHeader, const std::string &url);
66     void HandleHttpRequest(int clientSocket, const std::string &requestHeader, const std::string &url);
67     void SendErrorResponse(int clientSocket, const char *response);
68     void ForwardData(int fromSocket, int toSocket);
69     struct ClientTask {
70         int clientSocket_;
71         struct sockaddr_in clientAddr_;
ClientTaskClientTask72         ClientTask(int socket, const struct sockaddr_in &addr) : clientSocket_(socket), clientAddr_(addr) {}
73     };
74     void HandleClient(int clientSocket);
75     std::string GetRequestUrl(const std::string &header);
76     std::string GetRequestMethod(const std::string &header);
77     bool ParseConnectRequest(const std::string &header, std::string &host, int &port);
78     bool ParseHttpRequest(const std::string &header, std::string &host, int &port);
79     void TunnelData(int client, int server);
80     int ConnectToServer(const std::string &host, int port);
81     int ConnectViaUpstreamProxy(const std::string &targetHost, int targetPort, const std::string &originalRequest,
82                                 std::string proxyHost, int proxyPort);
83     int ConnectViaUpstreamProxyHttps(const std::string &targetHost, int targetPort, std::string proxyHost,
84                                      int proxyPort);
85     void AcceptLoop();
86     void WorkerThread();
87     void AddTask(const ClientTask &task);
88     std::string ReceiveResponseHeader(int socket);
89     int port_;
90     int serverSocket_;
91     int numThreads_;
92     std::atomic<bool> running_;
93     std::thread acceptThread_;
94     std::vector<std::thread> workers_;
95     std::function<std::string(std::string, std::string)> pacFunction_;
96     std::queue<ClientTask> taskQueue_;
97     std::mutex queueMutex_;
98     std::condition_variable queueCondition_;
99 };
100 } // namespace NetManagerStandard
101 } // namespace OHOS
102 #endif // PROXY_SERVER_H
103