初识CGI
CGI
Web 服务器只能生成静态内容,而用户请求动态内容时,Web服务器只能借助一些应用程序来实现。CGI时一套标准,它规定了Web服务器和应用程序之间的交互方式。
静态内容与动态内容
要想理解什么是CGI,首先需要什么是静态内容和动态内容。
静态内容:web 服务器读取一个磁盘文件,并将其内容返回给客户端。磁盘文件的称为静态内容,而返回文件给客户端的过程称为服务静态内容。
动态内容:web服务器运行一个可执行程序,并将它的输出结果返回给客户端。运行时可执行文件产生的输出称为动态内容。而运行程序并返回它的输出到客户端的过程称为服务动态内容。
服务动态内容
在web服务器服务动态内容时,一般需要创建一个子进程来运行可执行程序。在程序运行时时回读取用户提供的一些参数,比如一个加法程序需要读入加数和被加数,那么用户如何将程序参数传递给服务器?而服务器如何将这些参数传递给它所创建的子进程?子进程将它的输出又发送到哪里?CGI的出现则解决了这些问题。CGI是一套标准,规定了web服务器与可执行程序之间的交互方式,关于其具体说明可以参考RFC3875文档。
在对客户端请求的处理过程中,web服务器扮演着应用网关的角色。它接受来自客户端的请求,将客户端请求转为一个CGI请求,然后选择一个可执行文件(CGI脚本)去处理CGI请求。CGI脚本的执行结果称为CGI响应,web服务器将CGI响应转为客户端响应,将其发送给客户端。在实际应用中,web服务器负责处理与客户端请求有关的传输和网络问题,它会根据CGI标准将请求中一些参数写到环境变量中,然后CGI脚本从环境变量(environment variables)和标准输入(standard input)中读取数据、处理数据、向标准输出(standard output)输出数据。
服务器将参数传递给子进程
在服务器接受到一个如下的请求后:
GET /cgi-bin/add?100&200 HTTP/1.1
它调用fork来创建一个子进程,并调用execve在子进程的上下文中执行/cgi-bin/add程序。像add这样的程序被称作CGI程序,因为它遵循CGI标准。在调用execve之前,子进程将CGI环境变量QUERY_STRING设置为“100&200”,add程序在运行时可以用getenv函数来读取环境变量的值。
服务器如何将其他信息传递给子进程
CGI定义了大量的其他环境变量,一个CGI程序在它运行时可以设置这些环境变量。下表中给出了其中的一部分:
环境变量 | 描述 |
---|---|
QUERY_STRING | 程序参数 |
SERVER_PORT | 父进程监听端口 |
REQUESET_METHOD | GET或POST |
REMOTE_HOST | 客户端域名 |
REMOTE_ADDR | 客户端中点分十进制IP地址 |
CONTENT_TYPE | 对于POST而言,请求体的MIME类型 |
CONTENT_LENGTH | 对于POST而言,请求体字节大小 |
服务器可以将一些信息写到对应的环境变量中,而客户端则从环境变量中读取这些信息。
子进程将它的输出发送到哪
一个CGI程序将它的动态内容发送到标准输出。在子进程加载并运行CGI程序之前,它使用Linux dup2函数将标准输出重定向到和客户端相关联的已连接描述符。因此,任何CGI程序写到标准输出的东西都会直接到客户端。
CGI实战
通过具体的案例来理解什么时CGI,以及CGI在实际中时如何被应用的。环境为Ubuntu16,Apache2。
启动CGI模块
- 如果apache工作在prefork模式,加载CGI模块 sudo a2enmod cgi
- 如果apache工作在worker模式,加载CGID模块sudo a2enmod cgid
- 可以通过** apache2ctl -t -D DUMP_MODULES **指令来查看加载prefork模块还是worker模块,从而判断其工作模式
启用CGI配置文件
CGI配置文件位于/etc/apache2/conf-avaliable目录下,将其软连接到/etc/apache2/conf-enabled目录下,或者直接使用命令sudo a2enconf serve-cgi-bin, 配置文件内容修改如下,其中/usr/lib/cgi-bin用于存放CGI脚本:
<IfModule mod_alias.c> <IfModule mod_cgi.c>
Define ENABLE_USR_LIB_CGI_BIN
</IfModule>
<IfModule mod_cgid.c>
Define ENABLE_USR_LIB_CGI_BIN
</IfModule>
<IfDefine ENABLE_USR_LIB_CGI_BIN>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AddHandler cgi-script .cgi
Require all granted
</Directory>
</IfDefine>
</IfModule>
编写CGI程序
CGI程序可以以任何语言编写,我们这里使用C语言编写。代码如下:
#include<stdio.h>
int main() {
printf("Content-Type: text/html\n\n"); #这行代码必须加
printf("hello world!");
return 0;
}
将代码保存到test.c文件中,使用gcc对其进行编译生成可执行文件test.cgi,将test.cgi放置在/usr/lib/cgi-bin目录中,这里需要为test.cgi赋予可执行权限。
访问CGI程序
重启apache2服务器:systemctl restart apache2
在浏览器输入:http://地址/cgi-bin/test.cgi
补充
Apache不仅可以配置CGI方式,也可以配置模块方式,而其默认方式模块方式。PHP就是以模块方式在Apache上进行运行的。,关于Apache的其他方式可以参考链接。
参考
初识CGI的更多相关文章
- 【转】初识CGI
一.基本原理 CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口.通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器 ...
- shell脚本--初识CGI
CGI按照百度百科的定义,如下: CGI 是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能.CGI 应用程序能与浏览器进行交互,还可通过数据库API 与数据库服务器等外部数 ...
- CGI初识
---恢复内容开始--- 转自http://www.moon-soft.com/program/bbs/readelite887957.htm 用 C/C++ 写 CGI 程序 小传(zhcharle ...
- 初识中间件Kafka
初识中间件Kafka Author:SimplelWu 什么是消息中间件? 非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件 关注于数据的发送和接 ...
- 性能测试--初识Jmeter
初识Jmeter Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动 ...
- Python高手之路【一】初识python
Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...
- CGI与FastCGI nginx+PHP-FPM
本文转载自CGI与FastCGI 1.当我们在谈到cgi的时候,我们在讨论什么 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html. ...
- Android动画效果之初识Property Animation(属性动画)
前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...
- CGI与FastCGI
当我们在谈到cgi的时候,我们在讨论什么 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html.事物总是不 断发展,网站也越来越复杂, ...
随机推荐
- HTML节点树
在 HTML 中,所有标签定义的内容都是节点: 整个文档是一个文档节点 每个HTML元素是元素节点 HTML元素内的文本是文本节点 每个HTML属性是属性节点 注释是注释节点 这些节点构成了一个 HT ...
- MQTT协议笔记之mqtt.io项目Websocket协议支持
前言 MQTT协议专注于网络.资源受限环境,建立之初不曾考虑WEB环境,倒也正常.虽然如此,但不代表它不适合HTML5环境. HTML5 Websocket是建立在TCP基础上的双通道通信,和TCP通 ...
- MQTT的学习研究(十)【转】mosquitto——一个开源的mqtt代理
MQTT(MQ Telemetry Transport),消息队列遥测传输协议,轻量级的发布/订阅协议,适用于一些条件比较苛刻的环境,进行低带宽.不可靠或间歇性的通信.值得一提的是mqtt提供三种不同 ...
- C# 文件夹的常用操作
C#获取文件夹下的所有文件的文件名 string path = @"E:\微课视频大于200M"; DirectoryInfo folder = new DirectoryInfo ...
- SQL用户存在则更新不存在则插入
1.添加索引(一般是唯一索引,我的是联合唯一索引): alter table T_Cart add unique index(goods_id,user_id); 2.SQL /* * 保存购物车(如 ...
- 自定义Realm解析
自定义Realm解析---------------------------------------> /* * Copyright 2005-2013 shopxx.net. All right ...
- 导出无法正常启动的VMware虚拟机中的文件
为了使用网银,在MacBook中用VMware虚拟机跑Windows 8.今天在使用Windows 8时,Windows Update自动安装了更新并自动重启,结果怎么也启动不起来了.不是停在&quo ...
- python安装whl文件的注意事项(windows系统)
首先给大家来一波福利,在没有连接外网(互联网)的情况下,只有公司内网或者断网情况下,需要安装python的一些依赖,不会操作的同学可能就会遇到麻烦.这里教大家离线安装python依赖. 方法:使用.w ...
- Strongly connected---hdu4635(强联通分量)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 先判断图是否强连通.如果不是强连通的,那么缩点. 我们的目的是加最多的边,那么最后的图中,肯定两 ...
- RSA与AES的区别
RSA 非对称加密,公钥加密,私钥解密,反之亦然.由于需要大数的乘幂求模等算法,运行速度慢,不易于硬件实现. 通常私钥长度有512bit,1024bit,2048bit,4096bit,长度越长,越安 ...