Fix HTTP POST body parsing for web login

- Added --debug-web command line option for comprehensive web request debugging
- Fixed HTTP request parsing to properly separate headers from POST body
- Implemented Content-Length based body extraction for reliable form data parsing
- Added extensive debug output for troubleshooting web requests
- Updated configuration system to support debug_web flag

The login form now correctly parses username/password from POST requests.
parent 90656adf
......@@ -169,6 +169,19 @@ static int parse_http_request(int client_fd, http_request_t *req) {
buffer[bytes_read] = '\0';
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Raw buffer (%zd bytes): '", bytes_read);
for (ssize_t i = 0; i < bytes_read && i < 200; i++) {
if (buffer[i] == '\r') printf("\\r");
else if (buffer[i] == '\n') printf("\\n");
else if (buffer[i] >= 32 && buffer[i] <= 126) printf("%c", buffer[i]);
else printf("\\x%02x", (unsigned char)buffer[i]);
}
if (bytes_read > 200) printf("...'");
else printf("'");
printf("\n");
}
// Parse request line
char *line = strtok(buffer, "\r\n");
if (!line) return -1;
......@@ -185,18 +198,76 @@ static int parse_http_request(int client_fd, http_request_t *req) {
}
// Parse headers and body
char *body_start = strstr(buffer, "\r\n\r\n");
if (body_start) {
*body_start = '\0';
body_start += 4;
strcpy(req->body, body_start);
req->content_length = strlen(req->body);
// First, copy all headers
char *header_start = line + strlen(line) + 2;
strcpy(req->headers, header_start);
// Look for Content-Length header
int content_length = 0;
char *cl_header = strstr(req->headers, "Content-Length:");
if (cl_header) {
cl_header += 15; // Skip "Content-Length:"
while (*cl_header == ' ' || *cl_header == '\t') cl_header++;
content_length = atoi(cl_header);
}
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Content-Length from header: %d\n", content_length);
}
// Find body start - look for \r\n\r\n or calculate from Content-Length
char *body_separator = strstr(buffer, "\r\n\r\n");
char *body_start = NULL;
size_t body_length = 0;
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Looking for body separator...\n");
}
if (body_separator) {
body_start = body_separator + 4;
body_length = bytes_read - (body_start - buffer);
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Found \\r\\n\\r\\n separator at offset %ld, body_start at %ld, body_length: %zu\n",
body_separator - buffer, body_start - buffer, body_length);
}
} else if (content_length > 0) {
// Calculate body position: total bytes - content_length
body_start = buffer + bytes_read - content_length;
body_length = content_length;
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Calculated body start from Content-Length, body_start at %ld, body_length: %zu\n",
body_start - buffer, body_length);
}
}
// Copy body if found
if (body_start && body_length > 0) {
if (body_length < sizeof(req->body)) {
memcpy(req->body, body_start, body_length);
req->body[body_length] = '\0';
req->content_length = body_length;
} else {
memcpy(req->body, body_start, sizeof(req->body) - 1);
req->body[sizeof(req->body) - 1] = '\0';
req->content_length = sizeof(req->body) - 1;
}
} else {
req->body[0] = '\0';
req->content_length = 0;
}
strcpy(req->headers, line + strlen(line) + 2);
// Clean up headers - remove body if it's appended
char *headers_end = strstr(req->headers, "\r\n\r\n");
if (headers_end) {
*headers_end = '\0';
} else {
// Try to find where body starts in headers and truncate
char *body_in_headers = strstr(req->headers, "\r\nusername=");
if (body_in_headers) {
*body_in_headers = '\0';
}
}
return 0;
}
......@@ -370,6 +441,7 @@ static void handle_request(int client_fd, const http_request_t *req) {
if (req->query[0]) {
printf("[WEB-DEBUG] Query: %s\n", req->query);
}
printf("[WEB-DEBUG] Headers: %s\n", req->headers);
if (req->content_length > 0) {
printf("[WEB-DEBUG] Content-Length: %d\n", req->content_length);
}
......@@ -721,12 +793,17 @@ static void handle_request(int client_fd, const http_request_t *req) {
}
} else if (strcmp(req->method, "POST") == 0) {
if (strcmp(req->path, "/login") == 0) {
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Login POST body (%d bytes): '%s'\n",
req->content_length, req->body);
}
char form_username[50] = "";
char form_password[50] = "";
parse_form_data(req->body, form_username, form_password, sizeof(form_username));
if (global_config && global_config->debug_web) {
printf("[WEB-DEBUG] Login attempt: username='%s', password='%s'\n",
printf("[WEB-DEBUG] Parsed login data: username='%s', password='%s'\n",
form_username, form_password[0] ? "***" : "(empty)");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment