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

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

"There are two ways of constructing a software design; one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult."-C. A. R. Hoare

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

Tag:
« »