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