C语言web服务器支持php,纯C语言实现的一个简单的web服务器

搜索热词

下面是编程之家 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)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值