Common Gateway Interface如雷贯耳,遗憾的是一直以来都没玩过CGI,今天尝试一把。Tomcat可以是玩CGI的,但得改下配置。为了方便,直接使用一款更轻量级的web服务器lighttpd来跑,。

  先把lighttpd安装一下:直接使用linux的包管理器,先安装一个epel软件仓库

yum install epel-release

    从这个仓库里拿到lighttpd并安装

yum install lighttpd

  安装好web服务器后就可以来写CGI代码了,可以用各种语言来写,这里选择C。C编译后本身就是可执行文件,所以我们得把CGI的配置改一改:

[root@iZbp11ahvmlfioymoo7u3bZ ~]# vi /etc/lighttpd/conf.d/cgi.conf 

#######################################################################
##
## CGI modules
## ---------------
##
## See https://redmine.lighttpd.net/projects/lighttpd/wiki/docs_modcgi
##
server.modules += ( "mod_cgi" ) ##
## Plain old CGI handling
##
## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini.
##
cgi.assign = ( ".pl" => "/usr/bin/perl",
".cgi" => "/usr/bin/perl",
".rb" => "/usr/bin/ruby",
".erb" => "/usr/bin/eruby",
".py" => "/usr/bin/python" ) ##
## to get the old cgi-bin behavior of apache
##
## Note: make sure that mod_alias is loaded if you uncomment the
## next line. (see modules.conf)
##
#alias.url += ( "/cgi-bin" => server_root + "/cgi-bin" )
#$HTTP["url"] =~ "^/cgi-bin" {
# cgi.assign = ( "" => "" )
#} ##
#######################################################################

  这里将.cgi改为

".cgi" => "",

  以上表示指定解析程序为空,这样对于带扩展名为.cgi的请求,不需要特定解析程序(比如用/bin/sh/perl)就能执行CGI。接着到/var/www/lighttpd目录,用C写一个简单例子

  

// A "hello world" page
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INCR_LEN 10 char *getValue(char *, char **);// get the param value
char **getParameters(char *, char **);// get the array of params and values
int main(void)
{
char **pQuery;
char *pParam;
char *name;
char *city;
pParam = getenv("QUERY_STRING");
char *pStr = malloc(strlen(pParam)+);
memcpy(pStr, pParam, strlen(pParam)+);
pQuery = getParameters(pStr, pQuery);
name = getValue("name", pQuery);
city = getValue("city", pQuery); printf("Content-Type:text/html\n\n");// print html
puts("<html>");
puts("<head><title>An HTML Page From a CGI</title></head>");
puts("<body><br>");
puts("<p><h2>Hello world!</h2></p>");
printf("<p>Your name is :%s</p>\n", name);
printf("<p>Your city is :%s</p>\n", city);
puts("</body>");
puts("</html>"); return ;
} char **getParameters(char *pTemp, char **pQuery)
{
char **pArrayTemp = NULL;
pQuery = calloc(INCR_LEN, sizeof(char *));
char *pParamIndex = NULL;
int i = ;
int count_max = INCR_LEN; while((pParamIndex = strchr(pTemp,'&')) != NULL)
{
if(i == count_max) // array reach max(10) need more memory
{
count_max += INCR_LEN;
pArrayTemp = realloc(pQuery, count_max*sizeof(char*));
if(!pArrayTemp)
{
exit();
}
pQuery = pArrayTemp;
} *(pQuery+i) = malloc(pParamIndex - pTemp + );
strncpy(*(pQuery+i), pTemp, pParamIndex - pTemp);
strncpy(pTemp, pParamIndex+, strlen(pTemp) - (pParamIndex-pTemp) + );
i++;
}
*(pQuery+i) = malloc(strlen(pTemp) + );
strncpy(*(pQuery+i), pTemp, strlen(pTemp)+);
return pQuery;
} char *getValue(char *pParameter, char **pParamValues)
{
char *pValue = NULL;
for(; *pParamValues!=NULL; pParamValues++)
{
if(strstr(*pParamValues, pParameter))
{
pValue = strchr(*pParamValues, '=');
if(pValue)
return pValue+;
}
} return NULL;
}

  把上面的C编译一下:

gcc hello.c -o hello.cgi

  最后把端口号由80改为其他端口号如8089,避免启动时与原有端口冲突。

vi /etc/lighttpd/lighttpd.conf

  找到server.port后,将80改为8089。接着启动lighttpd服务器:

systemctl start lighttpd

  再看下是否已经启起来了:

systemctl status lighttpd
● lighttpd.service - Lightning Fast Webserver With Light System Requirements
Loaded: loaded (/usr/lib/systemd/system/lighttpd.service; disabled; vendor preset: disabled)
Active: active (running) since Thu -- :: CST; 2s ago
Main PID: (lighttpd)
CGroup: /system.slice/lighttpd.service
└─ /usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf Apr :: iZbp11ahvmlfioywlf7u3bZ systemd[]: Started Lightning Fast Webserver With Light System Requirements.
Apr :: iZbp11ahvmlfioywlf7u3bZ lighttpd[]: -- ::: (network.c.) warning: please use server.use-ipv6 only for hostnames, not wi...Y changes
Apr :: iZbp11ahvmlfioywlf7u3bZ lighttpd[]: -- ::: (server.c.) can't have more connections than fds/2: 1024 1024

  我们看到已经启动成功了,但提示要用ipv6的地址来访问,但我想用ipv4,所以把它改掉,再次/etc/lighttpd/lighttpd.conf -> 找到server.use-ipv6 = "enable" -> 将enable改为disable -> systemctl restart lighttpd

  然后我们通过ip:8089/index.html访问lighttpd自带的欢迎页:

  再去访问我们编译好的hello.cgi,发现页面可以访问,却啥都没有,浏览器把页面直接下载了而不是渲染出来。咋回事呢?原来这时候的cgi文件浏览器是无法解析的,必须要去modules.conf里打开cgi:vi /etc/lighttpd/modules.conf -> 找到 #include "conf.d/cgi.conf" -> 将前面的#号删掉 -> 重启lighttpd systemctl restart lighttpd

  再次访问我们的hello.cgi,这次ok了

linux上通过lighttpd上跑一个C语言的CGI小页面以及所遇到的坑的更多相关文章

  1. 在K8S上跑一个helloworld

    建立docker镜像 为了方便起见,这里直接使用一个js网页作为应用,以此创建镜像 hello world网页 创建server.js,输入以下代码创建helloworld网页: var http = ...

  2. 安装了linux系统的设备上不了网怎么办

    玩了一阵子的树莓派,曾经计划将其作成一台小小无线路由,但是时间和精力关系始终未成功做成. 同时也有在进行一些arm开发板的学习,突然一天发现arm板直接插上网线不能是不能上网的,又想起之前玩树莓派的时 ...

  3. 把Linux安装到移动硬盘上

    把Linux安装到移动硬盘上 转载于:http://mrkh.me/install-linux-on-a-portable-hard-drive.html 这一篇文章讲一下,怎么把linux安装到移动 ...

  4. Linux 在一个命令行上执行多个命令

    Linux 在一个命令行上执行多个命令 1. [ ; ] 如果被分号(;)所分隔的命令会连续的执行下去,就算是错误的命令也会继续执行后面的命令. 2. [ && ] 如果命令被 &am ...

  5. 在 Linux 的 KVM虚拟机 上安装 Mac OS 系统的研究总结

    在 Linux 的 KVM虚拟机 上安装 Mac OS 系统的研究总结 一.资料来源:    网上一共找到两个方法,一个是视频上的教程,一个是网页资料. 二.视频资料方法内容:1.install qe ...

  6. 将Windows上的文件上传到Linux上

    下载一个SSH Secure Shell Client即可. SSHSecureShellClient-3.2.9下载地址: 免费下载地址在 http://linux.linuxidc.com/ 用户 ...

  7. 在openwrt上编译最简单的一个ipk包文件

    1 什么是opkg Opkg 是一个轻量快速的套件管理系统,目前已成为 Opensource 界嵌入式系统标准.常用于路由.交换机等嵌入式设备中,用来管理软件包的安装升级与下载. opkg updat ...

  8. linux的tomcat服务器上部署项目的方法

    在tomcat服务器上部署项目的前提,是我们已经准备好了tomcat服务器.在CentOs环境下部署JavaWeb环境,部署tomcat服务器在前面的文章中已经总结过了,可以参考以前文章. 一  to ...

  9. java使用Jsch实现远程操作linux服务器进行文件上传、下载,删除和显示目录信息

    1.java使用Jsch实现远程操作linux服务器进行文件上传.下载,删除和显示目录信息. 参考链接:https://www.cnblogs.com/longyg/archive/2012/06/2 ...

随机推荐

  1. Vue--Vue.nextTick()的使用

    Vue.nextTick()是比较常用到的API Vue官网对它的解释是:在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 首先要明白Vue的响应式 ...

  2. js数组的方法小结

    js中数组是一种非常常用数据结构,而且很容易模拟其他的一些数据结构,比如栈和队列.数组的原型Array.prototype内置了很多方法,下面就来小小总结一下这些方法. 检测数组就不用多说了,使用EC ...

  3. 从用户输入url到页面最后呈现 发生了些什么?

    一.浏览器获取资源的过程: 1.输入url 2.浏览器解析url,获得主机名 3.将主机名转换成服务器ip地址(查找本地DNS缓存列表,如果没有则向默认的DNS服务器发送查询请求) 4.浏览器建立一条 ...

  4. PHP:第二章——PHP中的for语句

    知识点一:for语句    语法格式:    for(expr1;expr2;expr3){        //代码块;    }     说明:     expr1:循环开始前,无条件的执行一次,并 ...

  5. 什么是REST API?

    REST指一组架构约束条件和原则,满足约束条件和原则的应用程序设计.架构,软件体系结构分为三部分:构建,用于描述计算机:连接器,用于描述构建的链接部分:配置将构建和连接器组成有机整体.web基本技术: ...

  6. Oracle 数据库分析

    一.数据库分析 二.表的分析 1.分析表exec dbms_stats.gather_table_stats('SFISM4','R_SN_DETAIL_T',CASCADE=>TRUE);ex ...

  7. 自己写的一个delphi正整数快速排序

    type   TIntArr= array of word; procedure MyQSort(var arr: TIntArr; low: word; high: word); //word可以改 ...

  8. repeat 中的 continue

    repeat a := -; then ShowMessage('') else begin Caption := ''; Continue;//不是立即 向上 返回 执行,要先向下 检查循环条件 是 ...

  9. Pycharm(四)常用快捷键

    Ctrl + Alt +S 进入设置Ctrl + Alt + L 代码格式化Ctrl + Alt + I 自动缩进Ctrl + D 复制当前行 Ctrl + / 注释(取消注释)当前行 再有什么用的多 ...

  10. nginx+uwsgi+django部署流程

    当我们在用django开发的web项目时,开发测试过程中用到的是django自带的测试服务器,由于其安全及稳定等性能方面的局限性,django官方并不建议将测试服务器用在实际生产. nginx+uws ...