HTTP学习笔记(6)——server

分类: 开发技术 | 作者: 尼莫船长 | 发表于 2013/10/29 1条评论


从本章开始,开始总结HTTP的结构,大概会包括HTTP Server/ Cache / Proxy / Client / ….
先从HTTP server开始说。必然的,分硬件和软件,硬件的不谈,只唠软件部分。
HTTP server有很多,比较主流的:tomcat、apache、nginx、jetty、resin、 WebSphere、 Weblogic、 IIS……
一图说明基本的HTTP server的工作流程:
httpserver

实际的一个Http server 应该保证如上图的7步
1>建立连接:接受一个Clinet的链接,如果不想让其链接,直接关闭它。
2>接收请求:能够从网络中读取一条HTTP 报文
3>处理请求:对报文正确解析,并且能够做出相应的行动
4>访问资源:访问报文中指定的某些资源
5>创建相应:构建带有正确首部的HTTP响应报文
6>发送响应:将创建的响应发送给客户端
7>记录处理过程:能够将已完成的事物处理过程记录到日志中。

1,建立连接
客户端发起的连接,Server需要作出判断,并且建立链接,要从TCP请求中把客户端的IP解析出来,并且server有权利随时中断某个客户端的连接(比如某些恶意连接请求)。
在server中,可以配置“反向DNS“,这样能够很方便的建立IP和客户端主机名的对应关系。

2,接收请求
server会从网络中读取HTTP 请求行;
读取请求的方法、版本号、资源名称、以及以r/n/(CRLF)为结尾的请求头;
如果有以CRLF为结尾的空行也要读取;
如果有Content-length,就会按照指定的长度读取报文流。

3,处理请求

不写了,后面全是这方面的东西。。。。

4,访问资源
4.1 资源的目录
明确一个概念: docroot (document root)
这是说明资源所在的服务器的目录。 比如,可能你会把所有的web文件都放到 /usr/local/public_web/ 这个文件夹中,那么对于web server来说,其 docroot就是这个目录了。
而且,在大部分HTTP server中 ,这个目录是可配的!

假如:你的网站图片都存放在这个/usr/local/public_web/pics 下,你的域名是www.abc.com
那么一个客户端请求地址是 HTTP://www.abc.com/webLogo.gif
实际上,客户端访问的是/usr/local/public_web/pics/webLogo.gif 这个文件。

对于一个HTTP server而言,它要有足够的安全设计,不能让客户端输入这样的命令:
http://www.abc.com/../
就可以访问/usr/local/ 这个目录, 这是非常危险的。

4.2 资源目录列表
大家可能会在访问某些网站时候,发现显示成这样:

contentlist

这有3种可能:
1,http server是配置了目录显示选项。
2,这是一个错误的URL,但是http server并没有做响应的处理。
3,这是一个被编辑过的目录列表。

一般来说,如果我们只输入一个域名,http server回去自动寻找index页面,如果没有,才会显示成列表。但是一般可以屏蔽掉这种展示方式,因为这样会暴露服务器的目录信息,可能会被某些人利用。

4.3 动态内容映射
http server是可以在后面连接动态内容发布的后端程序的,这个就不用说了……谁部署个tomcat还不扔个servlet玩玩……

5,构建响应

http server 构建响应的时候,必须提到一个东西叫MIME,一般来说,这个MIME列表会存在server的配置文件中,这个列表表明了这个HTTP server能够处理的所有的媒体类型,比如tomcat就存放在 /conf/WEB.xml这个文件中。这个用来填充 content-type这个首部字段。

http server 还有个重要的功能就是重定向(redirect)。一般回返回3xx的状态码,比如资源被永久或者临时移除,或者服务器的负载均衡需要,或者是直接进行请求转发到别的server上去。

6,7 发送响应和记录日志
没什么说的,在上一篇的连接管理已经写过了,记录日志也ok,一般http server都有,而且大部分日志格式是可以配置的。

好了,HTTP server 简单写完了,期间还受到恶魔澄的不停的打扰,烦死了,附上一个最简化版本的HTTP server程序,是perl写的,大家有兴趣的可以在支持perl的环境下试一试哦!

#/usr/bin/perl

use Socket;
use Carp;
use FileHandle;

$port = (@ARGV ? $ARGV[0] :9099);


$proto = getprotobyname('tcp');
socket (S,  PF_INET,  SOCK_STREAM,  $proto) ||  die;
setsockopt (S,  SOL_SOCKET, SO_REUSEADDR,   pack("l", l))    ||  die;
bind (S,    sockaddr_in($port,  INADDR_ANY)) || die;
listen (S,  SOMAXCONN) || die;
printf("   <<<mini server start on " , $port);


while (1)
{
    $cport_caddr = accept(C, S);
    ($cport, $caddr) = sockaddr_in($cport_caddr);
    C-> autoflush(1);


    $cname = gethostbyaddr($caddr, AF_INET);
    printf("  << request from '$S'  ", $cname);

    while ($line = <C>)
    {

        print $line;
        if($line == /^\r/)  
        {
            last;
        }

    }


    printf ("   <<< response  ");

    while ($line = <STDIN>)
    {
        $line =~ s/\r//;
        $line =~ s/\n//;
        if ($sline =~ /^\./) 
        {
            last;
        }

        print C $line."\r\n";

    }

    close(C);


}

操作方法,
1,复制,粘贴,保存,起名字随便,记得扩展名要用 .pl 比如:easyServer.pl
2,执行这个perl脚本,在浏览器地址栏输入: http://localhost:9099/abc.txt
3,观察你的脚本运行终端控制台,会发现http请求过来了,你这时候需要手动在控制台写一个正确HTTP响应:

http/ 1.1  200 ok
connection: close
content-type: text/plain

hahaha  my server is ok!!!
.

4,记得在响应最后 用一个英文的句号结尾,并且敲一个回车。你回到浏览器,就可以看见结果咯!O(∩_∩)O~

本章结束,下一篇,会写HTTP的代理——Proxy

移动设备快速阅读本文:
  请扫描二维码  -->

"Sometimes a scream is better than a thesis."-Ralph Waldo Emerson (1803-1882)

» 本文链接地址:http://www.wanghaoyan.com/?p=210 » 英雄不问来路,转载请注明出处,谢谢。
» 您也可以订阅本站:RSS 2.0

Tag:
« »