我想让http 1.1 200响应与C.



我想构建一个web服务器,以便客户端可以使用http 1.1在本地Linux环境中查看index.html文档。

我不知道如何发送正确的html信息给客户端,因为我缺乏编程知识。

如何在c语言环境中配置web服务器来发送这样的响应?

HTTP/1.1 400 Bad Request
Date: Tue, 10 Jan 2023 11:27:27 GMT
Server: Apache/2.4.54 (FreeBSD)
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

HTTP/1.1 200 OK     
Date: Mon, 28 Nov 2022 06:11:52 GMT
Server: Apache/2.4.54 (FreeBSD)
Accept-Ranges: bytes
Connection: close
Content-Type: text/html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

代码
void send_data(int s, char * path) { //path='/index.html' 
char buf[1024];
char filename[256];
char protocol[] = "HTTP/1.0 200 OKrn ";   
char server[] = "Server: Linux Web Serverrn ";  
char cnt_len[] = "Content-length:2048rnrn";
FILE * send_file;
sprintf(filename, "htdocs%s", path);
printf("[%s]n", filename);
send_file = fopen(filename, "rb");
printf("%d fileopenn", send_file);
if (send_file == NULL) {
send_error(s);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
send(s, protocol, strlen(protocol), 0);
send(s, server, strlen(server), 0);
send(s, cnt_len, strlen(cnt_len), 0);
int len = 1;
while (len != 0) {
len = fread(buf, 1, 1024, send_file);
send(s, buf, len, 0);
}
}

除非文件实际大小为2048字节,否则将Content-length头硬编码为2048值是错误的。您需要发送文件的实际大小。

还需要更好的错误处理。

试试这样写:

int send_raw(int s, const char *data, size_t size) {
while (size > 0) {
int sent = send(s, data, size, 0);
if (sent < 0) {
return -1;
}
data += sent;
size -= sent;
}
return 0;
}
int send_str(int s, const char *data) {
return send_raw(s, data, strlen(data));
}
void send_data(int s, const char *path) { //path='/index.html' 
char buf[1024];
char filename[256];
char protocol[] = "HTTP/1.0 200 OKrn";
char server[] = "Server: Linux Web Serverrn";
char cnt_len_fmt[] = "Content-Length: %ldrnrn";
char cnt_len[48];
FILE *send_file;
snprintf(filename, 256, "htdocs%s", path);
printf("[%s]n", filename);
send_file = fopen(filename, "rb");
printf("%p fileopenn", send_file);
if (send_file == NULL) {
send_error(s);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
if (fseek(send_file, 0, SEEK_END) != 0) {
send_error(s);
fclose(send_file);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
long file_size = ftell(send_file);
if (file_size == -1L) {
send_error(s);
fclose(send_file);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
rewind(send_file);    

sprintf(cnt_len, cnt_len_fmt, file_size);
if (send_str(s, protocol) < 0) {
fclose(send_file);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
if (send_str(s, server) < 0) {
fclose(send_file);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
if (send_str(s, cnt_len) < 0) {
fclose(send_file);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
size_t len;
for(long offset = 0; offset < file_size; offset += len) {
len = fread(buf, 1, min(file_size-offset, 1024), send_file);
if (len < 1) {
printf("%s %dn", __FUNCTION__, __LINE__);
break;
}
if (send_raw(s, buf, len) < 0) {
printf("%s %dn", __FUNCTION__, __LINE__);
break;
}
}
fclose(send_file);
}

否则,您可以省略Content-length报头,而发送Connection: close报头。但是,当您完成发送文件时,您必须实际close()套接字,例如:

...
void send_data(int s, const char * path) { //path='/index.html' 
char buf[1024];
char filename[256];
char protocol[] = "HTTP/1.0 200 OKrn";
char server[] = "Server: Linux Web Serverrn";
char conn[] = "Connection: closernrn";
FILE *send_file;
snprintf(filename, 256, "htdocs%s", path);
printf("[%s]n", filename);
send_file = fopen(filename, "rb");
printf("%d fileopenn", send_file);
if (send_file == NULL) {
send_error(s);
close(s);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
if (send_str(s, protocol) < 0) {
close(s);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
if (send_str(s, server) < 0) {
close(s);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
if (send_str(s, conn) < 0) {
close(s);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
size_t len;
while ((len = fread(buf, 1, 1024, send_file)) > 0) {
if (send_raw(s, buf, len) < 0) {
close(s);
fclose(send_file);
printf("%s %dn", __FUNCTION__, __LINE__);
return;
}
}
while (true);
if (ferror(send_file) && !feof(send_file)) {
printf("%s %dn", __FUNCTION__, __LINE__);
}
fclose(send_file);
close(s);
}

相关内容

  • 没有找到相关文章

最新更新