python实现web服务器

426 查看

本想写一篇关于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()