Tornado

Web框架之Tornado

Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本。这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。

Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。(关于如何扩容 服务器,以处理数以千计的客户端的连接的问题,请参阅 C10K problem。)

下载安装:


1

2

3

4

pip3 install tornado

 

源码安装

https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz

框架使用

一、快速上手


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#!/usr/bin/env python

# -*- coding:utf-8 -*-

   

import tornado.ioloop

import tornado.web

   

   

class MainHandler(tornado.web.RequestHandler):

    def get(self):

        self.write("Hello, world")

   

application = tornado.web.Application([

    (r"/index", MainHandler),

])

   

   

if __name__ == "__main__":

    application.listen(8888)

    tornado.ioloop.IOLoop.instance().start()

执行过程:

  • 第一步:执行脚本,监听 8888 端口
  • 第二步:浏览器客户端访问 /index  -->  http://127.0.0.1:8888/index
  • 第三步:服务器接受请求,并交由对应的类处理该请求
  • 第四步:类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法
  • 第五步:方法返回值的字符串内容发送浏览器

 异步非阻塞示例

二、路由系统

路由系统其实就是 url 和 类 的对应关系,这里不同于其他框架,其他很多框架均是 url 对应 函数,Tornado中每个url对应的是一个类。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#!/usr/bin/env python

# -*- coding:utf-8 -*-

   

import tornado.ioloop

import tornado.web

   

   

class MainHandler(tornado.web.RequestHandler):

    def get(self):

        self.write("Hello, world")

   

class StoryHandler(tornado.web.RequestHandler):

    def get(self, story_id):

        self.write("You requested the story " + story_id)

   

class BuyHandler(tornado.web.RequestHandler):

    def get(self):

        self.write("buy.wupeiqi.com/index")

   

application = tornado.web.Application([

    (r"/index", MainHandler),

    (r"/story/([0-9]+)", StoryHandler),

])

   

application.add_handlers(‘buy.wupeiqi.com$‘, [

    (r‘/index‘,BuyHandler),

])

   

if __name__ == "__main__":

    application.listen(80)

    tornado.ioloop.IOLoop.instance().start()

  Tornado中原生支持二级域名的路由,如:

三、模板引擎

Tornao中的模板语言和django中类似,模板引擎将模板文件载入内存,然后将数据嵌入其中,最终获取到一个完整的字符串,再将字符串返回给请求者。

Tornado 的模板支持“控制语句”和“表达语句”,控制语句是使用 {% 和 %} 包起来的 例如 {% if len(items) > 2 %}。表达语句是使用 {{ 和 }} 包起来的,例如 {{ items[0] }}

控制语句和对应的 Python 语句的格式基本完全相同。我们支持 ifforwhile 和 try,这些语句逻辑结束的位置需要用 {% end %} 做标记。还通过 extends 和 block 语句实现了模板继承。这些在 template 模块 的代码文档中有着详细的描述。

注:在使用模板前需要在setting中设置模板路径:"template_path" : "tpl"

1、基本使用

 app.py

 index.html

 其他方法

2、母版

 layout.html

 index.html

3、导入

 header.html

 index.html

4、自定义UIMethod以UIModule

a. 定义

 uimethods.py

 uimodules.py

b. 注册

 

c. 使用

 

四、静态文件

对于静态文件,可以配置静态文件的目录和前段使用时的前缀,并且Tornaodo还支持静态文件缓存。

 app.py

 index.html

注:静态文件缓存的实现

 

五、cookie

Tornado中可以对cookie进行操作,并且还可以对cookie进行签名以放置伪造。

1、基本操作

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        if not self.get_cookie("mycookie"):
            self.set_cookie("mycookie", "myvalue")
            self.write("Your cookie was not set yet!")
        else:
            self.write("Your cookie was set!")

2、加密cookie(签名)

Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息,你需要对 cookie 作签名以防止伪造。Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法,你需要在创建应用时提供一个密钥,名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中:

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        if not self.get_secure_cookie("mycookie"):
            self.set_secure_cookie("mycookie", "myvalue")
            self.write("Your cookie was not set yet!")
        else:
            self.write("Your cookie was set!")

application = tornado.web.Application([
    (r"/", MainHandler),
], cookie_secret="61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=")

 内部算法

签名Cookie的本质是:

写cookie过程:

  • 将值进行base64加密
  • 对除值以外的内容进行签名,哈希算法(无法逆向解析)
  • 拼接 签名 + 加密值

读cookie过程:

  • 读取 签名 + 加密值
  • 对签名进行验证
  • base64解密,获取值内容

注:许多API验证机制和安全cookie的实现机制相同。

 基于Cookie实现用户验证-Demo

 基于签名Cookie实现用户验证-Demo

3、JavaScript操作Cookie

由于Cookie保存在浏览器端,所以在浏览器端也可以使用JavaScript来操作Cookie。


1

2

3

4

5

6

7

8

9

/*

设置cookie,指定秒数过期

 */

function setCookie(name,value,expires){

    var temp = [];

    var current_date = new Date();

    current_date.setSeconds(current_date.getSeconds() + 5);

    document.cookie = name + "= "+ value +";expires=" + current_date.toUTCString();

}

对于参数:

  • domain   指定域名下的cookie
  • path       域名下指定url中的cookie
  • secure    https使用

注:jQuery中也有指定的插件 jQuery Cookie 专门用于操作cookie,猛击这里

六、CSRF

Tornado中的夸张请求伪造和Django中的相似,跨站伪造请求(Cross-site request forgery)

 配置

 普通表单

 使用 - AJAX

注:Ajax使用时,本质上就是去获取本地的cookie,携带cookie再来发送请求

七、上传文件

1、Form表单上传

 HTML


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import tornado.ioloop

import tornado.web

class MainHandler(tornado.web.RequestHandler):

    def get(self):

        self.render(‘index.html‘)

    def post(self*args, **kwargs):

        file_metas = self.request.files["fff"]

        # print(file_metas)

        for meta in file_metas:

            file_name = meta[‘filename‘]

            with open(file_name,‘wb‘) as up:

                up.write(meta[‘body‘])

settings = {

    ‘template_path‘‘template‘,

}

application = tornado.web.Application([

    (r"/index", MainHandler),

], **settings)

if __name__ == "__main__":

    application.listen(8000)

    tornado.ioloop.IOLoop.instance().start()

Python

 2、AJAX上传

 HTML - XMLHttpRequest

 

 HTML - iframe

 Python

 扩展:基于iframe实现Ajax上传示例

八、验证码

验证码原理在于后台自动创建一张带有随机内容的图片,然后将内容通过img标签输出到页面。

安装图像处理模块:pip3 install pillow

示例截图:

class CheckCodeHandler(BaseRequestHandler):
    def get(self, *args, **kwargs):
        stream = io.BytesIO()
        img, code = check_code.create_validate_code()
        img.save(stream, "png")
        self.session["CheckCode"] = code
        self.write(stream.getvalue())

自定义Web组件

一、Session

1、面向对象基础

面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ 、__delitem__、__setitem__方法


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#!/usr/bin/env python

# -*- coding:utf-8 -*-

   

class Foo(object):

   

    def __getitem__(self, key):

        print  ‘__getitem__‘,key

   

    def __setitem__(self, key, value):

        print ‘__setitem__‘,key,value

   

    def __delitem__(self, key):

        print ‘__delitem__‘,key

   

   

   

obj = Foo()

result = obj[‘k1‘]

#obj[‘k2‘] = ‘wupeiqi‘

#del obj[‘k1‘]

2、Tornado扩展

Tornado框架中,默认执行Handler的get/post等方法之前默认会执行 initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作...

class BaseHandler(tornado.web.RequestHandler):

    def initialize(self):
        self.xxoo = "wupeiqi"

class MainHandler(BaseHandler):

    def get(self):
        print(self.xxoo)
        self.write(‘index‘)

class IndexHandler(BaseHandler):

    def get(self):
        print(self.xxoo)
        self.write(‘index‘)

3、session

session其实就是定义在服务器端用于保存用户回话的容器,其必须依赖cookie才能实现。

 自定义Session

4、分布式Session

 一致性哈西

 session

二、表单验证

在Web程序中往往包含大量的表单验证的工作,如:判断输入是否为空,是否符合规则。

 HTML

 Python

由于验证规则可以代码重用,所以可以如此定义:

 

 

分类: tornado源码系列python基础到高级

时间: 2024-08-26 17:08:37

Tornado的相关文章

微信小程序连接Tornado

自己搭建Tornado 监听8000端口, 提供给小程序访问的地址为http://127.0.0.1:8000/index #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): print('GET方式请求成功') self.write("123"

深入tornado中的IOStream

IOStream对tornado的高效起了很大的作用,他封装了socket的非阻塞IO的读写操作.大体上可以这么说,当连接建立后,服务端与客户端的请求响应都是基于IOStream的,也就是说:IOStream是用来处理连接的. 接下来说一下有关接收请求的大体流程: 当连接建立,服务器端会产生一个对应该连接的socket,同时将该socket封装至IOStream实例中(这代表着IOStream的初始化). 我们知道tornado是基于IO多路复用的(就拿epoll来说),此时将socket进行r

Tornado Web 框架

一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关有用工具及优化. Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以

Python框架之Tornado(二)请求阶段

概述 上图是tornado程序启动以及接收到客户端请求后的整个过程,对于整个过程可以分为两大部分: 启动程序阶段,又称为待请求阶段(上图1.2所有系列和3.0) 接收并处理客户端请求阶段(上图3系列) 简而言之: 1.在启动程序阶段,第一步,获取配置文件然后生成url映射(即:一个url对应一个XXRequestHandler,从而让XXRequestHandler来处理指定url发送的请求):第二步,创建服务器socket对象并添加到epoll中:第三步,创建无线循环去监听epoll. 2.在

tornado SSL3_READ_BYTES sslv3

////// ////// 支付宝回调,遇到问题 ////// WARNING:tornado.general:SSL Error on 9 ('110.75.248.125', 13675): [Errno 1] _ssl.c:504: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown ERROR:tornado.general:Uncaught exception Traceback (mo

tornado 资源

本章收集tornado(Python Web Framework)现有的资源 ##### introduction to tornado http://demo.pythoner.com/itt2zh/index.html document(tornadoweb) http://www.tornadoweb.org/en/stable/ http://www.tornadoweb.cn/documentation wiki(tornadoweb) https://github.com/torna

用 memcached 实现 Tornado 的 session 支持(一)

tornado 里面没有 session?不,当然有~我知道 github 上肯定有人帮我写好了~ O(∩_∩)O~ 于是乎,找到下面这个项目,用 memcached 实现 tornado 的 session.光会用可不行啊,让我们看看是怎么写的~ 项目地址:tornado-memcached-sessions 让我们先从 demo 看起.... app.py 中: 首先可以注意到,这里定义了一个新的 Application 类,继承于 tornado.web.Application, 在该类的

【从0开始Tornado建站】显示所有注册用户

显示注册用户的前台主要代码如下: {%block content%} <ul> {%for i in users%} <li><a href='/user/{{i[1]}}' class='text-success h4'>{{i[1]}}<small>({{i[3]}}星级)</small></a></li> {%end%} <br/> </ul> {%end%} 显示注册用户的后台代码如下: c

Tornado学习之异步原理

本文和大家分享的主要是Tornado 异步原理相关内容,一起来看看吧,希望对大家学习Tornado有所帮助. Tornado是什么? Tornado是一个用Python编写的异步HTTP服务器,同时也是一个web开发框架. Tornado 优秀的大并发处理能力得益于它的 web server 从底层开始就自己实现了一整套基于 epoll 的单线程异步架构. 同步.异步编程差异 .对于同步阻塞型Web服务器,我们来打个比方,将它比作一间饭馆,而Web请求就是来这家饭馆里吃饭的客人.假设饭馆店里只有

使用Tornado实现http代理

0x00 http代理 http代理的用处非常多,市面上也有公开的代理,可是有时候为了工作须要,比方分析应用层流量.做数据訪问控制.甚至做监控等等.Tornado提供了一些非常方便的环境和API,我们能够基于Tornado轻松实现一个http代理. 0x01 实现原理 http代理主要做client和web服务器之间的转发.这是大家都熟悉的场景,但仅仅限于http协议的情形.对于https的情况.这时候代理仅仅作为TCP中继进行信息中转,须要单独处理. 0x02 Tornado实现 基于Torn