Skip to content

Commit

Permalink
Fix bug #5548
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanFreeman committed Nov 24, 2024
1 parent 0f8f2be commit f27e539
Show file tree
Hide file tree
Showing 9 changed files with 336 additions and 303 deletions.
150 changes: 81 additions & 69 deletions core-tests/src/network/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,34 +217,26 @@ TEST(client, shutdown_all) {
}

#ifdef SW_USE_OPENSSL
TEST(client, ssl_1) {
int ret;

TEST(client, ssl_1) {
bool connected = false;
bool closed = false;
swoole::String buf(65536);
String buf(65536);

swoole_event_init(SW_EVENTLOOP_WAIT_EXIT);

Client client(SW_SOCK_TCP, true);
client.enable_ssl_encrypt();
client.onConnect = [&connected](Client *cli) {
connected = true;
cli->send(cli,
SW_STRL("GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"Connection: close\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/51.0.2704.106 Safari/537.36"
"\r\n\r\n"),
0);
cli->send(cli, SW_STRL(TEST_REQUEST_BAIDU), 0);
};

client.onError = [](Client *cli) {};
client.onClose = [&closed](Client *cli) { closed = true; };
client.onReceive = [&buf](Client *cli, const char *data, size_t length) { buf.append(data, length); };
ret = client.connect(&client, "www.baidu.com", 443, -1, 0);
ASSERT_EQ(ret, 0);

ASSERT_EQ(client.connect(&client, TEST_DOMAIN_BAIDU, 443, -1, 0), 0);

swoole_event_wait();

Expand All @@ -253,89 +245,109 @@ TEST(client, ssl_1) {
ASSERT_TRUE(buf.contains("Baidu"));
}


TEST(client, http_proxy) {
int ret;
static void proxy_async_test(Client &client, bool https) {
swoole_event_init(SW_EVENTLOOP_WAIT_EXIT);

bool connected = false;
bool closed = false;
swoole::String buf(65536);

swoole_event_init(SW_EVENTLOOP_WAIT_EXIT);
String buf(65536);

Client client(SW_SOCK_TCP, true);
client.enable_ssl_encrypt();
client.http_proxy = new HttpProxy();
client.http_proxy->proxy_host = std::string(TEST_HTTP_PROXY_HOST);
client.http_proxy->proxy_port = TEST_HTTP_PROXY_PORT;
if (https) {
client.enable_ssl_encrypt();
}

client.onConnect = [&connected](Client *cli) {
connected = true;
cli->send(cli,
SW_STRL("GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"Connection: close\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/51.0.2704.106 Safari/537.36"
"\r\n\r\n"),
0);
cli->send(cli, SW_STRL(TEST_REQUEST_BAIDU), 0);
};

client.onError = [](Client *cli) {};
client.onClose = [&closed](Client *cli) { closed = true; };
client.onReceive = [&buf](Client *cli, const char *data, size_t length) { buf.append(data, length); };
ret = client.connect(&client, "www.baidu.com", 443, -1, 0);
ASSERT_EQ(ret, 0);

ASSERT_EQ(client.connect(&client, TEST_DOMAIN_BAIDU, https ? 443 : 80, -1, 0), 0);

swoole_event_wait();

ASSERT_TRUE(connected);
ASSERT_TRUE(closed);
ASSERT_TRUE(buf.contains("Baidu"));
ASSERT_TRUE(buf.contains("www.baidu.com"));
}

TEST(client, socks5_proxy) {
int ret;
static void proxy_sync_test(Client &client, bool https) {
String buf(65536);
if (https) {
client.enable_ssl_encrypt();
}

ASSERT_EQ(client.connect(&client, TEST_DOMAIN_BAIDU, https ? 443 : 80, -1, 0), 0);
ASSERT_GT(client.send(&client, SW_STRL(TEST_REQUEST_BAIDU), 0), 0);

while (true) {
char rbuf[4096];
auto nr = client.recv(&client, rbuf, sizeof(rbuf), 0);
if (nr <= 0) {
break;
}
buf.append(rbuf, nr);
}

ASSERT_TRUE(buf.contains("www.baidu.com"));
}

bool connected = false;
bool closed = false;
swoole::String buf(65536);
static void proxy_set_socks5_proxy(Client &client) {
client.socks5_proxy = create_socks5_proxy();
}

swoole_event_init(SW_EVENTLOOP_WAIT_EXIT);
static void proxy_set_http_proxy(Client &client) {
client.http_proxy = create_http_proxy();
}

TEST(client, https_get_async_with_http_proxy) {
Client client(SW_SOCK_TCP, true);
client.enable_ssl_encrypt();
proxy_set_http_proxy(client);
proxy_async_test(client, true);
}

client.socks5_proxy = new Socks5Proxy();
client.socks5_proxy->host = std::string("127.0.0.1");
client.socks5_proxy->port = 1080;
client.socks5_proxy->dns_tunnel = 1;
client.socks5_proxy->method = 0x02;
client.socks5_proxy->username = std::string("user");
client.socks5_proxy->password = std::string("password");
TEST(client, https_get_async_with_socks5_proxy) {
Client client(SW_SOCK_TCP, true);
proxy_set_socks5_proxy(client);
proxy_async_test(client, true);
}

client.onConnect = [&connected](Client *cli) {
connected = true;
cli->send(cli,
SW_STRL("GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"Connection: close\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/51.0.2704.106 Safari/537.36"
"\r\n\r\n"),
0);
};
TEST(client, https_get_sync_with_http_proxy) {
Client client(SW_SOCK_TCP, false);
proxy_set_http_proxy(client);
proxy_sync_test(client, true);
}

client.onError = [](Client *cli) {};
client.onClose = [&closed](Client *cli) { closed = true; };
client.onReceive = [&buf](Client *cli, const char *data, size_t length) { buf.append(data, length); };
ret = client.connect(&client, "www.baidu.com", 443, -1, 0);
ASSERT_EQ(ret, 0);
TEST(client, https_get_sync_with_socks5_proxy) {
Client client(SW_SOCK_TCP, false);
proxy_set_socks5_proxy(client);
proxy_sync_test(client, true);
}

swoole_event_wait();
TEST(client, http_get_async_with_http_proxy) {
Client client(SW_SOCK_TCP, true);
proxy_set_http_proxy(client);
proxy_async_test(client, false);
}

ASSERT_TRUE(connected);
ASSERT_TRUE(closed);
ASSERT_TRUE(buf.contains("Baidu"));
TEST(client, http_get_async_with_socks5_proxy) {
Client client(SW_SOCK_TCP, true);
proxy_set_socks5_proxy(client);
proxy_async_test(client, false);
}

TEST(client, http_get_sync_with_http_proxy) {
Client client(SW_SOCK_TCP, false);
proxy_set_http_proxy(client);
proxy_sync_test(client, false);
}

TEST(client, http_get_sync_with_socks5_proxy) {
Client client(SW_SOCK_TCP, false);
proxy_set_socks5_proxy(client);
proxy_sync_test(client, false);
}
#endif
27 changes: 19 additions & 8 deletions include/swoole_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
#include "swoole_protocol.h"
#include "swoole_proxy.h"

#define SW_HTTPS_PROXY_HANDSHAKE_RESPONSE "HTTP/1.1 200 Connection established"

namespace swoole {
namespace network {

Expand Down Expand Up @@ -105,12 +103,12 @@ class Client {
std::shared_ptr<SSLContext> ssl_context = nullptr;
#endif

std::function<void (Client *cli)> onConnect = nullptr;
std::function<void (Client *cli)> onError = nullptr;
std::function<void (Client *cli, const char *, size_t)> onReceive = nullptr;
std::function<void (Client *cli)> onClose = nullptr;
std::function<void (Client *cli)> onBufferFull = nullptr;
std::function<void (Client *cli)> onBufferEmpty = nullptr;
std::function<void(Client *cli)> onConnect = nullptr;
std::function<void(Client *cli)> onError = nullptr;
std::function<void(Client *cli, const char *, size_t)> onReceive = nullptr;
std::function<void(Client *cli)> onClose = nullptr;
std::function<void(Client *cli)> onBufferFull = nullptr;
std::function<void(Client *cli)> onBufferEmpty = nullptr;

int (*connect)(Client *cli, const char *host, int port, double _timeout, int sock_flag) = nullptr;
ssize_t (*send)(Client *cli, const char *data, size_t length, int flags) = nullptr;
Expand All @@ -131,6 +129,19 @@ class Client {
return socket;
}

SocketType get_socket_type() {
return socket->socket_type;
}

const std::string *get_http_proxy_host_name() {
#ifdef SW_USE_OPENSSL
if (ssl_context && !ssl_context->tls_host_name.empty()) {
return &ssl_context->tls_host_name;
}
#endif
return &http_proxy->target_host;
}

int sleep();
int wakeup();
int shutdown(int __how);
Expand Down
13 changes: 12 additions & 1 deletion include/swoole_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
#include <cstdint>

#define SW_SOCKS5_VERSION_CODE 0x05
#define SW_HTTP_PROXY_CHECK_MESSAGE 0
#define SW_HTTP_PROXY_HANDSHAKE_RESPONSE "HTTP/1.1 200 Connection established\r\n"

#define SW_HTTP_PROXY_FMT \
"CONNECT %.*s:%d HTTP/1.1\r\n" \
"Host: %.*s:%d\r\n" \
"User-Agent: Swoole/" SWOOLE_VERSION "\r\n" \
"Proxy-Connection: Keep-Alive\r\n"

enum swHttpProxyState {
SW_HTTP_PROXY_STATE_WAIT = 0,
Expand All @@ -40,6 +48,8 @@ enum swSocks5Method {
};

namespace swoole {
class String;

struct HttpProxy {
uint8_t state;
uint8_t dont_handshake;
Expand All @@ -49,9 +59,10 @@ struct HttpProxy {
std::string password;
std::string target_host;
int target_port;
char buf[512];

std::string get_auth_str();
size_t pack(String *send_buffer, const std::string *host_name);
bool handshake(String *recv_buffer);
};

struct Socks5Proxy {
Expand Down
Loading

0 comments on commit f27e539

Please sign in to comment.