C 开发web支持php,用C一步步开发web服务器(4)

在教程1,教程2,教程3的带领下,大家肯定迫不及待进行教程4的开发了吧,这一章节,我们要完成现在这个webserver的所有功能,支持php动态页面以及报错404页面的开发,先展示下最终实现的界面

e681ab05230b

e681ab05230b

话不多说,先支持PHP再说

1.浏览器输入

可见,他是指向当前目录下的index.php文件,所以先在这个目录下创建文件

鹏哥的第一个web服务器

$array = array(

"id" => "1",

"name"=> "pengge",

"aaa" => "sdsdd",

"yes" => "sdsdfsfsff"

);

echo "

";

var_dump($array);

?>

2.顺着教程3的思路,解析filename的文件名,发现他是.php文件,所以我们不能直接文件读取他的内容,我们需要通过php脚本执行该文件内容,然后输出到浏览器上

重写wrap_response方法,使其支持php

/**

* @desc 封装response 支持静态页面以及php页面

*

*/

void wrap_response(int connfd,char *filename) {

struct stat sbuf;

int filefd,phpfd;

char *php_result;

char *srcp;

char response[MAXLINE],filetype[MAXLINE];

if(stat(filename,&sbuf) < 0) {

error_response(connfd);

exit(1);

}else {

//获取文件类型

get_filetype(filename,filetype);

//打开文件并将其写入内存,并由浏览器展示

filefd = open(filename,O_RDONLY);

//走php脚本执行输出

if(strstr(filename, ".php")) {

sprintf(response, "HTTP/1.1 200 OK\r\n");

sprintf(response, "%sServer: Pengge Web Server\r\n",response);

sprintf(response, "%sConnection: close\r\n",response);

sprintf(response, "%sContent-type: %s\r\n\r\n",response,filetype);

Write(connfd, response, strlen(response));

printf("Response headers:\n");

printf("%s\n",response);

php_cgi(filename, connfd);

Close(connfd);

exit(1);

//走静态页面输出

}else {

//拼接静态文件的response头

sprintf(response, "HTTP/1.0 200 OK\r\n");

sprintf(response, "%sServer: Pengge Web Server\r\n",response);

sprintf(response, "%sConnection: close\r\n",response);

sprintf(response, "%sContent-length: %lld\r\n",response,sbuf.st_size);

sprintf(response, "%sContent-type: %s\r\n\r\n",response,filetype);

Write(connfd, response, strlen(response));

printf("Response headers:\n");

printf("%s\n",response);

srcp = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, filefd, 0);

Close(filefd);

//清空srcp空间

Write(connfd, srcp, sbuf.st_size);

munmap(srcp, sbuf.st_size);

}

}

}

这里有个

php_cgi(filename, connfd);

这个方法,这个就是执行php脚本输出到页面的方法,我们可以这样写

void php_cgi(char* script_path, int fd) {

dup2(fd, STDOUT_FILENO);

execl("/usr/bin/php","/usr/bin/php",script_path,(char *) NULL);

}

大家可以查查dup2跟execl的用法,这里不介绍了

综上,我们完成了支持PHP的webserver

接下来,我们要进行404错误界面的开发了,

浏览器输入

1.因为不存在这个页面,所以我们需要像nginx一样,创建一个404页面

404 Not Found

404 Not Found


Pengge Server/1.0

2.在stat(filename,&sbuf)方法中判断

/**

* @desc 封装response 支持静态页面以及php页面

*

*/

void wrap_response(int connfd,char *filename) {

struct stat sbuf;

int filefd,phpfd;

char *php_result;

char *srcp;

char response[MAXLINE],filetype[MAXLINE];

if(stat(filename,&sbuf) < 0) {

error_response(connfd);

exit(1);

}else {

如果不存在,我们就会让他走一个error_sponse方法,这里就会包装response头信息以及文件

/**

* @desc 404页面的response拼接

*

*/

void error_response(int connfd) {

struct stat sbuf;

int filefd;

char *srcp;

char error_body[MAXLINE],response[MAXLINE];

char filename[] = "./404.html";

stat(filename,&sbuf);

filefd = open(filename,O_RDONLY);

sprintf(response, "HTTP/1.1 404 Not found\r\n");

sprintf(response, "%sServer: Pengge Web Server\r\n",response);

sprintf(response, "%sConnection: close\r\n",response);

sprintf(response, "%sContent-length: %lld\r\n",response,sbuf.st_size);

sprintf(response, "%sContent-type: text/html\r\n\r\n",response);

Write(connfd, response, strlen(response));

printf("Response headers:\n");

srcp = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, filefd, 0);

Close(filefd);

//清空srcp空间

Write(connfd, srcp, sbuf.st_size);

munmap(srcp, sbuf.st_size);

}

这个时候重新打开浏览器,运行

查看浏览器是不是有这样的报错界面了

e681ab05230b

到此,整个webserver到此结束了,撒花

最后,留给自己以及读者讨论的内容有以下几点

如何支持像nginx一样的配置文件

nginx中的epoll 模式能否支持

同样是nginx中的功能,如负载均衡,动静分离该怎么在配置文件中配置,并实现

...

最后献上我的代码,我传到我的github上了。多谢欣赏,希望能对大家有帮助原文章链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值