-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
191 lines (152 loc) · 5.61 KB
/
main.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
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dirent.h>
#define MAX_REQUEST_SIZE 1024
#include "mime_type_handler.h"
#include "request_logger.h"
#include "error_handling.h"
#include "authentication.h"
char SERVER_DIR[200];
void send_authentication_required_response(int client_socket, const char* file_path, const char* request) {
// Open the file
printf("Requested filepath: %s\n", file_path);
FILE* file = fopen(file_path, "r");
if (file == NULL) {
perror("Failed to open file");
send_error_response(client_socket, 404, "Not Found", file_path);
return;
}
printf("Serving file: %s\n", file_path); // Print the file path
// Check if the file is a PHP file
if (check_php_file(file_path)) {
char response_header[200];
snprintf(response_header, sizeof(response_header), "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
handle_php_file(file, &client_socket, response_header);
} else {
char* content_type = get_content_type(file_path);
// Send the HTTP response headers
char response_header[200];
sprintf(response_header, "HTTP/1.1 200 OK\r\nContent-Type: %s\r\n\r\n", content_type);
//logging
log_request_response(request, response_header);
if (send(client_socket, response_header, strlen(response_header), 0) < 0) {
perror("Failed to send response header");
fclose(file);
return;
}
// Read the file contents and send them to the client
char file_buffer[1024];
size_t bytes_read;
while ((bytes_read = fread(file_buffer, 1, sizeof(file_buffer), file)) > 0) {
if (send(client_socket, file_buffer, bytes_read, 0) < 0) {
perror("Failed to send file");
fclose(file);
return;
}
}
// Close the file
fclose(file);
}
// Close the client socket after sending the response
close(client_socket);
}
void handle_request(int client_socket, const char* request) {
// printf("Received request:\n%s\n", request);
// Parse the requested file path from the request header
char* request_copy = strdup(request); // Make a copy of the request string
char *path_start = strstr(request_copy, "GET /");
if (path_start == NULL) {
perror("Invalid request");
close(client_socket);
free(request_copy); // Free the allocated memory
return;
}
char *path_end = strstr(path_start, " HTTP/");
if (path_end == NULL) {
perror("Invalid request");
close(client_socket);
free(request_copy); // Free the allocated memory
return;
}
*path_end = '\0'; // Null-terminate the path
char *path = path_start + 5; // Skip "GET /"
char file_path[200];
strcpy(file_path, SERVER_DIR);
strcat(file_path, path);
int authentication_result = perform_authentication(client_socket, file_path, request);
free(request_copy); // Free the allocated memory
if (authentication_result == 0) {
// Authentication failed, return without sending the response
close(client_socket);
printf("Auth Failed\n");
return;
}
printf("perform_authentication completed\n");
send_authentication_required_response(client_socket, file_path, request);
// Close the client socket after sending the response
close(client_socket);
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s SERVER_DIR PORT\n", argv[0]);
printf("Please specify server directory and port number");
return 1;
}
strcpy(SERVER_DIR, argv[1]);
int port = atoi(argv[2]);
int server_socket, client_socket;
struct sockaddr_in server_address, client_address;
socklen_t client_address_len = sizeof(client_address);
// Create a socket
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("Failed to create socket");
return 1;
}
// Set up the server address
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port);
server_address.sin_addr.s_addr = INADDR_ANY;
// Bind the socket to the specified IP and port
if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
perror("Failed to bind socket");
return 1;
}
// Listen for incoming connections
if (listen(server_socket, 10) < 0) {
perror("Failed to listen for connections");
return 1;
}
printf("Server started on port %d\n", port);
// Accept and handle incoming connections
while (1) {
printf("Waiting for request...\n");
client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_address_len);
if (client_socket < 0) {
perror("Failed to accept connection");
continue;
}
char request[MAX_REQUEST_SIZE];
memset(request, 0, sizeof(request));
// Receive the request from the client
int recv_result = recv(client_socket, request, sizeof(request), 0);
if (recv_result == 0) {
printf("Client closed the connection.\n");
close(client_socket);
continue;
} else if (recv_result < 0) {
perror("Failed to receive request");
close(client_socket);
continue;
}
// Handle the request
handle_request(client_socket, request);
}
// Close the server socket
close(server_socket);
return 0;
}