need to read

以下是common.c代码,可以结合server_process理解,写好注释给我#include "common.h" void send_response(int client_fd, int status, const char* title, const char* text) { char response[BUFFER_SIZE]; int len = snprintf(response, BUFFER_SIZE, "HTTP/1.1 %d %s\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n" "<html><head><title>%d %s</title></head>" "<body><h1>%d %s</h1><p>%s</p></body></html>", status, title, status, title, status, title, text); send(client_fd, response, len, 0); DEBUG("Sent %d response\n", status); } void send_file(int client_fd, const char* path) { int fd = open(path, O_RDONLY); if (fd < 0) { perror("open"); send_response(client_fd, 404, "Not Found", "File not found"); return; } struct stat file_stat; if (fstat(fd, &file_stat) < 0) { perror("fstat"); close(fd); send_response(client_fd, 500, "Internal Error", "Could not get file stats"); return; } // 确定Content-Type const char *content_type = "text/plain"; if (strstr(path, ".html")) content_type = "text/html"; else if (strstr(path, ".css")) content_type = "text/css"; else if (strstr(path, ".js")) content_type = "application/javascript"; else if (strstr(path, ".png")) content_type = "image/png"; else if (strstr(path, ".jpg")) content_type = "image/jpeg"; else if (strstr(path, ".json")) content_type = "application/json"; char header[BUFFER_SIZE]; int header_len = snprintf(header, BUFFER_SIZE, "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %ld\r\n" "Connection: close\r\n\r\n", content_type, file_stat.st_size); send(client_fd, header, header_len, 0); sendfile(client_fd, fd, NULL, file_stat.st_size); DEBUG("Sent file: %s (%ld bytes)\n", path, file_stat.st_size); close(fd); } // URL解码函数 char* url_decode(const char* str) { if (!str) return NULL; char* decoded = malloc(strlen(str) + 1); if (!decoded) return NULL; char* d = decoded; for (const char* s = str; *s; s++) { if (*s == '+') { *d++ = ' '; } else if (*s == '%' && isxdigit(s[1]) && isxdigit(s[2])) { char hex[3] = {s[1], s[2], '\0'}; *d++ = (char)strtol(hex, NULL, 16); s += 2; } else { *d++ = *s; } } *d = '\0'; return decoded; } // 处理POST请求 void handle_post_request(int client_fd, const char* path, const char* post_data, size_t data_len) { DEBUG("Handling POST request to %s\n", path); // 简单的表单处理 if (strcmp(path, "/submit") == 0) { // 解析表单数据 char* decoded = url_decode(post_data); if (!decoded) { send_response(client_fd, 500, "Internal Error", "Failed to decode data"); return; } DEBUG("Decoded POST data: %s\n", decoded); // 提取表单字段 char name[256] = {0}; char email[256] = {0}; char message[1024] = {0}; char* token = strtok(decoded, "&"); while (token) { char* eq = strchr(token, '='); if (eq) { *eq = '\0'; char* key = token; char* value = eq + 1; if (strcmp(key, "name") == 0) { strncpy(name, value, sizeof(name)-1); } else if (strcmp(key, "email") == 0) { strncpy(email, value, sizeof(email)-1); } else if (strcmp(key, "message") == 0) { strncpy(message, value, sizeof(message)-1); } } token = strtok(NULL, "&"); } // 构建响应页面 char response[BUFFER_SIZE]; int len = snprintf(response, BUFFER_SIZE, "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n" "<html><head><title>Form Submitted</title></head>" "<body><h1>Thank You!</h1>" "<p>Name: %s</p>" "<p>Email: %s</p>" "<p>Message: %s</p>" "<p><a href=\"/\">Back to home</a></p></body></html>", name, email, message); send(client_fd, response, len, 0); free(decoded); } // 简单的API处理 else if (strcmp(path, "/api/data") == 0) { char response[BUFFER_SIZE]; int len = snprintf(response, BUFFER_SIZE, "HTTP/1.1 200 OK\r\n" "Content-Type: application/json\r\n" "Connection: close\r\n" "\r\n" "{\"status\":\"success\",\"message\":\"Data received\",\"length\":%zu}", data_len); send(client_fd, response, len, 0); } else { send_response(client_fd, 404, "Not Found", "POST endpoint not found"); } } void handle_request(int client_fd) { char buffer[BUFFER_SIZE]; ssize_t bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0); if (bytes_read <= 0) { DEBUG("Connection closed or error\n"); close(client_fd); return; } buffer[bytes_read] = '\0'; DEBUG("Request:\n%s\n", buffer); // 检测HTTP方法 HttpMethod method = HTTP_UNKNOWN; char *method_start = buffer; char *method_end = strchr(method_start, ' '); if (method_end) { *method_end = '\0'; if (strcmp(method_start, "GET") == 0) method = HTTP_GET; else if (strcmp(method_start, "POST") == 0) method = HTTP_POST; else if (strcmp(method_start, "PUT") == 0) method = HTTP_PUT; else if (strcmp(method_start, "DELETE") == 0) method = HTTP_DELETE; *method_end = ' '; // 恢复原始数据 } // 解析请求路径 char *path_start = buffer; if (method != HTTP_UNKNOWN) { path_start = strchr(buffer, ' ') + 1; } char *path_end = strchr(path_start, ' '); if (!path_end) { send_response(client_fd, 400, "Bad Request", "Invalid request"); close(client_fd); return; } *path_end = '\0'; // 处理POST请求 if (method == HTTP_POST) { // 查找Content-Length char *content_length_start = strstr(buffer, "Content-Length: "); size_t content_length = 0; if (content_length_start) { content_length_start += 15; // 跳过"Content-Length: " char *content_length_end = strchr(content_length_start, '\r'); if (content_length_end) { *content_length_end = '\0'; content_length = atoi(content_length_start); *content_length_end = '\r'; // 恢复原始数据 } } // 限制POST数据大小 if (content_length > MAX_POST_SIZE) { send_response(client_fd, 413, "Payload Too Large", "POST data too large"); close(client_fd); return; } // 查找POST数据开始位置 char *post_data = strstr(buffer, "\r\n\r\n"); if (post_data) { post_data += 4; // 跳过空行 // 确保不超出缓冲区 size_t data_size = bytes_read - (post_data - buffer); if (data_size < content_length) { // 需要读取更多数据(简化处理) DEBUG("Incomplete POST data, need to read more\n"); send_response(client_fd, 400, "Bad Request", "Incomplete POST data"); close(client_fd); return; } // 处理POST请求 handle_post_request(client_fd, path_start, post_data, content_length); close(client_fd); return; } } // 构建完整路径(处理GET请求) char full_path[256]; if (strcmp(path_start, "/") == 0) { snprintf(full_path, sizeof(full_path), "%s/Index.html", ROOT_DIR); } else { snprintf(full_path, sizeof(full_path), "%s%s", ROOT_DIR, path_start); } // 检查文件是否存在 struct stat st; if (stat(full_path, &st) == 0 && S_ISREG(st.st_mode)) { send_file(client_fd, full_path); } else { send_response(client_fd, 404, "Not Found", "File not found"); } close(client_fd); }
最新发布
08-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值