Skip to content

Commit f5b73c6

Browse files
committed
Refactor HttpProxy, fix #5548
1 parent 741e352 commit f5b73c6

File tree

8 files changed

+252
-219
lines changed

8 files changed

+252
-219
lines changed

include/swoole_client.h

-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#include "swoole_protocol.h"
2424
#include "swoole_proxy.h"
2525

26-
#define SW_HTTPS_PROXY_HANDSHAKE_RESPONSE "HTTP/1.1 200 Connection established"
27-
2826
namespace swoole {
2927
namespace network {
3028

include/swoole_proxy.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
#include <cstdint>
2121

2222
#define SW_SOCKS5_VERSION_CODE 0x05
23+
#define SW_HTTP_PROXY_CHECK_MESSAGE 0
24+
#define SW_HTTP_PROXY_HANDSHAKE_RESPONSE "HTTP/1.1 200 Connection established\r\n"
25+
26+
#define SW_HTTP_PROXY_FMT \
27+
"CONNECT %.*s:%d HTTP/1.1\r\n" \
28+
"Host: %.*s:%d\r\n" \
29+
"User-Agent: Swoole/" SWOOLE_VERSION "\r\n" \
30+
"Proxy-Connection: Keep-Alive\r\n"
2331

2432
enum swHttpProxyState {
2533
SW_HTTP_PROXY_STATE_WAIT = 0,
@@ -40,6 +48,8 @@ enum swSocks5Method {
4048
};
4149

4250
namespace swoole {
51+
class String;
52+
4353
struct HttpProxy {
4454
uint8_t state;
4555
uint8_t dont_handshake;
@@ -49,9 +59,10 @@ struct HttpProxy {
4959
std::string password;
5060
std::string target_host;
5161
int target_port;
52-
char buf[512];
5362

5463
std::string get_auth_str();
64+
size_t pack(String *send_buffer, const std::string *host_name);
65+
bool handshake(String *recv_buffer);
5566
};
5667

5768
struct Socks5Proxy {

src/coroutine/socket.cc

+11-100
Original file line numberDiff line numberDiff line change
@@ -351,20 +351,10 @@ bool Socket::socks5_handshake() {
351351
}
352352

353353
bool Socket::http_proxy_handshake() {
354-
#define HTTP_PROXY_FMT \
355-
"CONNECT %.*s:%d HTTP/1.1\r\n" \
356-
"Host: %.*s:%d\r\n" \
357-
"User-Agent: Swoole/" SWOOLE_VERSION "\r\n" \
358-
"Proxy-Connection: Keep-Alive\r\n"
359-
360-
// CONNECT
361-
int n;
362-
const char *host = http_proxy->target_host.c_str();
363-
int host_len = http_proxy->target_host.length();
354+
const std::string *real_host = &http_proxy->target_host;
364355
#ifdef SW_USE_OPENSSL
365356
if (ssl_context && !ssl_context->tls_host_name.empty()) {
366-
host = ssl_context->tls_host_name.c_str();
367-
host_len = ssl_context->tls_host_name.length();
357+
real_host = &ssl_context->tls_host_name;
368358
}
369359
#endif
370360

@@ -373,34 +363,11 @@ bool Socket::http_proxy_handshake() {
373363
send_buffer->clear();
374364
};
375365

376-
if (!http_proxy->password.empty()) {
377-
auto auth_str = http_proxy->get_auth_str();
378-
n = sw_snprintf(send_buffer->str,
379-
send_buffer->size,
380-
HTTP_PROXY_FMT "Proxy-Authorization: Basic %s\r\n\r\n",
381-
(int) http_proxy->target_host.length(),
382-
http_proxy->target_host.c_str(),
383-
http_proxy->target_port,
384-
host_len,
385-
host,
386-
http_proxy->target_port,
387-
auth_str.c_str());
388-
} else {
389-
n = sw_snprintf(send_buffer->str,
390-
send_buffer->size,
391-
HTTP_PROXY_FMT "\r\n",
392-
(int) http_proxy->target_host.length(),
393-
http_proxy->target_host.c_str(),
394-
http_proxy->target_port,
395-
host_len,
396-
host,
397-
http_proxy->target_port);
398-
}
399-
400-
swoole_trace_log(SW_TRACE_HTTP_CLIENT, "proxy request: <<EOF\n%.*sEOF", n, send_buffer->str);
401-
366+
size_t n = http_proxy->pack(send_buffer, real_host);
402367
send_buffer->length = n;
403-
if (send(send_buffer->str, n) != n) {
368+
swoole_trace_log(SW_TRACE_HTTP_CLIENT, "proxy request: <<EOF\n%.*sEOF", (int) n, send_buffer->str);
369+
370+
if (send(send_buffer->str, n) != (ssize_t) n) {
404371
return false;
405372
}
406373

@@ -415,61 +382,20 @@ bool Socket::http_proxy_handshake() {
415382
protocol.package_eof_len = sizeof("\r\n\r\n") - 1;
416383
memcpy(protocol.package_eof, SW_STRS("\r\n\r\n"));
417384

418-
n = recv_packet();
419-
if (n <= 0) {
385+
if (recv_packet() <= 0) {
420386
return false;
421387
}
422388

423389
swoole_trace_log(SW_TRACE_HTTP_CLIENT, "proxy response: <<EOF\n%.*sEOF", n, recv_buffer->str);
424390

425-
bool ret = false;
426-
char *buf = recv_buffer->str;
427-
int len = n;
428-
int state = 0;
429-
char *p = buf;
430-
char *pe = buf + len;
431-
for (; p < buf + len; p++) {
432-
if (state == 0) {
433-
if (SW_STR_ISTARTS_WITH(p, pe - p, "HTTP/1.1") || SW_STR_ISTARTS_WITH(p, pe - p, "HTTP/1.0")) {
434-
state = 1;
435-
p += sizeof("HTTP/1.x") - 1;
436-
} else {
437-
break;
438-
}
439-
} else if (state == 1) {
440-
if (isspace(*p)) {
441-
continue;
442-
} else {
443-
if (SW_STR_ISTARTS_WITH(p, pe - p, "200")) {
444-
state = 2;
445-
p += sizeof("200") - 1;
446-
} else {
447-
break;
448-
}
449-
}
450-
} else if (state == 2) {
451-
ret = true;
452-
break;
453-
#if 0
454-
if (isspace(*p)) {
455-
continue;
456-
} else {
457-
if (SW_STR_ISTARTS_WITH(p, pe - p, "Connection established")) {
458-
ret = true;
459-
}
460-
break;
461-
}
462-
#endif
463-
}
464-
}
465-
466-
if (!ret) {
391+
if (!http_proxy->handshake(recv_buffer)) {
467392
set_err(SW_ERROR_HTTP_PROXY_BAD_RESPONSE,
468393
std::string("wrong http_proxy response received, \n[Request]: ") + send_buffer->to_std_string() +
469-
"\n[Response]: " + std::string(buf, len));
394+
"\n[Response]: " + send_buffer->to_std_string());
395+
return false;
470396
}
471397

472-
return ret;
398+
return true;
473399
}
474400

475401
void Socket::init_sock_type(SocketType _type) {
@@ -1830,19 +1756,4 @@ Socket::~Socket() {
18301756
}
18311757

18321758
} // namespace coroutine
1833-
1834-
std::string HttpProxy::get_auth_str() {
1835-
char auth_buf[256];
1836-
char encode_buf[512];
1837-
size_t n = sw_snprintf(auth_buf,
1838-
sizeof(auth_buf),
1839-
"%.*s:%.*s",
1840-
(int) username.length(),
1841-
username.c_str(),
1842-
(int) password.length(),
1843-
password.c_str());
1844-
base64_encode((unsigned char *) auth_buf, n, encode_buf);
1845-
return std::string(encode_buf);
1846-
}
1847-
18481759
} // namespace swoole

0 commit comments

Comments
 (0)