-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebserver.c
More file actions
149 lines (124 loc) · 4.13 KB
/
Copy pathwebserver.c
File metadata and controls
149 lines (124 loc) · 4.13 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <time.h>
#define PORT 8080
#define BUFFER_SIZE 4096
#define MAX_THREADS 100
int user_id_counter = 0;
// Handler functions that bpftrace can hook into
void handle_users_endpoint(int user_id) {
printf("[handle_users_endpoint] user_id=%d\n", user_id);
sleep(0); // Simulate work
}
void handle_data_endpoint(int user_id, int data_size) {
printf("[handle_data_endpoint] user_id=%d, data_size=%d\n", user_id, data_size);
usleep(10000); // Simulate work
}
void handle_health_endpoint(void) {
printf("[handle_health_endpoint] called\n");
}
// Parse query param from URL (e.g., "user_id=123" from "/api/users?user_id=123")
int extract_user_id(const char *request) {
const char *query = strchr(request, '?');
if (!query) return 1; // Default user ID
const char *user_param = strstr(query, "user_id=");
if (!user_param) return 1;
int user_id = atoi(user_param + 8); // Skip "user_id="
return user_id > 0 ? user_id : 1;
}
void send_response(int client_socket, const char *status, const char *body) {
char response[BUFFER_SIZE];
snprintf(response, sizeof(response),
"HTTP/1.1 %s\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %lu\r\n"
"Connection: close\r\n"
"\r\n"
"%s",
status, strlen(body), body);
send(client_socket, response, strlen(response), 0);
}
void* handle_client(void *arg) {
int client_socket = *(int *)arg;
free(arg);
char request[BUFFER_SIZE] = {0};
if (recv(client_socket, request, sizeof(request) - 1, 0) < 0) {
perror("recv");
close(client_socket);
return NULL;
}
// Parse request line
char method[16], path[256];
sscanf(request, "%s %s", method, path);
// Route handling
if (strncmp(path, "/api/users", 10) == 0) {
int user_id = extract_user_id(request);
handle_users_endpoint(user_id);
send_response(client_socket, "200 OK", "User data retrieved");
}
else if (strncmp(path, "/api/data", 9) == 0) {
int user_id = extract_user_id(request);
int data_size = rand() % 1000 + 100;
handle_data_endpoint(user_id, data_size);
send_response(client_socket, "200 OK", "Data retrieved");
}
else if (strncmp(path, "/health", 7) == 0) {
handle_health_endpoint();
send_response(client_socket, "200 OK", "OK");
}
else {
send_response(client_socket, "404 Not Found", "Endpoint not found");
}
close(client_socket);
return NULL;
}
int main() {
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("socket");
exit(1);
}
int opt = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
perror("setsockopt");
exit(1);
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind");
exit(1);
}
if (listen(server_socket, 5) < 0) {
perror("listen");
exit(1);
}
printf("Server listening on port %d\n", PORT);
while (1) {
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int *client_socket = malloc(sizeof(int));
*client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
if (*client_socket < 0) {
perror("accept");
free(client_socket);
continue;
}
pthread_t thread;
if (pthread_create(&thread, NULL, handle_client, client_socket) != 0) {
perror("pthread_create");
free(client_socket);
} else {
pthread_detach(thread);
}
}
close(server_socket);
return 0;
}