Web服务器动态资源请求

1.浏览器请求动态页面过程

2.WSGI

Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”)。

WSGI允许开发者将选择web框架和web服务器分开。可以混合匹配web服务器和web框架,选择一个适合的配对。比如,可以在Gunicorn 或者 Nginx/uWSGI 或者 Waitress上运行 Django, Flask, 或 Pyramid。真正的混合匹配,得益于WSGI同时支持服务器和架构.

web服务器必须具备WSGI接口,所有的现代Python Web框架都已具备WSGI接口,它让你不对代码作修改就能使服务器和特点的web框架协同工作。

WSGI由web服务器支持,而web框架允许你选择适合自己的配对,但它同样对于服务器和框架开发者提供便利使他们可以专注于自己偏爱的领域和专长而不至于相互牵制。其他语言也有类似接口:java有Servlet API,Ruby 有 Rack。

3.定义WSGI接口

WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。我们来看一个最简单的Web版本的“Hello World!”:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return 'Hello World!'

上面的 application( ) 函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

  • environ:一个包含所有HTTP请求信息的dict对象;
  • start_response:一个发送HTTP响应的函数。

整个application( )函数本身没有涉及到任何解析HTTP的部分,也就是说,把底层web服务器解析部分和应用程序逻辑部分进行了分离,这样开发者就可以专心做一个领域了.

application( )函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器。而我们此时的web服务器项目的目的就是做一个极可能解析静态网页还可以解析动态网页的服务器

实现代码:

import time,multiprocessing,socket,os,re

class MyHttpServer(object):

    def __init__(self):
        serveSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serveSocket = serveSocket
        self.HTMLPATH = './html'

    def bind(self,port=8000):
        self.serveSocket.bind(('',port))

    def start(self):
        self.serveSocket.listen()
        while True:
            clientSocket, clientAddr = self.serveSocket.accept()
            print(clientSocket)
            multiprocessing.Process(target=self.serveHandler, args=(clientSocket, clientAddr)).start()
            clientSocket.close()

    def serveHandler(self,clientSocket,clientAddr):
        try:
            recvData = clientSocket.recv(1024).decode('gbk')
            fileName = re.split(r' +', recvData.splitlines()[0])[1]
            filePath = self.HTMLPATH

            if fileName.endswith('.py'):
                try:
                    pyname=fileName[1:-3]
                    # 导入
                    pyModule = __import__(pyname)

                    env={}
                    responseBody = pyModule.application(env,self.startResponse)
                    responseLine = self.responseLine
                    responseHeader = self.responseHeader
                except ImportError:
                    responseLine = 'HTTP/1.1 404 NOT FOUND'
                    responseHeader = 'Server: ererbai' + os.linesep
                    responseHeader += 'Date: %s' % time.ctime()
                    responseBody = '<h1>很抱歉,服务器中找不到你想要的内容<h1>'
            else:
                if '/'== fileName:
                    filePath += '/index.html'
                else:
                    filePath += fileName

                try:
                    file = None
                    file =open(filePath,'r',encoding='gbk')
                    responseBody = file.read()

                    responseLine = 'HTTP/1.1 200 OK'
                    responseHeader = 'Server: ererbai' + os.linesep
                    responseHeader += 'Date:%s' % time.ctime()
                except FileNotFoundError:
                    responseLine = 'HTTP/1.1 404 NOT FOUND'
                    responseHeader = 'Server: ererbai' + os.linesep
                    responseHeader += 'Date:%s' % time.ctime()
                    responseBody = '很抱歉,服务器中找不到你想要的内容'


                finally:
                    if (file!=None) and (not file.closed):
                        file.close()

        except Exception as ex:
            responseLine = 'HTTP/1.1 500 ERROR'
            responseHeader = 'Server: ererbai' + os.linesep
            responseHeader += 'Date: %s' % time.ctime()
            responseBody = '服务器正在维护中,请稍后再试。%s'%ex
        finally:
            senData = responseLine + os.linesep + responseHeader + os.linesep + os.linesep + responseBody
            print(senData)
            senData = senData.encode('gbk')
            clientSocket.send(senData)
            if (clientSocket!=None) and ( not clientSocket._closed):
                clientSocket.close()

    def startResponse(self,status,responseHeaders):
        self.responseLine = status
        self.responseHeader = ''
        for k,v in responseHeaders:
            kv = k + ':' + v + os.linesep
            self.responseHeader += kv



if __name__ == '__main__':
    server = MyHttpServer()
    server.bind(8000)
    server.start()

服务器中存在的html的文件:

  • index.html
<html>
<head>
    <title>首页-毕业季</title>
    <meta http-equiv=Content-Type content="text/html;charset=gbk">

</head>
<body>我们仍需共生命的慷慨与繁华相爱,即使岁月以刻薄和荒芜相欺。
</body>
</html>
  • biye.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="gbk">
    <title>毕业季</title>
</head>
<body>![](http://localhost:51017/day18/html/biyeji.png)
<br>当年以为六月不过也很平常
<br>当自己真正经历了毕业
<br>才知道偶尔看到六月毕业季等字里所流露的种种想要重温却不敢提及的回忆
<br>毕业了
<br>那个夏天,我的毕业季,我的青春年少
<br>六月
<br>有人笑着说解脱,有人哭着说不舍
<br>那年,
<br>你对我说的你好
<br>在不知不觉中
<br>变成了
<br>再见。

</body>
</html>
biyeji.png

mytime.py文件

import time
def application(env,startResponse):
    status = 'HTTP/1.1 200 OK'
    responseHeaders = [('Server','bfe/1.0.8.18'),('Date','%s'%time.ctime()),('Content-Type','text/plain')]
    startResponse(status,responseHeaders)

    responseBody = str(time.ctime())
    return responseBody

访问结果:

首页
biye.html
mytime.py
'''
自定义的符合wsgi的框架
'''
import time


class Application(object):
    def __init__(self, urls):
        '''框架初始化的时候需要获取路由列表'''
        self.urls = urls

    def __call__(self, env, startResponse):
        '''
        判断是静态资源还是动态资源。
        设置状态码和响应头和响应体
        :param env:
        :param startResponse:
        :return:
        '''
        # 从请求头中获取文件名
        fileName = env.get('PATH_INFO')

        # 判断静态还是动态
        if fileName.startwith('/static'):
            fileName = fileName[7:]
            if '/' == fileName:
                filePath += '/index.html'
            else:
                filePath += fileName
            try:
                file = None
                file = open(filePath, 'r', encoding='gbk')
                responseBody = file.read()
                status = 'HTTP/1.1 200 OK'
                responseHeaders = [('Server', 'ererbai')]

            except FileNotFoundError:
                status = 'HTTP/1.1 404 Not Found'
                responseHeaders = [('Server', 'ererbai')]
                responseBody = '<h1>找不到<h1>'
            finally:
                startResponse(status, responseHeaders)
                if (file != None) and (not file.closed):
                    file.close()
        else:
            isHas = False  # 表示请求的名字是否在urls中,True:存在,False:不存在
            for url, func in self.urls:
                if url == fileName:
                    responseBody = func(env, startResponse)
                    isHas = True
                    break
            if isHas == False:
                status = 'HTTP/1.1 404 Not Found'
                responseHeaders = [('Server', 'ererbai')]
                responseBody = '<h1>找不到<h1>'
                startResponse(status, responseHeaders)
        return responseBody


def mytime(env, startResponse):
    status = 'HTTP/1.1 200 OK'
    responseHeaders = [('Server', 'time')]
    startResponse(status, responseHeaders)
    responseBody = str(time.ctime())
    return responseBody




def mynews(env, startResponse):
    status = 'HTTP/1.1 200 OK'
    responseHeaders = [('Server', 'news')]
    startResponse(status, responseHeaders)
    responseBody = str('xx新闻')
    return responseBody


'''路由列表'''
urls = [
    ('/mytime', mytime),
    ('/mynews', mynews)
]

application = Application(urls)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容