搜索热词
下面是编程之家 jb51.cc 通过网络收集整理的代码片段。
编程之家小编现在分享给大家,也给大家做个参考。
/*
* WebServer.c
*
* Created on: Nov 3,2012
* Author: pavithra
*
* A web server in C language using only the standard libraries.
* The port number is passed as an argument.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define EOL "\r\n"
#define EOL_SIZE 2
typedef struct {
char *ext;
char *mediatype;
} extn;
//Possible media types
extn extensions[] ={
{"gif","image/gif" },{"txt","text/plain" },{"jpg","image/jpg" },{"jpeg","image/jpeg"},{"png","image/png" },{"ico","image/ico" },{"zip","image/zip" },{"gz","image/gz" },{"tar","image/tar" },{"htm","text/html" },{"html",{"PHP",{"pdf","application/pdf"},"application/octet-stream"},{"rar",{0,0} };
/*
A helper function
*/
void error(const char *msg) {
perror(msg);
exit(1);
}
/*
A helper function
*/
int get_file_size(int fd) {
struct stat stat_struct;
if (fstat(fd,&stat_struct) == -1)
return (1);
return (int) stat_struct.st_size;
}
/*
A helper function
*/
void send_new(int fd,char *msg) {
int len = strlen(msg);
if (send(fd,msg,len,0) == -1) {
printf("Error in send\n");
}
}
/*
This function recieves the buffer
until an "End of line(EOL)" byte is recieved
*/
int recv_new(int fd,char *buffer) {
char *p = buffer; // Use of a pointer to the buffer rather than dealing with the buffer directly
int eol_matched = 0; // Use to check whether the recieved byte is matched with the buffer byte or not
while (recv(fd,p,1,0) != 0) // Start receiving 1 byte at a time
{
if (*p == EOL[eol_matched]) // if the byte matches with the first eol byte that is '\r'
{
++eol_matched;
if (eol_matched == EOL_SIZE) // if both the bytes matches with the EOL
{
*(p + 1 - EOL_SIZE) = '\0'; // End the string
return (strlen(buffer)); // Return the bytes recieved
}
} else {
eol_matched = 0;
}
p++; // Increment the pointer to receive next byte
}
return (0);
}
/*
A helper function: Returns the
web root location.
*/
char* webroot() {
// open the file "conf" for reading
FILE *in = fopen("conf","rt");
// read the first line from the file
char buff[1000];
fgets(buff,1000,in);
// close the stream
fclose(in);
char* nl_ptr = strrchr(buff,'\n');
if (nl_ptr != NULL)
*nl_ptr = '\0';
return strdup(buff);
}
/*
Handles PHP requests
*/
void PHP_cgi(char* script_path,int fd) {
send_new(fd,"HTTP/1.1 200 OK\n Server: Web Server in C\n Connection: close\n");
dup2(fd,STDOUT_FILENO);
char script[500];
strcpy(script,"SCRIPT_FILENAME=");
strcat(script,script_path);
putenv("GATEWAY_INTERFACE=CGI/1.1");
putenv(script);
putenv("QUERY_STRING=");
putenv("REQUEST_METHOD=GET");
putenv("REDIRECT_STATUS=true");
putenv("SERVER_PROTOCOL=HTTP/1.1");
putenv("REMOTE_HOST=127.0.0.1");
execl("/usr/bin/php-cgi","php-cgi",NULL);
}
/*
This function parses the HTTP requests,arrange resource locations,check for supported media types,serves files in a web root,sends the HTTP error codes.
*/
int connection(int fd) {
char request[500],resource[500],*ptr;
int fd1,length;
if (recv_new(fd,request) == 0) {
printf("Recieve Failed\n");
}
printf("%s\n",request);
// Check for a valid browser request
ptr = strstr(request," HTTP/");
if (ptr == NULL) {
printf("NOT HTTP !\n");
} else {
*ptr = 0;
ptr = NULL;
if (strncmp(request,"GET ",4) == 0) {
ptr = request + 4;
}
if (ptr == NULL) {
printf("Unknown Request ! \n");
} else {
if (ptr[strlen(ptr) - 1] == '/') {
strcat(ptr,"index.html");
}
strcpy(resource,webroot());
strcat(resource,ptr);
char* s = strchr(ptr,'.');
int i;
for (i = 0; extensions[i].ext != NULL; i++) {
if (strcmp(s + 1,extensions[i].ext) == 0) {
fd1 = open(resource,O_RDONLY,0);
printf("opening \"%s\"\n",resource);
if (fd1 == -1) {
printf("404 File not found Error\n");
send_new(fd,"HTTP/1.1 404 Not Found\r\n");
send_new(fd,"Server : Web Server in C\r\n\r\n");
send_new(fd,"
404 Not Found");send_new(fd,"
404 Not Found: The requested resource could not be found!
");//Handling PHP requests
} else if (strcmp(extensions[i].ext,"PHP") == 0) {
PHP_cgi(resource,fd);
sleep(1);
close(fd);
exit(1);
} else {
printf("200 OK,Content-Type: %s\n\n",extensions[i].mediatype);
send_new(fd,"HTTP/1.1 200 OK\r\n");
send_new(fd,"Server : Web Server in C\r\n\r\n");
if (ptr == request + 4) // if it is a GET request
{
if ((length = get_file_size(fd1)) == -1)
printf("Error in getting size !\n");
size_t total_bytes_sent = 0;
ssize_t bytes_sent;
while (total_bytes_sent < length) {
//Zero copy optimization
if ((bytes_sent = sendfile(fd,fd1,length - total_bytes_sent)) <= 0) {
if (errno == EINTR || errno == EAGAIN) {
continue;
}
perror("sendfile");
return -1;
}
total_bytes_sent += bytes_sent;
}
}
}
break;
}
int size = sizeof(extensions) / sizeof(extensions[0]);
if (i == size - 2) {
printf("415 Unsupported Media Type\n");
send_new(fd,"HTTP/1.1 415 Unsupported Media Type\r\n");
send_new(fd,"Server : Web Server in C\r\n\r\n");
send_new(fd,"
415 Unsupported Media Type");send_new(fd,"
415 Unsupported Media Type!
");}
}
close(fd);
}
}
shutdown(fd,SHUT_RDWR);
}
int main(int argc,char *argv[]) {
int sockfd,newsockfd,portno,pid;
socklen_t clilen;
struct sockaddr_in serv_addr,cli_addr;
if (argc < 2) {
fprintf(stderr,"ERROR,no port provided\n");
exit(1);
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr,sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
/*
Server runs forever,forking off a separate
process for each connection.
*/
while (1) {
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
if (newsockfd < 0)
error("ERROR on accept");
pid = fork();
if (pid < 0)
error("ERROR on fork");
if (pid == 0) {
close(sockfd);
connection(newsockfd);
exit(0);
} else
close(newsockfd);
} /* end of while */
close(sockfd);
return 0; /* we never get here */
}
以上是编程之家(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
总结
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。