2020-01-21 19:48:05 +08:00
|
|
|
#include "http.h"
|
|
|
|
#include "proxy.h"
|
|
|
|
|
2020-03-24 11:46:32 +08:00
|
|
|
int sslEncodeCode;
|
|
|
|
|
|
|
|
/* 对数据进行编码 */
|
2020-06-20 16:59:51 +08:00
|
|
|
void dataEncode(char *data, int data_len)
|
2020-03-24 11:46:32 +08:00
|
|
|
{
|
|
|
|
if (sslEncodeCode)
|
|
|
|
while (data_len-- > 0)
|
|
|
|
data[data_len] ^= sslEncodeCode;
|
|
|
|
}
|
|
|
|
|
2020-06-08 20:28:15 +08:00
|
|
|
static char *read_data(conn * in, char *data, int *data_len)
|
2020-01-21 19:48:05 +08:00
|
|
|
{
|
|
|
|
char *new_data;
|
|
|
|
int read_len;
|
|
|
|
|
|
|
|
do {
|
|
|
|
new_data = (char *)realloc(data, *data_len + BUFFER_SIZE + 1);
|
|
|
|
if (new_data == NULL) {
|
|
|
|
free(data);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
data = new_data;
|
|
|
|
read_len = read(in->fd, data + *data_len, BUFFER_SIZE);
|
|
|
|
// 判断是否关闭连接
|
|
|
|
if (read_len <= 0) {
|
|
|
|
if (read_len == 0 || *data_len == 0 || errno != EAGAIN) {
|
|
|
|
free(data);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*data_len += read_len;
|
|
|
|
} while (read_len == BUFFER_SIZE);
|
|
|
|
*(data + *data_len) = '\0';
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2020-06-08 20:28:15 +08:00
|
|
|
void close_connection(conn * conn)
|
2020-01-21 19:48:05 +08:00
|
|
|
{
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL);
|
|
|
|
close(conn->fd);
|
|
|
|
if ((conn - cts) & 1) {
|
|
|
|
char *server_data;
|
|
|
|
server_data = conn->header_buffer;
|
|
|
|
memset(conn, 0, sizeof(*conn));
|
|
|
|
conn->header_buffer = server_data;
|
|
|
|
conn--->fd = -1;
|
|
|
|
} else {
|
|
|
|
free(conn->header_buffer);
|
|
|
|
memset(conn, 0, sizeof(*conn));
|
|
|
|
conn++->fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conn->fd >= 0)
|
|
|
|
close_connection(conn);
|
|
|
|
}
|
|
|
|
|
2020-06-08 20:28:15 +08:00
|
|
|
static void serverToClient(conn * server)
|
2020-01-21 19:48:05 +08:00
|
|
|
{
|
|
|
|
int write_len;
|
|
|
|
conn *client;
|
|
|
|
client = server - 1;
|
|
|
|
|
|
|
|
while ((server->header_buffer_len = read(server->fd, server->header_buffer, BUFFER_SIZE)) > 0) {
|
2020-03-24 11:46:32 +08:00
|
|
|
dataEncode(server->header_buffer, server->header_buffer_len);
|
2020-01-21 19:48:05 +08:00
|
|
|
write_len = write(client->fd, server->header_buffer, server->header_buffer_len);
|
|
|
|
if (write_len <= 0) {
|
|
|
|
if (write_len == 0 || errno != EAGAIN)
|
|
|
|
close_connection(server);
|
|
|
|
else
|
|
|
|
server->sent_len = 0;
|
|
|
|
return;
|
|
|
|
} else if (write_len < server->header_buffer_len) {
|
|
|
|
server->sent_len = write_len;
|
|
|
|
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
|
|
|
ev.data.ptr = client;
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, client->fd, &ev);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (server->header_buffer_len < BUFFER_SIZE)
|
|
|
|
break;
|
|
|
|
}
|
2020-06-08 20:28:15 +08:00
|
|
|
if (server->header_buffer_len == 0 || (server->header_buffer_len == -1 && errno != EAGAIN))
|
2020-01-21 19:48:05 +08:00
|
|
|
close_connection(server);
|
|
|
|
else
|
|
|
|
server->header_buffer_len = server->sent_len = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-06-08 20:28:15 +08:00
|
|
|
void clienttoserver(conn * in)
|
2020-01-21 19:48:05 +08:00
|
|
|
{
|
|
|
|
int write_len;
|
|
|
|
conn *remote;
|
|
|
|
remote = in + 1;
|
2020-06-08 20:28:15 +08:00
|
|
|
|
2020-01-21 19:48:05 +08:00
|
|
|
write_len = write(remote->fd, in->header_buffer, in->header_buffer_len);
|
|
|
|
if (write_len == in->header_buffer_len) {
|
|
|
|
in->header_buffer_len = 0;
|
|
|
|
in->header_buffer = NULL;
|
|
|
|
} else {
|
|
|
|
close_connection(remote);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 判断请求类型
|
|
|
|
static int8_t request_type(char *data)
|
|
|
|
{
|
2020-06-08 20:28:15 +08:00
|
|
|
if (strncmp(data, "GET", 3) == 0 || strncmp(data, "POST", 4) == 0 || strncmp(data, "CONNECT", 7) == 0 || strncmp(data, "HEAD", 4) == 0 || strncmp(data, "PUT", 3) == 0 || strncmp(data, "OPTIONS", 7) == 0 || strncmp(data, "MOVE", 4) == 0 || strncmp(data, "COPY", 4) == 0 || strncmp(data, "TRACE", 5) == 0 || strncmp(data, "DELETE", 6) == 0 || strncmp(data, "LINK", 4) == 0 || strncmp(data, "UNLINK", 6) == 0 || strncmp(data, "PATCH", 5) == 0 || strncmp(data, "WRAPPED", 7) == 0)
|
2020-01-21 19:48:05 +08:00
|
|
|
return HTTP_TYPE;
|
|
|
|
return OTHER_TYPE;
|
|
|
|
}
|
|
|
|
|
2020-06-08 20:28:15 +08:00
|
|
|
void tcp_in(conn * in, conf * configure)
|
2020-01-21 19:48:05 +08:00
|
|
|
{
|
|
|
|
if (in->fd < 0)
|
|
|
|
return;
|
|
|
|
// 如果in - cts是奇数,那么是服务端触发事件
|
|
|
|
if ((in - cts) & 1) {
|
2020-06-08 20:28:15 +08:00
|
|
|
in->timer = (in - 1)->timer = 0;
|
2020-01-21 19:48:05 +08:00
|
|
|
serverToClient(in);
|
|
|
|
return;
|
|
|
|
}
|
2020-06-08 20:28:15 +08:00
|
|
|
in->timer = (in + 1)->timer = 0;
|
2020-01-21 19:48:05 +08:00
|
|
|
in->header_buffer = read_data(in, in->header_buffer, &in->header_buffer_len);
|
|
|
|
if (in->header_buffer != NULL) {
|
|
|
|
if (request_type(in->header_buffer) == HTTP_TYPE) {
|
|
|
|
in->header_buffer = request_head(in, configure);
|
|
|
|
struct epoll_event epollEvent;
|
|
|
|
conn *remote;
|
|
|
|
remote = in + 1;
|
|
|
|
remote->fd = create_connection(remote_host, remote_port);
|
2020-06-08 20:28:15 +08:00
|
|
|
epollEvent.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
2020-01-21 19:48:05 +08:00
|
|
|
epollEvent.data.ptr = remote;
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, remote->fd, &epollEvent);
|
|
|
|
}
|
|
|
|
}
|
2020-03-24 11:46:32 +08:00
|
|
|
dataEncode(in->header_buffer, in->header_buffer_len);
|
2020-01-21 19:48:05 +08:00
|
|
|
clienttoserver(in);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-08 20:28:15 +08:00
|
|
|
void tcp_out(conn * out)
|
2020-01-21 19:48:05 +08:00
|
|
|
{
|
|
|
|
conn *from;
|
|
|
|
int write_len;
|
|
|
|
|
|
|
|
if (out->fd == -1)
|
|
|
|
return;
|
|
|
|
else if ((out - cts) & 1)
|
|
|
|
from = out - 1;
|
|
|
|
else
|
|
|
|
from = out + 1;
|
|
|
|
from->timer = out->timer = 0;
|
|
|
|
write_len = write(out->fd, from->header_buffer + from->sent_len, from->header_buffer_len - from->sent_len);
|
|
|
|
if (write_len == from->header_buffer_len - from->sent_len) {
|
|
|
|
// 服务端的数据可能没全部写入到客户端
|
|
|
|
if ((from - cts) & 1) {
|
|
|
|
serverToClient(from);
|
|
|
|
if (from->fd >= 0 && from->header_buffer == 0) {
|
|
|
|
ev.events = EPOLLIN | EPOLLET;
|
|
|
|
ev.data.ptr = out;
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, out->fd, &ev);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ev.events = EPOLLIN | EPOLLET;
|
|
|
|
ev.data.ptr = out;
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, out->fd, &ev);
|
|
|
|
free(from->header_buffer);
|
|
|
|
from->header_buffer = NULL;
|
|
|
|
from->header_buffer_len = 0;
|
|
|
|
}
|
|
|
|
} else if (write_len > 0) {
|
|
|
|
from->sent_len += write_len;
|
|
|
|
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
|
|
|
ev.data.ptr = out;
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, out->fd, &ev);
|
|
|
|
} else if (errno != EAGAIN) {
|
|
|
|
close_connection(out);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|