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
16 #include "curl/curl.h"
17 #include "net_conn_client.h"
18 #include "net_connection.h"
19 #include "pac_server.h"
20 #include "proxy_server.h"
21 #include "security_config.h"
22 #include "gtest/gtest.h"
23 #include <iostream>
24
25 using namespace OHOS::NetManagerStandard;
26 std::map<int32_t, std::shared_ptr<ProxyServer>> services;
27 #define PACPROXYSERVER 9000
28 #define GLOBALPROXYSERVER 9001
29 #define PORT_8080 8080
30 #define PORT_8889 8889
31 #define TIME_500_MS 500
32 #define TIMEOUT_10_S 30
33
StartProxyServer(int32_t port)34 static void StartProxyServer(int32_t port)
35 {
36 std::shared_ptr<ProxyServer> server = std::make_shared<ProxyServer>(port);
37 services.insert({port, server});
38 server->Start();
39 }
40
WriteCallback(void * contents,size_t size,size_t nmemb,std::string * userp)41 static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *userp)
42 {
43 size_t totalSize = size * nmemb;
44 userp->append(static_cast<char *>(contents), totalSize);
45 return totalSize;
46 }
47
Request(std::string url,std::string ip,uint16_t port)48 static std::string Request(std::string url, std::string ip, uint16_t port)
49 {
50 CURL *curl;
51 CURLcode res;
52 std::string readBuffer;
53 curl_global_init(CURL_GLOBAL_DEFAULT);
54 curl = curl_easy_init();
55 if (curl) {
56 struct curl_slist *headers = nullptr;
57 std::string proxyStr = "GlobalProxyIp: " + ip;
58 std::string proxyPortStr = "GlobalProxyPort: " + std::to_string(port);
59 headers = curl_slist_append(headers, proxyStr.c_str());
60 headers = curl_slist_append(headers, proxyPortStr.c_str());
61 headers = curl_slist_append(headers, "X-Custom-Header: CustomValue");
62 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
63 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
64 if (!ip.empty()) {
65 std::string proxy = "http://" + ip + ":" + std::to_string(port);
66 printf(
67 "\033[32m"
68 "curl %s use poxy %s \n"
69 "\033[0m",
70 url.c_str(), proxy.c_str());
71 curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str());
72 }
73 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
74 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
75 curl_easy_setopt(curl, CURLOPT_TIMEOUT, TIMEOUT_10_S);
76 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
77 res = curl_easy_perform(curl);
78 if (res != CURLE_OK) {
79 std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
80 } else {
81 long httpCode = 0;
82 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
83 printf(
84 "\033[32m"
85 "HTTP Status Code: %d Response:%s \n"
86 "\033[0m",
87 httpCode, readBuffer.c_str());
88 }
89 curl_slist_free_all(headers);
90 curl_easy_cleanup(curl);
91 }
92 curl_global_cleanup();
93 return readBuffer;
94 }
95
SetPacFileUrl(std::string url)96 static int32_t SetPacFileUrl(std::string url)
97 {
98 int32_t ret = OH_NetConn_SetPacFileUrl(url.c_str());
99 usleep(TIME_500_MS);
100 return ret;
101 }
102
FindProxyForURL(std::string url)103 static std::tuple<int32_t, std::string> FindProxyForURL(std::string url)
104 {
105 char proxy[1024];
106 int32_t ret = OH_NetConn_FindProxyForURL(url.c_str(), nullptr, proxy);
107 return {ret, proxy};
108 }
109
TestAutoMode()110 void TestAutoMode()
111 {
112 NetConn_HttpProxy proxy;
113 int32_t ret = -1;
114 OHOS::NetManagerStandard::ProxyModeType mode;
115 std::string script = ProxyServer::pacScripts[LOCAL_PROXY_9000];
116 StartHttpServer(PORT_8889, "", script);
117 std::string pacFileUrl = "http://127.0.0.1:8889/";
118 ret = SetPacFileUrl(pacFileUrl);
119 EXPECT_EQ(ret, 0);
120 ret = OH_NetConn_SetProxyMode(PROXY_MODE_AUTO);
121 EXPECT_EQ(ret, 0);
122
123 ret = OH_NetConn_GetProxyMode(&mode);
124 EXPECT_EQ(ret, 0);
125 EXPECT_EQ(mode, ProxyModeType::PROXY_MODE_AUTO);
126
127 ret = OH_NetConn_GetDefaultHttpProxy(&proxy);
128 EXPECT_EQ(ret, 0);
129 EXPECT_EQ(std::string(proxy.host), "127.0.0.1");
130 printf("mode %d host:%s port:%d \n", mode, proxy.host, proxy.port);
131
132 // Test FindProxyForURL default rule returns DIRECT
133 auto result = FindProxyForURL("http://127.0.0.1:3888/test");
134 EXPECT_EQ(std::get<0>(result), 0);
135 EXPECT_EQ(std::get<1>(result), "PROXY 127.0.0.1:9000");
136
137 std::string url = "http://127.0.0.1:8080/test";
138 std::string res = Request(url, proxy.host, proxy.port);
139 printf("res %s %s \n", url.c_str(), res.c_str());
140 EXPECT_EQ(res.empty(), false);
141 }
142
TEST(PROXY_SWITCH_TEST,PacFileUrlClient)143 TEST(PROXY_SWITCH_TEST, PacFileUrlClient)
144 {
145 SetUpPermission();
146 StartHttpServer(PORT_8080, "", "");
147 StartProxyServer(GLOBALPROXYSERVER);
148 StartProxyServer(PACPROXYSERVER);
149 TestAutoMode();
150 OHOS::NetManagerStandard::ProxyModeType mode;
151 int32_t ret = OH_NetConn_SetProxyMode(PROXY_MODE_OFF);
152 EXPECT_EQ(ret, 0);
153 NetConn_HttpProxy proxy;
154 ret = OH_NetConn_GetProxyMode(&mode);
155 EXPECT_EQ(ret, 0);
156 EXPECT_EQ(mode, 0);
157
158 ret = OH_NetConn_GetDefaultHttpProxy(&proxy);
159 EXPECT_EQ(ret, 0);
160 printf("mode %d host:%s port:%d \n", mode, proxy.host, proxy.port);
161 UnsetUpPermission();
162 }