本想写一篇关于http->nginx->php这个过程中数据是怎么传输的文章,想了半天,实在没有心情去写。刚好看了一下python,就想着用python实现一下web服务器的过程。这个很简单,目前只支持静态文件的加载,动态语言就要接入fastcgi了(目前还在看fastcgi,下一版本更新吧)。以前没写过python也是边写边查,好多东西用的不是特别好,还有,可以在这个基础上改动,可以支持access.log,多server配置。这里就不写了。

其实过程很简单,nginx大体也是这个逻辑(但是,nginx内部就复杂多了)。

  1. 创建socket,监听80端口(可以自设)

  2. 解析http协议中的request(获取你想要的参数)

  3. 通过获取的参数取服务器上找到相应的静态资源(这里只说静态资源,动态的下一篇再说)

  4. 组织http协议的response

  5. 通过80端口返回给客服端

#/usr/bin/python
import socket
import sys
import os
from thread import *

HOST = \'\';PORT = 8887

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print \'Socket created\'

try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print \'Bind failed. Error Code : \' + str(msg[0]) + \' Message \' + msg[1]
    sys.exit()

print \'Socket bind complete\'

s.listen(10)

print \'Socket now listening\'

def assces_log(request):
    fp = open(\'http.log\', \"aw\")
    fp.write(request+\"\\r\\n\")
    fp.close()

def parse_request(request):
    request = request.splitlines()
    line = request[0]
    line = line.split();
    dict_request = {\'method\':line[0], \'path\':line[1], \'version\':line[2]}
    return dict_request

while True:
    conn, addr = s.accept()
    request = conn.recv(1024)
    print request
    print \"\\r\\n\"

    dist_request = parse_request(request)
    path = dist_request[\'path\']
    path = os.getcwd() + path

    if os.path.isfile(path):
        if os.path.exists(path):
            fp = open(path, \"r\")
            reply = fp.read()
            fp.close()
            response_errno = 200
            response_msg = \'OK\'
        else:
            reply = \'Not found page\'
            response_errno = 404
            response_msg = \'Not found\'
    else:
        reply = \'Forbidden\'
        response_errno = 403
        response_msg = \'Forbidden\'

    response = \"HTTP/1.1 \" + str(response_errno) + \" \" + response_msg + \"\\r\\n\"
    response += \"\\r\\n\"
    response += reply
    print response

    assces_log(request)

    conn.sendall(response)
    conn.close()

s.close()