我需要编写一个简单的HTTP服务器来发送有关我的应用程序剩余部分的诊断信息。所以我首先尝试了这个简单的例子:
/* Simple HTTP server which discard the client request. Please record this file in ISO-8859-15 to get proper results */
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <zlib.h>
#define CHUNK 8388608
#include <unistd.h>
/*****************************************************************************
* Crée et envoi la réponse au client
*****************************************************************************/
void * reponse(int newsockfd)
{
char * buffer=calloc(sizeof(char),5890);
sprintf(buffer,"<!DOCTYPE html>\n\
<html>\n\
<head>\n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO8859-15\">\n\
<title color=\"white\">ACCÈS INTERDIT!</title>\n\
<script>\n\
function launchFullscreen() {\n\
if(document.body.requestFullscreen) {\n\
document.body.requestFullscreen();\n\
} else if(document.body.mozRequestFullScreen) {\n\
document.body.mozRequestFullScreen();\n\
} else if(document.body.webkitRequestFullscreen) {\n\
document.body.webkitRequestFullscreen();\n\
} else if(document.body.msRequestFullscreen) {\n\
document.body.msRequestFullscreen();\n\
}\n\
}\n\
\n\
</script>\n\
</head>\n\
\n\
<body align=\"center\" valign=\"center\" >\n\
<button onclick=\"launchFullscreen();\">ACCÈS INTERDIT!</button>\n\
</body>\n\
</html>\r\n\0");
size_t inputLen = strlen(buffer);
uLong maxCompressLen = compressBound(inputLen);
char * destbuffer=calloc(sizeof(char),maxCompressLen);
compress2(destbuffer,&maxCompressLen,buffer,inputLen,Z_BEST_COMPRESSION);
memset(buffer,0,(unsigned int)maxCompressLen+1);
sprintf( buffer, "HTTP/1.1 200 OK\n\
Vary: Accept-Encoding\n\
Content-Length: %ld\n\
Connection: close\n\
Content-encoding: deflate\n\
Content-Type: text/html; charset=iso-8859-15\n\
Content-language: fr\n\
X-Powered-By: GCC 4.8.1 avec -flto -mtune=native et -Ofast!\n\
Server: Serveur avec easter-egg servant à faire la différence entre une page bloqué et une connection internet qui ne marche pas\n\
\r\n",maxCompressLen);
memcpy( buffer+359, destbuffer, maxCompressLen);
write(newsockfd,buffer,359+maxCompressLen);
free(buffer);
free(destbuffer);
close(newsockfd);
}
void main()
{
close(0);close(1);close(2); // close stderr stdin stdout
pthread_t parallel;
struct sockaddr_in6 client_address, server_address;
int newsockfd,clilen=sizeof(client_address),server_handle=socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (server_handle < 0)
perror("Unable to create socket.");
server_address.sin6_family = AF_INET6;
server_address.sin6_addr = in6addr_any;
server_address.sin6_port = 0x5000; // port 80
if ( bind(server_handle, (struct sockaddr *)&server_address, sizeof( server_address )) < 0)
perror("Unable to bind.");
listen(server_handle,0xF);
struct passwd *pass;
struct group *grp;
/* lookup the uid/gid for the given user and group name */
if ((pass = getpwnam("nobody")) == NULL) {
perror("Can't find username!\n");
exit(1);
}
if ((grp = getgrnam("nogroup")) == NULL) {
perror("Can't fine groupname!\n");
exit(1);
}
/* drop root */
if (setgid(grp->gr_gid) == -1) {
perror("Couldn't change groupid");
exit(1);
}
if (setuid(pass->pw_uid) == -1) {
perror("Couldn't change userid");
exit(1);
}
endpwent();
endgrent();
Boucle:;
newsockfd=accept(server_handle, (struct sockaddr *) &client_address, &clilen);
pthread_create(¶llel,NULL,reponse,(void *)newsockfd);
goto Boucle;
}
主要问题是IE和firefox抱怨连接重置并且不显示它。基于Presto的opera和基于blink / webkit的浏览器版本不会遇到这个问题......
所以我在考虑HTTP协议中的错误。
更新:我的代码中似乎还有一个小内存泄漏......