I write a very very simple HTTP server to call a simple CGI program which I wrote,
but I the HTTP server can’t show the result of CGI program on my browser.
The part code of my HTTP server is in following.
while(1)
{
struct sockaddr_in client_addr;
int addrlen = sizeof(client_addr);
/*Accept*/
if((clientfd = accept(sockfd, (struct sockaddr *)&client_addr, (socklen_t*)&addrlen)) < 0)
{
perror("Accpet Error");
close(sockfd);
exit(-1);
}
else
{
/*Fork process*/
if((child = fork()) < 0)
{
perror("Fork Error");
close(sockfd);
exit(-1);
}
else if(child == 0)
{
int fd[2]; //pipe a fd
close(sockfd);
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
buffer1.clear();
buffer1.resize(VECTOR_SIZE);
while(1)
{
if((res = recv(clientfd, buffer1.data(), buffer1.size(), 0)) > 0)
{
string token = "QUERY_STRING=" + buffer1.data();
pipe(fd);
dup2(fd[1], STDOUT_FILENO);
close(fd[0]);
execlp("cgi", "cgi", NULL);
//if the bug fixed, will use `execvpe` here
cout << "fail" << endl;
}
}
}
else
{
//exit(0);
close(clientfd);
}
}
}
And, my CGI program just
string reply = "HTTP/1.1 200 OK\nTEST"; cout << reply;
But the browser can’t show the result and timeout.
You need 2 CRLFs between your HTTP Response and the content. Additionally, most browsers will probably not display the content without at least setting the Content-Type header. For your purposes, you should just set Content-Type: text/plain testing purposes. If you intend to serve other mime types, you will want to account for that in your CGI.
As you’ll probably hear from others, they’ll be curious why you are attempting this … i’ll chalk it up to an academic exercise or just curiousness … but one thing you’ll want to do is put the responsibility for returning the response code and status on the HTTP server itself, not the CGI.