从零开始一个http服务器(五)-模拟cgi
从零开始一个http服务器-模拟cgi(五)
代码地址 : https://github.com/flamedancer/cserver
git checkout step5
运行:
make clean && make && ./myserver.out
测试
浏览器打开 http://127.0.0.1:9734/action/show_date
模拟cgi:用外部程序来优化 动态 response
- cgi解释
- 调用外部程序
cgi解释
上一节中,我们确实是实现了动态的response:我们不需要修改我们的代码,也不需要中断server,只需要修改我们的html页面文件就可以实时的更改返回内容。
但是当需要返回更加灵活的内容,比如当前时间的时候,我们不可能每隔一秒钟就去改下页面文件。这时候就可以借助外部的程序,比如shell,来为我们生产返回内容。这个外部程序,就类似于常说的cgi程序。所谓cgi,维基百科是这么解释:通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。
这是说CGI是一种标准,只要服务器 和 外部的程序 都实现了这个标准,就可以相互通信。
我们这比较粗鲁一点,我们不管正规的CGI标准是什么,我们定义一个我们自己简单粗暴的标准,这个标准只有两条:
- 外部的程序 可以产生 标准输出
- 服务器可以获得外部的程序产生的标准输出
这样的话我们就可以把外部的程序的标准输出直接作为response的body。
调用外部程序
执行外部程序的核心函数为popen ,它会开启一个新进程执行传入的外部命令,返回一个管道文件流,读取这个管道文件流就可以读取到外部命令的输出。管道文件流需要用pclose关闭,而不是fclose。
void doCgi(char * filePath, struct http_response * response) {
char fileName[100];
char cmd[100];
sprintf(fileName, "cgi/%s", filePath + strlen(action_url + 1));
sprintf(cmd, "%s 2>&1", fileName);
FILE *fstream = NULL;
if (access(fileName, F_OK) == -1 || NULL == (fstream = popen(cmd, "r"))) {
// file doesn't exist or FILE cannot be exec
setResponseMsg(response, errorMsg);
return;
}
response->body = (char *)malloc((5000));
int len = 0;
char *buff = response->body;
do {
buff += len;
len = fread(buff, 1024, 1, fstream);
// printf("%d\n", len);
} while (len);
pclose(fstream);
response->body_size = strlen(response->body);
struct Item *item2 = newItem(
"Content-Type",
"text/html; charset=utf-8");
mapPush(response->headers, item2);
return;
}
建一个目录名为cgi,把我们写的外部程序放到这个目录,例如我们写个 cgi/show_date 程序:
#! /bin/bash
echo $(date)
make clean && make && ./myserver.out 打开 http://127.0.0.1:9734/action/show_date 可以看到实时的时间
从零开始一个http服务器(五)-模拟cgi的更多相关文章
- 从零开始一个http服务器(三)-返回response 构造
从零开始一个http服务器(三) 代码地址 : https://github.com/flamedancer/cserver git checkout step3 运行: gcc request.h ...
- 从零开始一个http服务器(六)-多路复用和压力测试
从零开始一个http服务器(六)-多路复用和压力测试 代码地址 : https://github.com/flamedancer/cserver git checkout step6 运行: make ...
- 从零开始一个http服务器(二)-请求request解析
从零开始一个http服务器 (二) 代码地址 : https://github.com/flamedancer/cserver git checkout step2 解析http request 观察 ...
- 从零开始一个http服务器(一)-开始
从零开始一个http服务器 (一) 代码地址 : https://github.com/flamedancer/cserver git checkout step1 一个简单的socket serve ...
- 从零开始一个http服务器(四)-动态返回
从零开始一个http服务器(四) 代码地址 : https://github.com/flamedancer/cserver git checkout step4 运行: make clean &am ...
- 在阿里云服务器(ECS)上从零开始搭建nginx服务器
本文介绍了如何在阿里云服务器上从零开始搭建nginx服务器.阿里云服务器(ECS)相信大家都不陌生,感兴趣的同学可以到http://www.aliyun.com/product/ecs去购买,或到体验 ...
- 用Backbone.js创建一个联系人管理系统(五)
原文: Build a Contacts Manager Using Backbone.js: Part 5 这是这系列教程最后一部分了. 之前所有的增删改都在前端完成. 这部分我们要把Contact ...
- 用java写一个web服务器
一.超文本传输协议 Web服务器和浏览器通过HTTP协议在Internet上发送和接收消息.HTTP协议是一种请求-应答式的协议——客户端发送一个请求,服务器返回该请求的应答.HTTP协议使用可靠的T ...
- 用C写一个web服务器(二) I/O多路复用之epoll
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
随机推荐
- jquery cookie插件
jquery-cookie下载地址:http://www.bootcdn.cn/jquery-cookie/ 使用方法: 1.引入jQuery.Cookie.js插件. <script src= ...
- Python中readline()函数 去除换行符
从Python中readline()函数读取的一行内容中含有换行符\n,很多时候我们需要处理不含有换行符的字符串,此时就要去掉换行符\n. 方法是使用strip()函数. 例子如下: f = open ...
- java继承-重写-super实例补充
方法重写: 是指子类根据需要父类继承来的方法进行改写,是多态机制的前奏. 重写注意点: 1.重写方法必须和被重写方法具有相同的方法名,参数列表和返回值. 2.重写方法方法不能使用比被重写方法更严格的访 ...
- MySQL查询时强制区分大写和小写
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zyb_icanplay7/article/details/24981791 平时非常少会考虑数据存储 ...
- oracle exp 无法导出空表
oracle exp 无法导出空表 select 'alter table '|| a.table_name ||' allocate extent;' from user_tables a wh ...
- BZOJ5072:[Lydsy1710月赛]小A的树(树形DP)
Description BZOJ只是扔了个下载链接 Solution 设$f[x][i]$表示$x$点选中$i$个黑点的最小连通块. 设$g[x][i]$表示$x$点选中$i$个黑点的最大连通块. 转 ...
- 多GPU计算
多GPU计算已经可以说,只要是个成熟的模型,都使用了这一点. 例如: gluoncv:https://github.com/dmlc/gluon-cv/blob/master/scripts/dete ...
- 【[TJOI2010]电影迷】
一度自闭 这道题一看就是最小割无疑 我们假设源点\(S\)表示看这个电影,汇点\(T\)表示不看这部电影 如果一个电影的价值为正,我们就从源点点连一条容量为\(val\)的边,表示割掉这个边也就是选择 ...
- 随手练——HDU-2037 、P-2920 时间安排(贪心)
普通时间安排 HDU-2037 :http://acm.hdu.edu.cn/showproblem.php?pid=2037 选取结束时间早的策略. #include <iostream> ...
- map详讲<二>
查找元素: Map可以根据健来查找元素,提供方法find(key),如果是这个健对应的元素存在,则返回的是这个健的迭代器iterator,否则返回的是std::end(): 使用find()函数有点笨 ...