CGI的功能:通常情况下CGI程序被用来解释处理来自表单的输入信息,在服务器产生相应的处理,并将相应的信息反馈给浏览器。CGI程序使网页具有交互功能。
CGI处理步骤: 通过Internet把用户请求送到服务器服务器接收用户请求并交给CGI程序处理CGI程序把处理结果传送给服务器服务器把结果送回到用户
CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。
CGI程序的输出: CGI程序中的标准输出是经过重定向了的。CGI程序并不会在服务器上产生任何的输出内容,而是被重定向到客户浏览器。这样,如果编写一个C的CGI程序的时候,把一个HTML文档输出到它的stdout上,这个HTML文档会被在客户端的浏览器中显示出来。这也是CGI程序的一个基本原理。
CGI程序第一行输出的内容必须是: "Content-Type:text/html"这个输出作为HTML的文件头。因为CGI不仅可以像浏览器输出HTML文本,而且可以输出图像,声音之类的东西,http服务器向远程发送文件时要说明文件类型。
两个重要的CGI环境变量
QUERY-STRING:GET方法表单输入的数据,URL中间号后的内容。
CONTENT-LENGTH:POST方法输入的数据的字节数。
CGI环境变量列表:
SERVER-NAME:运行CGI序为机器名或IP地址。
SERVER-INTERFACE:WWW服务器的类型,如:CERN型或NCSA型。
SERVER-PROTOCOL:通信协议,应当是HTTP/1.0。
SERVER-PORT:TCP端口,一般说来web端口是80。
HTTP-ACCEPT:HTTP定义的浏览器能够接受的数据类型。
HTTP-REFERER: 发送表单的文件URL。(并非所有的浏览器都传送这一变量)
HTTP-USER-AGENT:发送表单的浏览器的有关信息。
GETWAY-INTERFACE:CGI程序的版本,在UNIX下为 CGI/1.1。
PATH-TRANSLATED: PATH-INFO中包含的实际路径名。
PATH-INFO:浏览器用GET方式发送数据时的附加路径。
SCRIPT-NAME: CGI程序的路径名。
QUERY-STRING:表单输入的数据,URL中间号后的内容。
REMOTE-HOST:发送程序的主机名,不能确定该值。
REMOTE-ADDR:发送程序的机器的IP地址。
REMOTE-USER:发送程序的人名。
CONTENT-TYPE:POST发送,一般为applioation/xwww-form-urlencoded。
CONTENT-LENGTH:POST方法输入的数据的字节数。
二,CGICC----用C++实现的一个cgi库
cgicc是开发cgi程序的c++库,它是基于stl的,从使用上来说,可以把它分成两个部分:第一部分是输入输出的处理和封装,它包括 Cgicc、CgiEnvironment、CgiInput、FormEntry和FormFile类,第二部分是数据输出模块,它们是以MStreamable为基类的封装了HTTPHeader和HTML元素的一系列子类。HTTPCookie是继承MStreamable的,但是,对于输入Cookie来说,也是通过HTTPCookie来表示的,也许这是因为Cookie通常需要在不同请求中保留而设计的。
Cgicc:封装了Web Server和CGI程序之间的数据过渡功能,对于Web Server来说它是参数的输出对象,对于CGI程序来说它是提取Web Server传递过来的数据(包括浏览器信息、Web Server自身的数据和用户提交的数据)的代理。
CgiEnvironment:表示CGI运行的环境变量,这些环境变量是Web Server初始化的,也就CGI需要处理的数据,它是作为Cgicc对象的数据成员而保存的,当然开发者也可以通过getEnvironment()来直接获得CgiEnvironment的const引用。
CgiInput:这是对于Web Server数据输入方式的抽象,对于传统CGI程序来说它就是标准输入,对于FastCGI来说,它是一个独立的sockket,而且对于FastCGI或者是用户自定义的参数输入方式来说,可以通过继承CgiInput来生成定制的类,只要在子类中覆盖read、getenv成员函数就能够很好地工作。
FormEntry和FormFile是对于用户提交的数据的抽象,FormEntry是描述普通name-value对的抽象,而FormFile则是对用户上传的文件的抽象。事实上FormEntry和FormFile的本质差别就是FomFile多了一个文件名和文件类型。
输出数据的封装类比较多,这里只是说说它设计的基本思想,如果需要详细的接口说明,可以参看cgicc的帮助文档。
cgicc中重载了流输出函数:CGICC_API std::ostream& operator<<(std::ostream& out, const MStreamable& obj);在具有输出功能的基类MStreamable里声明为友元函数,这样只要以 "outstream << MStreamable" 的形式调用的话,就会调用这个自定义的输出流函数,在这个自定义的流输出函数中,会调用MStreamable.render(outstream), 也就是说只要在MStreamable的子类中覆盖render成员函数就能够定制之类的输出。在应用中,通常之类会把自己的内部数据转换为字符串,然后调用outstream << data_str ,只要在outstream的成员函数中覆盖<<操作符,就能够实现各种输出协议(当然也包括FastCGI协议),在传统的CGI中,这个outstream就是std::cout对象。
cgicc的详细说明文档及案例:cgicc-3.2\doc\html\index.html
例子:
html网页:</