如何改动代码,才能让服务器发送的数据完整,能让浏览器图片完全显示,以下分别是html文件和C代码。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>About</title>
<link rel="stylesheet" type="text/css" href="css/style_mobile.css">
<script language="javascript" type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script language="javascript" type="text/javascript" src="js/action.js"></script>
</head>
<body>
<div id="container">
<div id="header">
<div id="logo">David Lanham</div>
<ul>
<li><a href="Index.html">Blog</a></li>
<li><a href="Work.html">Work</a></li>
<li><a class="active" href="About.html">About</a></li>
<li><a href="Contact.html">Contact</a></li>
</ul>
</div>
<div id="about_content">
<p class="content_text">About</p>
<div id="about_slider">
<ul>
<li><img src="images/About_baby.png" /></li>
<li><img src="img/6.jpg" /></li>
<li><img src="img/5.jpg" /></li>
<li><img src="img/4.jpg" /></li>
<li><img src="img/3.jpg" /></li>
<li><img src="img/2.jpg" /></li>
<li><img src="img/1.jpg" /></li>
<li><img src="images/About_baby.png" /></li>
</ul>
</div>
<div id="about_text">
<p class="about_font_big">My name is David Lanham and I creat beautiful</p>
<p class="about_font_big">illustrations that capture imaginations of all</p>
<p class="about_font_big">ages. I currently work at <font color="#f04922">Illustration Industries</font></p>
<p class="about_font_big">and I am based in <font color="#f04922">Washington, DC.</font></p>
<div id="about_text_small">
<p class="about_font_small">I began my career when I was younger, and started drawing all</p>
<p class="about_font_small">kinds of glorious and wonderful creatures. I rearely ever drew</p>
<p class="about_font_small">humans, and even tot his day I prefer drawing characters with</p>
<p class="about_font_small">interesting features that would only be found in childrens books.</p>
<p class="about_font_small">I then created my own illustration company and began creating</p>
<p class="about_font_small">new illustrations for magazines and websites, and even did</p>
<p class="about_font_small">icons for creative companies.</p>
</div>
<ul>
<li><a href="#"><img src="images/About_bird.png"></a></li>
<li><a href="#"><img src="images/About_ball.png"></a></li>
<li><a href="#"><img src="images/About_be.png"></a></li>
<li><a href="#"><img src="images/About_@.png"></a></li>
<li><a href="#"><img src="images/About_message.png"></a></li>
</ul>
</div>
</div>
<div id="footer">
<div id="fttext">
<p>All illustrations on this site are from the very talented</p>
<p> illustrator and designer David Lanham. Make sure to</p>
<p>check out his work at <a href="#">DavidLanham.com.</a></p>
</div>
<div id="ftimage">
<a href="#"><img src="images/footer_baby.png"></a>
</div>
<div id="ft_text">
<p class="ftname">David Lanham</p>
<p class="ftabout">I create beatufiul illustrations and designs.<a href="#">About me.</a></p>
</div>
<ul>
<li><a href="#"><img src="images/footer_bird.png"></a></li>
<li><a href="#"><img src="images/footer_ball.png"></a></li>
<li><a href="#"><img src="images/footer_be.png"></a></li>
<li><a href="#"><img src="images/footer_@.png"></a></li>
<li><a href="#"><img src="images/footer_message.png"></a></li>
</ul>
</div>
</div>
</body>
</html>
#include "http_parser.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../common/debug.h"
int parse_http_request(const char *data, size_t length, HttpRequest *request) {
memset(request, 0, sizeof(HttpRequest));
// 解析请求行
const char *end = data + length;
const char *start = data;
const char *line_end = strstr(start, "\r\n");
if (!line_end || line_end >= end) {
LOG_ERROR("Invalid request line");
return -1;
}
// 解析方法
if (strncmp(start, "GET ", 4) == 0) {
request->method = GET;
start += 4;
} else if (strncmp(start, "POST ", 5) == 0) {
request->method = POST;
start += 5;
} else {
request->method = UNSUPPORTED;
LOG_WARN("Unsupported HTTP method");
return -1;
}
// 解析路径
const char *path_end = strchr(start, ' ');
if (!path_end || path_end >= line_end) {
LOG_ERROR("Invalid request path");
return -1;
}
size_t path_len = path_end - start;
request->path = malloc(path_len + 1);
if (!request->path) {
LOG_ERROR("Memory allocation failed");
return -1;
}
memcpy(request->path, start, path_len);
request->path[path_len] = '\0';
// 解析查询字符串
char *query_start = strchr(request->path, '?');
if (query_start) {
*query_start = '\0';
request->query_string = query_start + 1;
}
// 解析HTTP版本
start = path_end + 1;
if (strncmp(start, "HTTP/1.1", 8) == 0) {
request->http_version_major = 1;
request->http_version_minor = 1;
} else if (strncmp(start, "HTTP/1.0", 8) == 0) {
request->http_version_major = 1;
request->http_version_minor = 0;
} else {
LOG_WARN("Unsupported HTTP version: %.*s", (int)(line_end - start), start);
return -1;
}
// 解析头部
start = line_end + 2; // 跳过\r\n
while (start < end) {
line_end = strstr(start, "\r\n");
if (!line_end || line_end >= end) break;
// 空行表示头部结束
if (line_end == start) {
start = line_end + 2;
break;
}
// 解析单个头部
const char *colon = strchr(start, ':');
if (!colon || colon >= line_end) {
LOG_WARN("Invalid header: %.*s", (int)(line_end - start), start);
start = line_end + 2;
continue;
}
// 分配头部
if (request->header_count >= MAX_HEADERS) {
LOG_WARN("Too many headers, ignoring the rest");
break;
}
HttpHeader *header = &request->headers[request->header_count++];
size_t name_len = colon - start;
header->name = malloc(name_len + 1);
if (!header->name) {
LOG_ERROR("Memory allocation failed");
return -1;
}
memcpy(header->name, start, name_len);
header->name[name_len] = '\0';
// 跳过冒号和空格
const char *value_start = colon + 1;
while (*value_start == ' ' && value_start < line_end) {
value_start++;
}
size_t value_len = line_end - value_start;
header->value = malloc(value_len + 1);
if (!header->value) {
LOG_ERROR("Memory allocation failed");
free(header->name);
return -1;
}
memcpy(header->value, value_start, value_len);
header->value[value_len] = '\0';
// 特殊处理Content-Length
if (strcasecmp(header->name, "Content-Length") == 0) {
request->body_length = strtoul(header->value, NULL, 10);
}
start = line_end + 2;
}
// 解析正文 (POST请求)
if (request->method == POST && request->body_length > 0 &&
(end - start) >= request->body_length) {
request->body = malloc(request->body_length + 1);
if (!request->body) {
LOG_ERROR("Memory allocation failed");
return -1;
}
memcpy(request->body, start, request->body_length);
request->body[request->body_length] = '\0';
}
return 0;
}
void free_http_request(HttpRequest *request) {
if (request->path) free(request->path);
for (size_t i = 0; i < request->header_count; i++) {
free(request->headers[i].name);
free(request->headers[i].value);
}
if (request->body) free(request->body);
memset(request, 0, sizeof(HttpRequest));
}
void build_http_response(const HttpResponse *response, char *buffer, size_t *length) {
char *ptr = buffer;
size_t remaining = *length;
// 状态行
int written = snprintf(ptr, remaining, "HTTP/1.1 %d %s\r\n",
response->status_code, response->status_text);
ptr += written;
remaining -= written;
// 头部
for (size_t i = 0; i < response->header_count; i++) {
written = snprintf(ptr, remaining, "%s: %s\r\n",
response->headers[i].name, response->headers[i].value);
ptr += written;
remaining -= written;
}
// 内容长度
written = snprintf(ptr, remaining, "Content-Length: %zu\r\n", response->body_length);
ptr += written;
remaining -= written;
// 结束头部
written = snprintf(ptr, remaining, "Connection: close\r\n\r\n");
ptr += written;
remaining -= written;
// 正文
if (response->body_length > 0 && remaining >= response->body_length) {
memcpy(ptr, response->body, response->body_length);
ptr += response->body_length;
remaining -= response->body_length;
}
*length = ptr - buffer;
}
void build_200_response(HttpResponse *response, const char *content, const char *content_type) {
response->status_code = 200;
response->status_text = "OK";
response->body = content;
// 设置Content-Type
response->header_count = 1;
response->headers[0].name = "Content-Type";
response->headers[0].value = (char*)content_type;
}
void build_404_response(HttpResponse *response) {
const char *content =
"<html>"
"<head><title>404 Not Found</title></head>"
"<body><h1>404 Not Found test</h1></body>"
"</html>";
response->status_code = 404;
response->status_text = "Not Found";
response->body = content;
response->body_length = strlen(content);
response->header_count = 1;
response->headers[0].name = "Content-Type";
response->headers[0].value = "text/html";
}
void build_400_response(HttpResponse *response) {
const char *content =
"<html>"
"<head><title>400 Failed to parse</title></head>"
"<body><h1>400 Failed to parse</h1></body>"
"</html>";
response->status_code = 400;
response->status_text = "Failed to parse";
response->body = content;
response->body_length = strlen(content);
response->header_count = 1;
response->headers[0].name = "Content-Type";
response->headers[0].value = "text/html";
}
void build_500_response(HttpResponse *response) {
const char *content =
"<html>"
"<head><title>500 Internal Server Error</title></head>"
"<body><h1>500 Internal Server Error</h1></body>"
"</html>";
response->status_code = 500;
response->status_text = "Internal Server Error";
response->body = content;
response->body_length = strlen(content);
response->header_count = 1;
response->headers[0].name = "Content-Type";
response->headers[0].value = "text/html";
}
// 添加403和413错误处理
void build_403_response(HttpResponse *response) {
const char *content =
"<html><head><title>403 Forbidden</title></head>"
"<body><h1>403 Forbidden</h1></body></html>";
response->status_code = 403;
response->status_text = "Forbidden";
response->body = content;
response->body_length = strlen(content);
response->owns_body = 0;
response->header_count = 1;
response->headers[0].name = "Content-Type";
response->headers[0].value = "text/html";
}
void build_413_response(HttpResponse *response) {
const char *content =
"<html><head><title>413 Payload Too Large</title></head>"
"<body><h1>File too large</h1></body></html>";
response->status_code = 413;
response->status_text = "Payload Too Large";
response->body = content;
response->body_length = strlen(content);
response->owns_body = 0;
response->header_count = 1;
response->headers[0].name = "Content-Type";
response->headers[0].value = "text/html";
}
// 添加MIME类型映射函数
const char* get_content_type(const char* path) {
const char *ext = strrchr(path, '.');
if (!ext) return "application/octet-stream";
if (strcmp(ext, ".html") == 0 || strcmp(ext, ".htm") == 0) return "text/html";
if (strcmp(ext, ".css") == 0) return "text/css";
if (strcmp(ext, ".js") == 0) return "application/javascript";
if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) return "image/jpeg";
if (strcmp(ext, ".png") == 0) return "image/png";
if (strcmp(ext, ".gif") == 0) return "image/gif";
if (strcmp(ext, ".pdf") == 0) return "application/pdf";
if (strcmp(ext, ".txt") == 0) return "text/plain";
return "application/octet-stream";
}
最新发布