-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredirect_server.c
executable file
·106 lines (81 loc) · 2.9 KB
/
redirect_server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "redirect_server.h"
#include "get_page.h"
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage : %s [redirected URL in string format] [# port] \n",
argv[0]);
exit(1);
}
//make a copy of global static variables.
global_redirect_server_url = argv[1];
global_redirect_server_port = atoi(argv[2]);
//make server socket
int server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket < 0) {
printf("server socket init fail \n");
return 1;
}
struct sockaddr_in serv_addr;
//bind ip + port to server socket
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(global_redirect_server_port);
if (bind(server_socket, (struct sockaddr*) &serv_addr, sizeof(serv_addr))
< 0) {
printf("server socket bind fail \n");
return 2;
}
//make server socket to start listen
if (listen(server_socket, __REDIRECT_SERVER_WAIT_MAX__) < 0) {
printf("server socket listen fail \n");
return 3;
}
socklen_t client_addr_size = sizeof(struct sockaddr_in);
while (1) {
struct sockaddr_in client_addr;
//wait for http request on desired port
printf("waiting for client...\n");
int client_socket = accept(server_socket,
(struct sockaddr*) &client_addr, &client_addr_size);
if (client_socket < 0) {
printf("client socket accept fail \n");
} else {
printf("Connected.\n");
}
//make a pointer referencing to connected client socket.
int *pointer_to_client_socket = malloc(sizeof(int));
*pointer_to_client_socket = client_socket;
pthread_t new_thread;
//start new working thread to deal with new client
pthread_create(&new_thread, NULL, redirection_handler,
pointer_to_client_socket);
}
}
//thread;
void* redirection_handler(void *sock_arg) {
int sock = *((int*) sock_arg);
//redirect to specific url
redirect_socket_to_url(sock, global_redirect_server_url);
//free socket
free(sock_arg);
}
void redirect_socket_to_url(int socket, const char *url) {
//basic HTTP response format, might expand with some more headers like Date.
char *reply =
"HTTP/1.1 200 OK\nServer: C,libcurl redirection server\nContent-Type: text/html\nConnection: close\n\n";
/* use libcurl to get redirecting webpage.
*
* Could use HTTP 302 Location header, but if redirecting URL lives in different domain security problem arises.
* reference: https://stackoverflow.com/questions/17167935/302-redirect-to-a-different-domain-fails-silently
*/
char *redirection_page = get_page(url);
//simple copy and making of buffer
char *data = malloc(strlen(reply) + strlen(redirection_page) + 1);
strcpy(data, reply);
strcpy(data + strlen(reply), redirection_page);
write(socket, data, strlen(data));
printf("redirected to %s \n", url);
free(data);
free(redirection_page);
}