1. Web基础
Web客户端和服务器之间的交互用的是一个基于文本的应用级协议—HTTP协议。
过程:一个web客户端(即浏览器)打开一个到服务器的因特网连接,并且请求内容。
服务器响应所请求的内容,然后关闭连接。 浏览器 读取内容,并把它们显示在屏幕上。
Web服务与常规的文件检索服务(如FTP)的主要区别:web内容可以用HTML语言来编写。
一个HTML程序(页)包含指令(标记),告诉浏览器如何显示这页的各种文件和图形对象。
例 <b> Make me bold </b> 以粗体显示 Make me bold
同时,HTML真正强大之处在于 一个页面 可以包含指针(超链接),从而指向存放在任何因特网主机上的内容。
例 <a href= “http://www.baidu.com/index.html”>Baidu</a>
2. Web内容
Web内容是与MIME(MultipurposeInternet Mail Extensions)类型相关的字节序列。
MIME类型 |
描述 |
text/html |
HTML页面 |
text/plain |
无格式文本 |
application/postscript |
Postscript文档 |
image/gif |
Gif格式编码二进制图片 |
image/jpeg |
Jpeg格式编码二进制图片 |
Web服务器为 客户端 提供内容的两种方式:
1.读取磁盘文件,返回给客户端 内容 称为 静态内容,过程 称为服务静态内容。
2.运行一可执行文件,并将输出返回给客户端。 可执行文件产生的输出 称为 动态内容, 该过程 称 为服务动态内容。
Web服务器返回的内容是和他管理的某个文件相关联的。这些文件都有一个唯一的名字,成为URL(universal resourse locator)。
例:http://www.google.com:80/index.html (静态内容)
http://bluefish.ics.cs.cmu.edu:8000/cgi-bin/adder?15000&232 (动态内容)
可执行文件的URL可以在文件名后包括参数。其中,”?”分隔文件名和参数,而且每个参数用”&”字符分隔开
3. HTTP事务
包括HTTP请求 与 HTTP响应。
HTTP请求
请求行 |
<method> <uri> <version> |
例: GET /index.html HTTP/1.1 |
请求报头(零个或多个) |
<header name> : <header data> |
例: Host:www.aol.com |
终止报头 |
空行 “\r\n” |
|
其中,HTTP支持的方法(method)有: GET,POST, OPTIONS, PUT, DELETE, TRACE, HEAD
Uri(uniformresourse identifier 统一资源标识符) 是相应的 URL 的后缀,包括文件名和可选的参数。如 GET /index.htmlHTTP/1.1 中 /index.html 即为在 uri中传递的参数。
Uri 中参数不允许有空格,必须用字符串 ”%20”表示,其他特殊字符,也有类似编码。
HTTP 响应
响应行 |
<version> <status code> <status message> |
|
响应报头 |
<header name> : <header data> 其中两个重要的报头: Content-type(告诉客户端响应主体内容的MIME类型) Content-length(响应主体字节大小) |
|
终止报头 |
空行 “\r\n” |
|
响应主体 |
|
|
4. 服务动态内容
由CGI(commongateway interface)标准来解决。
例如
客户端如何将参数传于服务器? GET请求的参数 在URI中传递。
服务器如何将参数传递于子进程? 创建子进程,并调用execve执行 所请求的cgi程序。调用execve 之前子进程将设置 cgi环境变量,此处 用请求URI的cgi参数”1500&213”,将环境变量QUERY_STRING 设为”1500&213”。
例: if(fork()==0)//子进程内部
{
Setenv(“QUEUE_STRING”, ”1500&213”,1);
Dup2(fd, STDOUT_FILENO);
Execve(xx,xx,xx);//加载cgi程序
}
子进程运行时可以用 getenv()函数来引用。
例 GET /cgi-bin/adder?15000&213 HTTP/1.1
服务器如何将其他信息传递给子进程? 一个CGI程序在运行时可以设置环境变量
环境变量 |
描述 |
QUERY_STRING |
程序参数 |
SERVER_PORT |
父进程侦听的端口 |
….. |
… |
子进程将他的输出发送到哪里? 一个CGI程序将他的动态内容发送到 标准输出。在子进程加载并运行cgi程序之前,它使用dup2函数将标准输出重定向到和客户端 相关联的 已连接描述符上,因此,任何cgi程序写到标准输出的东西都直接到客户端。 (即Cgi运行在子进程的上下文中,能够访问所有在调用execve加载cgi程序前,就存在的打开文件和环境变量,并且在子进程中不受 父进程 影响)
同时,因为父进程不知道子进程生成的内容的类型和大小,所以需要子进程负责生成content-type,content-length响应包头,以及终止报头的空行。