├── .gitignore
├── LICENSE
├── README.md
└── src
├── readme.md
├── tornado-1.0.0
├── README.md
└── tornado
│ ├── __init__.py
│ ├── auth.py
│ ├── autoreload.py
│ ├── database.py
│ ├── epoll.c
│ ├── escape.py
│ ├── httpclient.py
│ ├── httpserver.py
│ ├── httputil.py
│ ├── ioloop.py
│ ├── iostream.py
│ ├── locale.py
│ ├── options.py
│ ├── s3server.py
│ ├── template.py
│ ├── test
│ ├── README
│ └── test_ioloop.py
│ ├── web.py
│ ├── win32_support.py
│ └── wsgi.py
├── tornado-3.2.2
├── demos
│ ├── appengine
│ │ ├── README
│ │ ├── app.yaml
│ │ ├── blog.py
│ │ ├── static
│ │ │ └── blog.css
│ │ └── templates
│ │ │ ├── archive.html
│ │ │ ├── base.html
│ │ │ ├── compose.html
│ │ │ ├── entry.html
│ │ │ ├── feed.xml
│ │ │ ├── home.html
│ │ │ └── modules
│ │ │ └── entry.html
│ ├── auth
│ │ └── authdemo.py
│ ├── benchmark
│ │ ├── benchmark.py
│ │ ├── chunk_benchmark.py
│ │ ├── stack_context_benchmark.py
│ │ └── template_benchmark.py
│ ├── blog
│ │ ├── README
│ │ ├── blog.py
│ │ ├── schema.sql
│ │ ├── static
│ │ │ └── blog.css
│ │ └── templates
│ │ │ ├── archive.html
│ │ │ ├── base.html
│ │ │ ├── compose.html
│ │ │ ├── entry.html
│ │ │ ├── feed.xml
│ │ │ ├── home.html
│ │ │ └── modules
│ │ │ └── entry.html
│ ├── chat
│ │ ├── chatdemo.py
│ │ ├── static
│ │ │ ├── chat.css
│ │ │ └── chat.js
│ │ └── templates
│ │ │ ├── index.html
│ │ │ └── message.html
│ ├── facebook
│ │ ├── README
│ │ ├── facebook.py
│ │ ├── static
│ │ │ ├── facebook.css
│ │ │ └── facebook.js
│ │ └── templates
│ │ │ ├── modules
│ │ │ └── post.html
│ │ │ └── stream.html
│ ├── helloworld
│ │ └── helloworld.py
│ ├── s3server
│ │ └── s3server.py
│ ├── twitter
│ │ ├── home.html
│ │ └── twitterdemo.py
│ └── websocket
│ │ ├── chatdemo.py
│ │ ├── static
│ │ ├── chat.css
│ │ └── chat.js
│ │ └── templates
│ │ ├── index.html
│ │ └── message.html
├── readme.md
└── tornado
│ ├── __init__.py
│ ├── auth.py
│ ├── autoreload.py
│ ├── ca-certificates.crt
│ ├── concurrent.py
│ ├── curl_httpclient.py
│ ├── escape.py
│ ├── gen.py
│ ├── httpclient.py
│ ├── httpserver.py
│ ├── httputil.py
│ ├── ioloop.py
│ ├── iostream.py
│ ├── locale.py
│ ├── log.py
│ ├── netutil.py
│ ├── options.py
│ ├── platform
│ ├── __init__.py
│ ├── asyncio.py
│ ├── auto.py
│ ├── caresresolver.py
│ ├── common.py
│ ├── epoll.py
│ ├── interface.py
│ ├── kqueue.py
│ ├── posix.py
│ ├── select.py
│ ├── twisted.py
│ └── windows.py
│ ├── process.py
│ ├── simple_httpclient.py
│ ├── speedups.c
│ ├── stack_context.py
│ ├── tcpserver.py
│ ├── template.py
│ ├── test
│ ├── README
│ ├── __init__.py
│ ├── auth_test.py
│ ├── concurrent_test.py
│ ├── csv_translations
│ │ └── fr_FR.csv
│ ├── curl_httpclient_test.py
│ ├── escape_test.py
│ ├── gen_test.py
│ ├── gettext_translations
│ │ ├── extract_me.py
│ │ └── fr_FR
│ │ │ └── LC_MESSAGES
│ │ │ └── tornado_test.po
│ ├── httpclient_test.py
│ ├── httpserver_test.py
│ ├── httputil_test.py
│ ├── import_test.py
│ ├── ioloop_test.py
│ ├── iostream_test.py
│ ├── locale_test.py
│ ├── log_test.py
│ ├── netutil_test.py
│ ├── options_test.cfg
│ ├── options_test.py
│ ├── process_test.py
│ ├── resolve_test_helper.py
│ ├── runtests.py
│ ├── simple_httpclient_test.py
│ ├── stack_context_test.py
│ ├── static
│ │ ├── dir
│ │ │ └── index.html
│ │ └── robots.txt
│ ├── template_test.py
│ ├── templates
│ │ └── utf8.html
│ ├── test.crt
│ ├── test.key
│ ├── testing_test.py
│ ├── twisted_test.py
│ ├── util.py
│ ├── util_test.py
│ ├── web_test.py
│ ├── websocket_test.py
│ └── wsgi_test.py
│ ├── testing.py
│ ├── util.py
│ ├── web.py
│ ├── websocket.py
│ └── wsgi.py
└── tornado-4.2.0
├── .coveragerc
├── .travis.yml
├── LICENSE
├── MANIFEST.in
├── README.rst
├── demos
├── appengine
│ ├── README
│ ├── app.yaml
│ ├── blog.py
│ ├── static
│ │ └── blog.css
│ └── templates
│ │ ├── archive.html
│ │ ├── base.html
│ │ ├── compose.html
│ │ ├── entry.html
│ │ ├── feed.xml
│ │ ├── home.html
│ │ └── modules
│ │ └── entry.html
├── benchmark
│ ├── benchmark.py
│ ├── chunk_benchmark.py
│ ├── gen_benchmark.py
│ ├── stack_context_benchmark.py
│ └── template_benchmark.py
├── blog
│ ├── Dockerfile
│ ├── README
│ ├── blog.py
│ ├── docker-compose.yml
│ ├── requirements.txt
│ ├── schema.sql
│ ├── static
│ │ └── blog.css
│ └── templates
│ │ ├── archive.html
│ │ ├── base.html
│ │ ├── compose.html
│ │ ├── create_author.html
│ │ ├── entry.html
│ │ ├── feed.xml
│ │ ├── home.html
│ │ ├── login.html
│ │ └── modules
│ │ └── entry.html
├── chat
│ ├── chatdemo.py
│ ├── static
│ │ ├── chat.css
│ │ └── chat.js
│ └── templates
│ │ ├── index.html
│ │ └── message.html
├── facebook
│ ├── README
│ ├── facebook.py
│ ├── static
│ │ ├── facebook.css
│ │ └── facebook.js
│ └── templates
│ │ ├── modules
│ │ └── post.html
│ │ └── stream.html
├── helloworld
│ └── helloworld.py
├── s3server
│ └── s3server.py
├── twitter
│ ├── home.html
│ └── twitterdemo.py
├── websocket
│ ├── chatdemo.py
│ ├── static
│ │ ├── chat.css
│ │ └── chat.js
│ └── templates
│ │ ├── index.html
│ │ └── message.html
└── webspider
│ └── webspider.py
├── maint
├── README
├── requirements.txt
├── scripts
│ ├── custom_fixers
│ │ ├── __init__.py
│ │ ├── fix_future_imports.py
│ │ └── fix_unicode_literal.py
│ ├── run_autopep8.sh
│ ├── run_fixers.py
│ └── test_resolvers.py
├── test
│ ├── README
│ ├── appengine
│ │ ├── README
│ │ ├── common
│ │ │ ├── cgi_runtests.py
│ │ │ └── runtests.py
│ │ ├── py27
│ │ │ ├── app.yaml
│ │ │ ├── cgi_runtests.py
│ │ │ ├── runtests.py
│ │ │ └── tornado
│ │ ├── setup.py
│ │ └── tox.ini
│ ├── pyuv
│ │ └── tox.ini
│ ├── redbot
│ │ ├── README
│ │ ├── red_test.py
│ │ └── tox.ini
│ └── websocket
│ │ ├── .gitignore
│ │ ├── client.py
│ │ ├── fuzzingclient.json
│ │ ├── fuzzingserver.json
│ │ ├── run-client.sh
│ │ ├── run-server.sh
│ │ ├── server.py
│ │ └── tox.ini
└── vm
│ ├── README
│ ├── freebsd
│ ├── Vagrantfile
│ ├── setup.sh
│ └── tox.ini
│ ├── shared-setup.sh
│ ├── ubuntu10.04
│ ├── Vagrantfile
│ ├── setup.sh
│ └── tox.ini
│ ├── ubuntu12.04
│ ├── Vagrantfile
│ ├── setup.sh
│ └── tox.ini
│ ├── ubuntu14.04
│ ├── Vagrantfile
│ ├── setup.sh
│ └── tox.ini
│ └── windows
│ ├── bootstrap.py
│ └── tox.ini
├── runtests.sh
├── setup.py
├── tornado
├── __init__.py
├── auth.py
├── autoreload.py
├── concurrent.py
├── curl_httpclient.py
├── escape.py
├── gen.py
├── http1connection.py
├── httpclient.py
├── httpserver.py
├── httputil.py
├── ioloop.py
├── iostream.py
├── locale.py
├── locks.py
├── log.py
├── netutil.py
├── options.py
├── platform
│ ├── __init__.py
│ ├── asyncio.py
│ ├── auto.py
│ ├── caresresolver.py
│ ├── common.py
│ ├── epoll.py
│ ├── interface.py
│ ├── kqueue.py
│ ├── posix.py
│ ├── select.py
│ ├── twisted.py
│ └── windows.py
├── process.py
├── queues.py
├── simple_httpclient.py
├── speedups.c
├── stack_context.py
├── tcpclient.py
├── tcpserver.py
├── template.py
├── test
│ ├── __init__.py
│ ├── __main__.py
│ ├── asyncio_test.py
│ ├── auth_test.py
│ ├── concurrent_test.py
│ ├── csv_translations
│ │ └── fr_FR.csv
│ ├── curl_httpclient_test.py
│ ├── escape_test.py
│ ├── gen_test.py
│ ├── gettext_translations
│ │ ├── extract_me.py
│ │ └── fr_FR
│ │ │ └── LC_MESSAGES
│ │ │ └── tornado_test.po
│ ├── httpclient_test.py
│ ├── httpserver_test.py
│ ├── httputil_test.py
│ ├── import_test.py
│ ├── ioloop_test.py
│ ├── iostream_test.py
│ ├── locale_test.py
│ ├── locks_test.py
│ ├── log_test.py
│ ├── netutil_test.py
│ ├── options_test.cfg
│ ├── options_test.py
│ ├── process_test.py
│ ├── queues_test.py
│ ├── resolve_test_helper.py
│ ├── runtests.py
│ ├── simple_httpclient_test.py
│ ├── stack_context_test.py
│ ├── static
│ │ ├── dir
│ │ │ └── index.html
│ │ └── robots.txt
│ ├── tcpclient_test.py
│ ├── tcpserver_test.py
│ ├── template_test.py
│ ├── templates
│ │ └── utf8.html
│ ├── test.crt
│ ├── test.key
│ ├── testing_test.py
│ ├── twisted_test.py
│ ├── util.py
│ ├── util_test.py
│ ├── web_test.py
│ ├── websocket_test.py
│ └── wsgi_test.py
├── testing.py
├── util.py
├── web.py
├── websocket.py
└── wsgi.py
└── tox.ini
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *,cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 |
55 | # Sphinx documentation
56 | docs/_build/
57 |
58 | # PyBuilder
59 | target/
60 |
61 |
62 | *.pyc
63 | *~
64 | build
65 | tornado.egg-info
66 |
67 |
68 | *.pyo
69 | *.class
70 | /dist/
71 | MANIFEST
72 | /tornado.egg-info/
73 | .vagrant
74 | /.coverage
75 | /htmlcov/
76 | /env/
77 | # Used in demo apps
78 | secrets.cfg
79 |
80 | # add 2016
81 | .idea/
82 | .DS_Store
83 |
84 | src/tornado-4.2.0/docs/
85 | tmp/
86 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 hhstore
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tornado-annotated
2 |
3 | - tornado 源码 注解
4 |
5 | ## 1. 项目说明:
6 |
7 | 1. 对 tornado 框架 源码,添加学习注释
8 | 2. 目前选择的版本:
9 | - 1.0.0 这是 tornado 的第一版,代码应该是最简洁的
10 | - 4.2.1 简单对github 上 使用 tornado 框架的 版本,进行初步统计,发现使用该版本的项目最多.
11 | - 故不再选择 2.x, 3.x 的版本 学习注解
12 |
13 |
14 | ## 2. 本项目结构:
15 |
16 | - 会包含tornado框架的结构剖析.
17 | - 包括 思维导图等工具制作的笔记
18 | - 参考阅读文档
19 | - tornado 核心模块源码重点剖析
20 |
21 |
22 |
23 | ## 3. tornado 源码版本:
24 |
25 |
26 | - [releases](https://github.com/tornadoweb/tornado/releases)
27 | - 版本规律:
28 | - v1.x, v2.x, v3.x, v4.x, 当大版本更新时, 代码增长量, 比较多
29 | - v1.x 的 小版本更新时, 通常是修复 bug, 代码增长量, 比较少.
30 | - 选择阅读版本技巧:
31 | - 选定 某个大版本号, 如 v2.1
32 | - 选择该大版本号号下, 最后一个小版本, 如 v2.1.10
33 |
34 |
35 | ## 4. 各版本代码统计对比:
36 |
37 | - [v1.0.0](https://github.com/tornadoweb/tornado/releases/tag/v1.0.0):
38 | - 代码行数: 6207 (少量测试代码,忽略)
39 | - date: on 23 Jul 2010
40 | - 阅读指数: ✖✖✖✖ (版本过老, 不推荐)
41 | - [v2.1.0](https://github.com/tornadoweb/tornado/releases/tag/v2.1.0):
42 | - 代码行数: 9981 (含 gen.py 模块)
43 | - date: on 21 Sep 2011
44 | - 阅读指数: ✖✖✖✖ (不推荐)
45 | - 对比 v2.1.1, 无优势
46 | - [v2.1.1](https://github.com/tornadoweb/tornado/releases/tag/v2.1.1):
47 | - 代码行数: 12720 - 2721(测试代码) = 9999
48 | - date: on 5 Oct 2011
49 | - 阅读指数: ✖✖✖✖ (不推荐)
50 | - 对比 v2.2.0, 无优势
51 | - [v2.2.0](https://github.com/tornadoweb/tornado/releases/tag/v2.2.0):
52 | - 代码行数: 13654 - 3202(测试代码) = 10453
53 | - date: on 31 Jan 2012
54 | - 阅读指数: ✔✔ (可选)
55 | - [v2.4.1](https://github.com/tornadoweb/tornado/releases/tag/v2.4.1):
56 | - 代码行数: 15174 - 4145(测试代码) = 11029
57 | - date: on 25 Nov 2012
58 | - 阅读指数: ✔✔✔ (可选)
59 | - [v3.1.0](https://github.com/tornadoweb/tornado/releases/tag/v3.1.0):
60 | - 代码行数: 21242 - 7377(测试代码) = 13865
61 | - date: on 16 Jun 2013
62 | - 阅读指数: ✖✖✖✖ (不推荐)
63 | - 对比 v3.2.0, 无优势
64 | - [v3.2.0](https://github.com/tornadoweb/tornado/releases/tag/v3.2.0):
65 | - 代码行数: 22222 - 7873(测试代码) = 14349
66 | - 重大更新: 修改了很多文件
67 | - date: on 14 Jan 2014
68 | - 阅读指数: ✖✖✖✖ (不推荐)
69 | - 对比 v3.2.2, 无优势
70 | - [v3.2.2](https://github.com/tornadoweb/tornado/releases/tag/v3.2.2):
71 | - 代码行数: 22680 - 8107(测试代码) = `14573`
72 | - date: [on 4 Jun 2014]()
73 | - 阅读指数: ✔✔✔✔ (较推荐)
74 | - 本版本为 3.x 最后一个版本
75 | - 本版本 docs 可知有 python 3.4 测试
76 | - 包含 asyncio 模块: tornado.platform.asyncio
77 | - [asyncio 参考](http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090954004980bd351f2cd4cc18c9e6c06d855c498000)
78 | - asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持
79 | - asyncio的编程模型就是一个消息循环
80 | - 下一版本为 4.x 系列
81 | - 交叉时间对比:
82 | - `python 3.4.1 final`: [May 18, 2014](https://www.python.org/dev/peps/pep-0429/#id1)
83 | - `python 3.4.4 final`: [December 20, 2015](https://www.python.org/dev/peps/pep-0429/#id3)
84 | - v4.2.0:
85 | - 代码行数: 29851 - 12027(测试代码) = 17824
86 |
87 |
--------------------------------------------------------------------------------
/src/tornado-1.0.0/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## 1.0.0 注解备忘:
5 |
6 |
7 | - 此版本的代码,是python2.x的, 当在pycharm中阅读时,项目环境不要设置成python3.
8 | - 为方便阅读, 删除了 批注源码文件 的 LICENSE 说明, 请注意尊重版权.
9 | - 项目原有模块,函数的英文注释,根据需要,会作中文翻译.
10 | - 本版本 tornado 主体框架 Python 代码行数: `6023` (含注释)
11 | - 代码量,比想象中的少,很精简,很有必要花时间精读一下
12 | - 剔除 Demo 示例代码
13 | - 本版本 单元测试代码,忽略不计
14 | - 统计代码行数命令: find . -name "*.py" | xargs grep -v "^$" | wc -l
15 |
16 |
17 | - 阅读入口:
18 | - tornado/web.py
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ---
29 |
30 |
31 |
32 | # 原项目 Readme 说明:
33 |
34 | Tornado
35 | =======
36 | Tornado is an open source version of the scalable, non-blocking web server
37 | and and tools that power FriendFeed. Documentation and downloads are
38 | available at http://www.tornadoweb.org/
39 |
40 | Tornado is licensed under the Apache Licence, Version 2.0
41 | (http://www.apache.org/licenses/LICENSE-2.0.html).
42 |
43 | Installation
44 | ============
45 | To install:
46 |
47 | python setup.py build
48 | sudo python setup.py install
49 |
50 | Tornado has been tested on Python 2.5 and 2.6. To use all of the features
51 | of Tornado, you need to have PycURL and a JSON library like simplejson
52 | installed.
53 |
54 | On Mac OS X, you can install the packages with:
55 |
56 | sudo easy_install setuptools pycurl==7.16.2.1 simplejson
57 |
58 | On Ubuntu Linux, you can install the packages with:
59 |
60 | sudo apt-get install python-pycurl python-simplejson
61 |
--------------------------------------------------------------------------------
/src/tornado-1.0.0/tornado/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2009 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """The Tornado web server and tools."""
18 |
--------------------------------------------------------------------------------
/src/tornado-1.0.0/tornado/test/README:
--------------------------------------------------------------------------------
1 | Test coverage is almost non-existent, but it's a start. Be sure to
2 | set PYTHONPATH apprioriately (generally to the root directory of your
3 | tornado checkout) when running tests to make sure you're getting the
4 | version of the tornado package that you expect.
--------------------------------------------------------------------------------
/src/tornado-1.0.0/tornado/test/test_ioloop.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import unittest
4 | import time
5 |
6 | from tornado import ioloop
7 |
8 |
9 | class TestIOLoop(unittest.TestCase):
10 | def setUp(self):
11 | self.loop = ioloop.IOLoop()
12 |
13 | def tearDown(self):
14 | pass
15 |
16 | def _callback(self):
17 | self.called = True
18 | self.loop.stop()
19 |
20 | def _schedule_callback(self):
21 | self.loop.add_callback(self._callback)
22 | # Scroll away the time so we can check if we woke up immediately
23 | self._start_time = time.time()
24 | self.called = False
25 |
26 | def test_add_callback(self):
27 | self.loop.add_timeout(time.time(), self._schedule_callback)
28 | self.loop.start() # Set some long poll timeout so we can check wakeup
29 | self.assertAlmostEqual(time.time(), self._start_time, places=2)
30 | self.assertTrue(self.called)
31 |
32 |
33 | if __name__ == "__main__":
34 | import logging
35 |
36 | logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:%(msecs)03d %(levelname)-8s %(name)-8s %(message)s', datefmt='%H:%M:%S')
37 |
38 | unittest.main()
39 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/README:
--------------------------------------------------------------------------------
1 | Running the Tornado AppEngine example
2 | =====================================
3 | This example is designed to run in Google AppEngine, so there are a couple
4 | of steps to get it running. You can download the Google AppEngine Python
5 | development environment at http://code.google.com/appengine/downloads.html.
6 |
7 | 1. Link or copy the tornado code directory into this directory:
8 |
9 | ln -s ../../tornado tornado
10 |
11 | AppEngine doesn't use the Python modules installed on this machine.
12 | You need to have the 'tornado' module copied or linked for AppEngine
13 | to find it.
14 |
15 | 3. Install and run dev_appserver
16 |
17 | If you don't already have the App Engine SDK, download it from
18 | http://code.google.com/appengine/downloads.html
19 |
20 | To start the tornado demo, run the dev server on this directory:
21 |
22 | dev_appserver.py .
23 |
24 | 4. Visit http://localhost:8080/ in your browser
25 |
26 | If you sign in as an administrator, you will be able to create and
27 | edit blog posts. If you sign in as anybody else, you will only see
28 | the existing blog posts.
29 |
30 |
31 | If you want to deploy the blog in production:
32 |
33 | 1. Register a new appengine application and put its id in app.yaml
34 |
35 | First register a new application at http://appengine.google.com/.
36 | Then edit app.yaml in this directory and change the "application"
37 | setting from "tornado-appenginge" to your new application id.
38 |
39 | 2. Deploy to App Engine
40 |
41 | If you registered an application id, you can now upload your new
42 | Tornado blog by running this command:
43 |
44 | appcfg update .
45 |
46 | After that, visit application_id.appspot.com, where application_id
47 | is the application you registered.
48 |
49 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/app.yaml:
--------------------------------------------------------------------------------
1 | application: tornado-appengine
2 | version: 2
3 | runtime: python27
4 | api_version: 1
5 | threadsafe: yes
6 |
7 | handlers:
8 | - url: /static/
9 | static_dir: static
10 |
11 | - url: /.*
12 | script: blog.application
13 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/static/blog.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Facebook
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | color: black;
20 | margin: 15px;
21 | margin-top: 0;
22 | }
23 |
24 | body,
25 | input,
26 | textarea {
27 | font-family: Georgia, serif;
28 | font-size: 12pt;
29 | }
30 |
31 | table {
32 | border-collapse: collapse;
33 | border: 0;
34 | }
35 |
36 | td {
37 | border: 0;
38 | padding: 0;
39 | }
40 |
41 | h1,
42 | h2,
43 | h3,
44 | h4 {
45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
46 | margin: 0;
47 | }
48 |
49 | h1 {
50 | font-size: 20pt;
51 | }
52 |
53 | pre,
54 | code {
55 | font-family: monospace;
56 | color: #060;
57 | }
58 |
59 | pre {
60 | margin-left: 1em;
61 | padding-left: 1em;
62 | border-left: 1px solid silver;
63 | line-height: 14pt;
64 | }
65 |
66 | a,
67 | a code {
68 | color: #00c;
69 | }
70 |
71 | #body {
72 | max-width: 800px;
73 | margin: auto;
74 | }
75 |
76 | #header {
77 | background-color: #3b5998;
78 | padding: 5px;
79 | padding-left: 10px;
80 | padding-right: 10px;
81 | margin-bottom: 1em;
82 | }
83 |
84 | #header,
85 | #header a {
86 | color: white;
87 | }
88 |
89 | #header h1 a {
90 | text-decoration: none;
91 | }
92 |
93 | #footer,
94 | #content {
95 | margin-left: 10px;
96 | margin-right: 10px;
97 | }
98 |
99 | #footer {
100 | margin-top: 3em;
101 | }
102 |
103 | .entry h1 a {
104 | color: black;
105 | text-decoration: none;
106 | }
107 |
108 | .entry {
109 | margin-bottom: 2em;
110 | }
111 |
112 | .entry .date {
113 | margin-top: 3px;
114 | }
115 |
116 | .entry p {
117 | margin: 0;
118 | margin-bottom: 1em;
119 | }
120 |
121 | .entry .body {
122 | margin-top: 1em;
123 | line-height: 16pt;
124 | }
125 |
126 | .compose td {
127 | vertical-align: middle;
128 | padding-bottom: 5px;
129 | }
130 |
131 | .compose td.field {
132 | padding-right: 10px;
133 | }
134 |
135 | .compose .title,
136 | .compose .submit {
137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
138 | font-weight: bold;
139 | }
140 |
141 | .compose .title {
142 | font-size: 20pt;
143 | }
144 |
145 | .compose .title,
146 | .compose .body_source {
147 | width: 100%;
148 | }
149 |
150 | .compose .body_source {
151 | height: 500px;
152 | line-height: 16pt;
153 | }
154 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/archive.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
20 | {% end %}
21 |
22 | {% block body %}
23 |
31 | {% end %}
32 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ handler.settings["blog_title"] }}
6 |
7 |
8 | {% block head %}{% end %}
9 |
10 |
11 |
12 |
25 |
{% block body %}{% end %}
26 |
27 | {% block bottom %}{% end %}
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/compose.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 |
16 | {% end %}
17 |
18 | {% block bottom %}
19 |
20 |
40 | {% end %}
41 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/entry.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% module Entry(entry) %}
5 | {% end %}
6 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %}
4 | {{ handler.settings["blog_title"] }}
5 | {% if len(entries) > 0 %}
6 | {{ max(e.updated for e in entries).strftime(date_format) }}
7 | {% else %}
8 | {{ datetime.datetime.utcnow().strftime(date_format) }}
9 | {% end %}
10 | http://{{ request.host }}/
11 |
12 |
13 | {{ handler.settings["blog_title"] }}
14 | {% for entry in entries %}
15 |
16 | http://{{ request.host }}/entry/{{ entry.slug }}
17 | {{ entry.title }}
18 |
19 | {{ entry.updated.strftime(date_format) }}
20 | {{ entry.published.strftime(date_format) }}
21 |
22 | {% raw entry.html %}
23 |
24 |
25 | {% end %}
26 |
27 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% for entry in entries %}
5 | {% module Entry(entry) %}
6 | {% end %}
7 |
8 | {% end %}
9 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/appengine/templates/modules/entry.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user and current_user.administrator %}
6 |
7 | {% end %}
8 |
9 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/auth/authdemo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2009 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | import tornado.auth
18 | import tornado.escape
19 | import tornado.httpserver
20 | import tornado.ioloop
21 | import tornado.web
22 |
23 | from tornado import gen
24 | from tornado.options import define, options, parse_command_line
25 |
26 | define("port", default=8888, help="run on the given port", type=int)
27 |
28 |
29 | class Application(tornado.web.Application):
30 | def __init__(self):
31 | handlers = [
32 | (r"/", MainHandler),
33 | (r"/auth/login", AuthHandler),
34 | (r"/auth/logout", LogoutHandler),
35 | ]
36 | settings = dict(
37 | cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
38 | login_url="/auth/login",
39 | )
40 | tornado.web.Application.__init__(self, handlers, **settings)
41 |
42 |
43 | class BaseHandler(tornado.web.RequestHandler):
44 | def get_current_user(self):
45 | user_json = self.get_secure_cookie("authdemo_user")
46 | if not user_json: return None
47 | return tornado.escape.json_decode(user_json)
48 |
49 |
50 | class MainHandler(BaseHandler):
51 | @tornado.web.authenticated
52 | def get(self):
53 | name = tornado.escape.xhtml_escape(self.current_user["name"])
54 | self.write("Hello, " + name)
55 | self.write("Log out ")
56 |
57 |
58 | class AuthHandler(BaseHandler, tornado.auth.GoogleMixin):
59 | @gen.coroutine
60 | def get(self):
61 | if self.get_argument("openid.mode", None):
62 | user = yield self.get_authenticated_user()
63 | self.set_secure_cookie("authdemo_user",
64 | tornado.escape.json_encode(user))
65 | self.redirect("/")
66 | return
67 | self.authenticate_redirect()
68 |
69 |
70 | class LogoutHandler(BaseHandler):
71 | def get(self):
72 | # This logs the user out of this demo app, but does not log them
73 | # out of Google. Since Google remembers previous authorizations,
74 | # returning to this app will log them back in immediately with no
75 | # interaction (unless they have separately logged out of Google in
76 | # the meantime).
77 | self.clear_cookie("authdemo_user")
78 | self.write('You are now logged out. '
79 | 'Click here to log back in.')
80 |
81 | def main():
82 | parse_command_line()
83 | http_server = tornado.httpserver.HTTPServer(Application())
84 | http_server.listen(options.port)
85 | tornado.ioloop.IOLoop.instance().start()
86 |
87 |
88 | if __name__ == "__main__":
89 | main()
90 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/benchmark/benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # A simple benchmark of tornado's HTTP stack.
4 | # Requires 'ab' to be installed.
5 | #
6 | # Running without profiling:
7 | # demos/benchmark/benchmark.py
8 | # demos/benchmark/benchmark.py --quiet --num_runs=5|grep "Requests per second"
9 | #
10 | # Running with profiling:
11 | #
12 | # python -m cProfile -o /tmp/prof demos/benchmark/benchmark.py
13 | # python -m pstats /tmp/prof
14 | # % sort time
15 | # % stats 20
16 |
17 | from tornado.ioloop import IOLoop
18 | from tornado.options import define, options, parse_command_line
19 | from tornado.web import RequestHandler, Application
20 |
21 | import random
22 | import signal
23 | import subprocess
24 |
25 | # choose a random port to avoid colliding with TIME_WAIT sockets left over
26 | # from previous runs.
27 | define("min_port", type=int, default=8000)
28 | define("max_port", type=int, default=9000)
29 |
30 | # Increasing --n without --keepalive will eventually run into problems
31 | # due to TIME_WAIT sockets
32 | define("n", type=int, default=15000)
33 | define("c", type=int, default=25)
34 | define("keepalive", type=bool, default=False)
35 | define("quiet", type=bool, default=False)
36 |
37 | # Repeat the entire benchmark this many times (on different ports)
38 | # This gives JITs time to warm up, etc. Pypy needs 3-5 runs at
39 | # --n=15000 for its JIT to reach full effectiveness
40 | define("num_runs", type=int, default=1)
41 |
42 | define("ioloop", type=str, default=None)
43 |
44 | class RootHandler(RequestHandler):
45 | def get(self):
46 | self.write("Hello, world")
47 |
48 | def _log(self):
49 | pass
50 |
51 | def handle_sigchld(sig, frame):
52 | IOLoop.instance().add_callback(IOLoop.instance().stop)
53 |
54 | def main():
55 | parse_command_line()
56 | if options.ioloop:
57 | IOLoop.configure(options.ioloop)
58 | for i in xrange(options.num_runs):
59 | run()
60 |
61 | def run():
62 | app = Application([("/", RootHandler)])
63 | port = random.randrange(options.min_port, options.max_port)
64 | app.listen(port, address='127.0.0.1')
65 | signal.signal(signal.SIGCHLD, handle_sigchld)
66 | args = ["ab"]
67 | args.extend(["-n", str(options.n)])
68 | args.extend(["-c", str(options.c)])
69 | if options.keepalive:
70 | args.append("-k")
71 | if options.quiet:
72 | # just stops the progress messages printed to stderr
73 | args.append("-q")
74 | args.append("http://127.0.0.1:%d/" % port)
75 | subprocess.Popen(args)
76 | IOLoop.instance().start()
77 | IOLoop.instance().close()
78 | del IOLoop._instance
79 | assert not IOLoop.initialized()
80 |
81 | if __name__ == '__main__':
82 | main()
83 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/benchmark/chunk_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Downloads a large file in chunked encoding with both curl and simple clients
4 |
5 | import logging
6 | from tornado.curl_httpclient import CurlAsyncHTTPClient
7 | from tornado.simple_httpclient import SimpleAsyncHTTPClient
8 | from tornado.ioloop import IOLoop
9 | from tornado.options import define, options, parse_command_line
10 | from tornado.web import RequestHandler, Application
11 |
12 | define('port', default=8888)
13 | define('num_chunks', default=1000)
14 | define('chunk_size', default=2048)
15 |
16 | class ChunkHandler(RequestHandler):
17 | def get(self):
18 | for i in xrange(options.num_chunks):
19 | self.write('A' * options.chunk_size)
20 | self.flush()
21 | self.finish()
22 |
23 | def main():
24 | parse_command_line()
25 | app = Application([('/', ChunkHandler)])
26 | app.listen(options.port, address='127.0.0.1')
27 | def callback(response):
28 | response.rethrow()
29 | assert len(response.body) == (options.num_chunks * options.chunk_size)
30 | logging.warning("fetch completed in %s seconds", response.request_time)
31 | IOLoop.instance().stop()
32 |
33 | logging.warning("Starting fetch with curl client")
34 | curl_client = CurlAsyncHTTPClient()
35 | curl_client.fetch('http://localhost:%d/' % options.port,
36 | callback=callback)
37 | IOLoop.instance().start()
38 |
39 | logging.warning("Starting fetch with simple client")
40 | simple_client = SimpleAsyncHTTPClient()
41 | simple_client.fetch('http://localhost:%d/' % options.port,
42 | callback=callback)
43 | IOLoop.instance().start()
44 |
45 |
46 | if __name__ == '__main__':
47 | main()
48 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/benchmark/stack_context_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Benchmark for stack_context functionality."""
3 | import collections
4 | import contextlib
5 | import functools
6 | import subprocess
7 | import sys
8 |
9 | from tornado import stack_context
10 |
11 | class Benchmark(object):
12 | def enter_exit(self, count):
13 | """Measures the overhead of the nested "with" statements
14 | when using many contexts.
15 | """
16 | if count < 0:
17 | return
18 | with self.make_context():
19 | self.enter_exit(count - 1)
20 |
21 | def call_wrapped(self, count):
22 | """Wraps and calls a function at each level of stack depth
23 | to measure the overhead of the wrapped function.
24 | """
25 | # This queue is analogous to IOLoop.add_callback, but lets us
26 | # benchmark the stack_context in isolation without system call
27 | # overhead.
28 | queue = collections.deque()
29 | self.call_wrapped_inner(queue, count)
30 | while queue:
31 | queue.popleft()()
32 |
33 | def call_wrapped_inner(self, queue, count):
34 | if count < 0:
35 | return
36 | with self.make_context():
37 | queue.append(stack_context.wrap(
38 | functools.partial(self.call_wrapped_inner, queue, count - 1)))
39 |
40 | class StackBenchmark(Benchmark):
41 | def make_context(self):
42 | return stack_context.StackContext(self.__context)
43 |
44 | @contextlib.contextmanager
45 | def __context(self):
46 | yield
47 |
48 | class ExceptionBenchmark(Benchmark):
49 | def make_context(self):
50 | return stack_context.ExceptionStackContext(self.__handle_exception)
51 |
52 | def __handle_exception(self, typ, value, tb):
53 | pass
54 |
55 | def main():
56 | base_cmd = [
57 | sys.executable, '-m', 'timeit', '-s',
58 | 'from stack_context_benchmark import StackBenchmark, ExceptionBenchmark']
59 | cmds = [
60 | 'StackBenchmark().enter_exit(50)',
61 | 'StackBenchmark().call_wrapped(50)',
62 | 'StackBenchmark().enter_exit(500)',
63 | 'StackBenchmark().call_wrapped(500)',
64 |
65 | 'ExceptionBenchmark().enter_exit(50)',
66 | 'ExceptionBenchmark().call_wrapped(50)',
67 | 'ExceptionBenchmark().enter_exit(500)',
68 | 'ExceptionBenchmark().call_wrapped(500)',
69 | ]
70 | for cmd in cmds:
71 | print cmd
72 | subprocess.check_call(base_cmd + [cmd])
73 |
74 | if __name__ == '__main__':
75 | main()
76 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/benchmark/template_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # A simple benchmark of tornado template rendering, based on
4 | # https://github.com/mitsuhiko/jinja2/blob/master/examples/bench.py
5 |
6 | import sys
7 | from timeit import Timer
8 |
9 | from tornado.options import options, define, parse_command_line
10 | from tornado.template import Template
11 |
12 | define('num', default=100, help='number of iterations')
13 | define('dump', default=False, help='print template generated code and exit')
14 |
15 | context = {
16 | 'page_title': 'mitsuhiko\'s benchmark',
17 | 'table': [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) for x in range(1000)]
18 | }
19 |
20 | tmpl = Template("""\
21 |
22 |
23 |
24 | {{ page_title }}
25 |
26 |
27 |
30 |
31 | {% for href, caption in [ \
32 | ('index.html', 'Index'), \
33 | ('downloads.html', 'Downloads'), \
34 | ('products.html', 'Products') \
35 | ] %}
36 | {{ caption }}
37 | {% end %}
38 |
39 |
40 |
41 | {% for row in table %}
42 |
43 | {% for cell in row %}
44 | {{ cell }}
45 | {% end %}
46 |
47 | {% end %}
48 |
49 |
50 |
51 | \
52 | """)
53 |
54 | def render():
55 | tmpl.generate(**context)
56 |
57 | def main():
58 | parse_command_line()
59 | if options.dump:
60 | print tmpl.code
61 | sys.exit(0)
62 | t = Timer(render)
63 | results = t.timeit(options.num) / options.num
64 | print '%0.3f ms per iteration' % (results*1000)
65 |
66 | if __name__ == '__main__':
67 | main()
68 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/README:
--------------------------------------------------------------------------------
1 | Running the Tornado Blog example app
2 | ====================================
3 | This demo is a simple blogging engine that uses MySQL to store posts and
4 | Google Accounts for author authentication. Since it depends on MySQL, you
5 | need to set up MySQL and the database schema for the demo to run.
6 |
7 | 1. Install prerequisites and build tornado
8 |
9 | See http://www.tornadoweb.org/ for installation instructions. If you can
10 | run the "helloworld" example application, your environment is set up
11 | correctly.
12 |
13 | 2. Install MySQL if needed
14 |
15 | Consult the documentation for your platform. Under Ubuntu Linux you
16 | can run "apt-get install mysql". Under OS X you can download the
17 | MySQL PKG file from http://dev.mysql.com/downloads/mysql/
18 |
19 | 3. Install Python prerequisites
20 |
21 | Install the packages MySQL-python, torndb, and markdown (e.g. using pip or
22 | easy_install)
23 |
24 | 3. Connect to MySQL and create a database and user for the blog.
25 |
26 | Connect to MySQL as a user that can create databases and users:
27 | mysql -u root
28 |
29 | Create a database named "blog":
30 | mysql> CREATE DATABASE blog;
31 |
32 | Allow the "blog" user to connect with the password "blog":
33 | mysql> GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog';
34 |
35 | 4. Create the tables in your new database.
36 |
37 | You can use the provided schema.sql file by running this command:
38 | mysql --user=blog --password=blog --database=blog < schema.sql
39 |
40 | You can run the above command again later if you want to delete the
41 | contents of the blog and start over after testing.
42 |
43 | 5. Run the blog example
44 |
45 | With the default user, password, and database you can just run:
46 | ./blog.py
47 |
48 | If you've changed anything, you can alter the default MySQL settings
49 | with arguments on the command line, e.g.:
50 | ./blog.py --mysql_user=casey --mysql_password=happiness --mysql_database=foodblog
51 |
52 | 6. Visit your new blog
53 |
54 | Open http://localhost:8888/ in your web browser. You will be redirected to
55 | a Google account sign-in page because the blog uses Google accounts for
56 | authentication.
57 |
58 | Currently the first user to connect will automatically be given the
59 | ability to create and edit posts.
60 |
61 | Once you've created one blog post, subsequent users will not be
62 | prompted to sign in.
63 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/schema.sql:
--------------------------------------------------------------------------------
1 | -- Copyright 2009 FriendFeed
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | -- not use this file except in compliance with the License. You may obtain
5 | -- a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | -- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | -- License for the specific language governing permissions and limitations
13 | -- under the License.
14 |
15 | -- To create the database:
16 | -- CREATE DATABASE blog;
17 | -- GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog';
18 | --
19 | -- To reload the tables:
20 | -- mysql --user=blog --password=blog --database=blog < schema.sql
21 |
22 | SET SESSION storage_engine = "InnoDB";
23 | SET SESSION time_zone = "+0:00";
24 | ALTER DATABASE CHARACTER SET "utf8";
25 |
26 | DROP TABLE IF EXISTS entries;
27 | CREATE TABLE entries (
28 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
29 | author_id INT NOT NULL REFERENCES authors(id),
30 | slug VARCHAR(100) NOT NULL UNIQUE,
31 | title VARCHAR(512) NOT NULL,
32 | markdown MEDIUMTEXT NOT NULL,
33 | html MEDIUMTEXT NOT NULL,
34 | published DATETIME NOT NULL,
35 | updated TIMESTAMP NOT NULL,
36 | KEY (published)
37 | );
38 |
39 | DROP TABLE IF EXISTS authors;
40 | CREATE TABLE authors (
41 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
42 | email VARCHAR(100) NOT NULL UNIQUE,
43 | name VARCHAR(100) NOT NULL
44 | );
45 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/static/blog.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Facebook
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | color: black;
20 | margin: 15px;
21 | margin-top: 0;
22 | }
23 |
24 | body,
25 | input,
26 | textarea {
27 | font-family: Georgia, serif;
28 | font-size: 12pt;
29 | }
30 |
31 | table {
32 | border-collapse: collapse;
33 | border: 0;
34 | }
35 |
36 | td {
37 | border: 0;
38 | padding: 0;
39 | }
40 |
41 | h1,
42 | h2,
43 | h3,
44 | h4 {
45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
46 | margin: 0;
47 | }
48 |
49 | h1 {
50 | font-size: 20pt;
51 | }
52 |
53 | pre,
54 | code {
55 | font-family: monospace;
56 | color: #060;
57 | }
58 |
59 | pre {
60 | margin-left: 1em;
61 | padding-left: 1em;
62 | border-left: 1px solid silver;
63 | line-height: 14pt;
64 | }
65 |
66 | a,
67 | a code {
68 | color: #00c;
69 | }
70 |
71 | #body {
72 | max-width: 800px;
73 | margin: auto;
74 | }
75 |
76 | #header {
77 | background-color: #3b5998;
78 | padding: 5px;
79 | padding-left: 10px;
80 | padding-right: 10px;
81 | margin-bottom: 1em;
82 | }
83 |
84 | #header,
85 | #header a {
86 | color: white;
87 | }
88 |
89 | #header h1 a {
90 | text-decoration: none;
91 | }
92 |
93 | #footer,
94 | #content {
95 | margin-left: 10px;
96 | margin-right: 10px;
97 | }
98 |
99 | #footer {
100 | margin-top: 3em;
101 | }
102 |
103 | .entry h1 a {
104 | color: black;
105 | text-decoration: none;
106 | }
107 |
108 | .entry {
109 | margin-bottom: 2em;
110 | }
111 |
112 | .entry .date {
113 | margin-top: 3px;
114 | }
115 |
116 | .entry p {
117 | margin: 0;
118 | margin-bottom: 1em;
119 | }
120 |
121 | .entry .body {
122 | margin-top: 1em;
123 | line-height: 16pt;
124 | }
125 |
126 | .compose td {
127 | vertical-align: middle;
128 | padding-bottom: 5px;
129 | }
130 |
131 | .compose td.field {
132 | padding-right: 10px;
133 | }
134 |
135 | .compose .title,
136 | .compose .submit {
137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
138 | font-weight: bold;
139 | }
140 |
141 | .compose .title {
142 | font-size: 20pt;
143 | }
144 |
145 | .compose .title,
146 | .compose .markdown {
147 | width: 100%;
148 | }
149 |
150 | .compose .markdown {
151 | height: 500px;
152 | line-height: 16pt;
153 | }
154 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/archive.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
20 | {% end %}
21 |
22 | {% block body %}
23 |
31 | {% end %}
32 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ escape(handler.settings["blog_title"]) }}
6 |
7 |
8 | {% block head %}{% end %}
9 |
10 |
11 |
12 |
23 |
{% block body %}{% end %}
24 |
25 | {% block bottom %}{% end %}
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/compose.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 |
5 |
6 | {{ entry.markdown if entry else "" }}
7 |
12 | {% if entry %}
13 |
14 | {% end %}
15 | {% module xsrf_form_html() %}
16 |
17 | {% end %}
18 |
19 | {% block bottom %}
20 |
21 |
41 | {% end %}
42 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/entry.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% module Entry(entry) %}
5 | {% end %}
6 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %}
4 | {{ handler.settings["blog_title"] }}
5 | {% if len(entries) > 0 %}
6 | {{ max(e.updated for e in entries).strftime(date_format) }}
7 | {% else %}
8 | {{ datetime.datetime.utcnow().strftime(date_format) }}
9 | {% end %}
10 | http://{{ request.host }}/
11 |
12 |
13 | {{ handler.settings["blog_title"] }}
14 | {% for entry in entries %}
15 |
16 | http://{{ request.host }}/entry/{{ entry.slug }}
17 | {{ entry.title }}
18 |
19 | {{ entry.updated.strftime(date_format) }}
20 | {{ entry.published.strftime(date_format) }}
21 |
22 | {% raw entry.html %}
23 |
24 |
25 | {% end %}
26 |
27 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% for entry in entries %}
5 | {% module Entry(entry) %}
6 | {% end %}
7 |
8 | {% end %}
9 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/blog/templates/modules/entry.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user %}
6 |
7 | {% end %}
8 |
9 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/chat/static/chat.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 FriendFeed
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | margin: 10px;
20 | }
21 |
22 | body,
23 | input {
24 | font-family: sans-serif;
25 | font-size: 10pt;
26 | color: black;
27 | }
28 |
29 | table {
30 | border-collapse: collapse;
31 | border: 0;
32 | }
33 |
34 | td {
35 | border: 0;
36 | padding: 0;
37 | }
38 |
39 | #body {
40 | position: absolute;
41 | bottom: 10px;
42 | left: 10px;
43 | }
44 |
45 | #input {
46 | margin-top: 0.5em;
47 | }
48 |
49 | #inbox .message {
50 | padding-top: 0.25em;
51 | }
52 |
53 | #nav {
54 | float: right;
55 | z-index: 99;
56 | }
57 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/chat/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tornado Chat Demo
6 |
7 |
8 |
9 |
13 |
14 |
15 | {% for message in messages %}
16 | {% module Template("message.html", message=message) %}
17 | {% end %}
18 |
19 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/chat/templates/message.html:
--------------------------------------------------------------------------------
1 | {{ message["from"] }}: {% module linkify(message["body"]) %}
2 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/facebook/README:
--------------------------------------------------------------------------------
1 | Running the Tornado Facebook example
2 | =====================================
3 | To work with the provided Facebook api key, this example must be
4 | accessed at http://localhost:8888/ to match the Connect URL set in the
5 | example application.
6 |
7 | To use any other domain, a new Facebook application must be registered
8 | with a Connect URL set to that domain.
9 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/facebook/static/facebook.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Facebook
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | color: black;
20 | margin: 15px;
21 | }
22 |
23 | body,
24 | input,
25 | textarea {
26 | font-family: "Lucida Grande", Tahoma, Verdana, sans-serif;
27 | font-size: 10pt;
28 | }
29 |
30 | table {
31 | border-collapse: collapse;
32 | border: 0;
33 | }
34 |
35 | td {
36 | border: 0;
37 | padding: 0;
38 | }
39 |
40 | img {
41 | border: 0;
42 | }
43 |
44 | a {
45 | text-decoration: none;
46 | color: #3b5998;
47 | }
48 |
49 | a:hover {
50 | text-decoration: underline;
51 | }
52 |
53 | .post {
54 | border-bottom: 1px solid #eeeeee;
55 | min-height: 50px;
56 | padding-bottom: 10px;
57 | margin-top: 10px;
58 | }
59 |
60 | .post .picture {
61 | float: left;
62 | }
63 |
64 | .post .picture img {
65 | height: 50px;
66 | width: 50px;
67 | }
68 |
69 | .post .body {
70 | margin-left: 60px;
71 | }
72 |
73 | .post .media img {
74 | border: 1px solid #cccccc;
75 | padding: 3px;
76 | }
77 |
78 | .post .media:hover img {
79 | border: 1px solid #3b5998;
80 | }
81 |
82 | .post a.actor {
83 | font-weight: bold;
84 | }
85 |
86 | .post .meta {
87 | font-size: 11px;
88 | }
89 |
90 | .post a.permalink {
91 | color: #777777;
92 | }
93 |
94 | #body {
95 | max-width: 700px;
96 | margin: auto;
97 | }
98 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/facebook/static/facebook.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-3.2.2/demos/facebook/static/facebook.js
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/facebook/templates/modules/post.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% set author_url="http://www.facebook.com/profile.php?id=" + escape(post["from"]["id"]) %}
4 |
5 |
6 |
7 |
{{ escape(post["from"]["name"]) }}
8 | {% if "message" in post %}
9 |
{{ escape(post["message"]) }}
10 | {% end %}
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/facebook/templates/stream.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tornado Facebook Stream Demo
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 | {% for post in stream["data"] %}
17 | {{ modules.Post(post) }}
18 | {% end %}
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/helloworld/helloworld.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2009 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | import tornado.httpserver
18 | import tornado.ioloop
19 | import tornado.options
20 | import tornado.web
21 |
22 | from tornado.options import define, options
23 |
24 | define("port", default=8888, help="run on the given port", type=int)
25 |
26 |
27 | class MainHandler(tornado.web.RequestHandler):
28 | def get(self):
29 | self.write("Hello, world")
30 |
31 |
32 | def main():
33 | tornado.options.parse_command_line()
34 | application = tornado.web.Application([
35 | (r"/", MainHandler),
36 | ])
37 | http_server = tornado.httpserver.HTTPServer(application)
38 | http_server.listen(options.port)
39 | tornado.ioloop.IOLoop.instance().start()
40 |
41 |
42 | if __name__ == "__main__":
43 | main()
44 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/twitter/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tornado Twitter Demo
4 |
5 |
6 |
7 | {% for tweet in timeline %}
8 | {{ tweet['user']['screen_name'] }} : {{ tweet['text'] }}
9 | {% end %}
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/websocket/static/chat.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 FriendFeed
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | margin: 10px;
20 | }
21 |
22 | body,
23 | input {
24 | font-family: sans-serif;
25 | font-size: 10pt;
26 | color: black;
27 | }
28 |
29 | table {
30 | border-collapse: collapse;
31 | border: 0;
32 | }
33 |
34 | td {
35 | border: 0;
36 | padding: 0;
37 | }
38 |
39 | #body {
40 | position: absolute;
41 | bottom: 10px;
42 | left: 10px;
43 | }
44 |
45 | #input {
46 | margin-top: 0.5em;
47 | }
48 |
49 | #inbox .message {
50 | padding-top: 0.25em;
51 | }
52 |
53 | #nav {
54 | float: right;
55 | z-index: 99;
56 | }
57 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/websocket/static/chat.js:
--------------------------------------------------------------------------------
1 | // Copyright 2009 FriendFeed
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | $(document).ready(function() {
16 | if (!window.console) window.console = {};
17 | if (!window.console.log) window.console.log = function() {};
18 |
19 | $("#messageform").live("submit", function() {
20 | newMessage($(this));
21 | return false;
22 | });
23 | $("#messageform").live("keypress", function(e) {
24 | if (e.keyCode == 13) {
25 | newMessage($(this));
26 | return false;
27 | }
28 | });
29 | $("#message").select();
30 | updater.start();
31 | });
32 |
33 | function newMessage(form) {
34 | var message = form.formToDict();
35 | updater.socket.send(JSON.stringify(message));
36 | form.find("input[type=text]").val("").select();
37 | }
38 |
39 | jQuery.fn.formToDict = function() {
40 | var fields = this.serializeArray();
41 | var json = {}
42 | for (var i = 0; i < fields.length; i++) {
43 | json[fields[i].name] = fields[i].value;
44 | }
45 | if (json.next) delete json.next;
46 | return json;
47 | };
48 |
49 | var updater = {
50 | socket: null,
51 |
52 | start: function() {
53 | var url = "ws://" + location.host + "/chatsocket";
54 | updater.socket = new WebSocket(url);
55 | updater.socket.onmessage = function(event) {
56 | updater.showMessage(JSON.parse(event.data));
57 | }
58 | },
59 |
60 | showMessage: function(message) {
61 | var existing = $("#m" + message.id);
62 | if (existing.length > 0) return;
63 | var node = $(message.html);
64 | node.hide();
65 | $("#inbox").append(node);
66 | node.slideDown();
67 | }
68 | };
69 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/websocket/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tornado Chat Demo
6 |
7 |
8 |
9 |
10 |
11 | {% for message in messages %}
12 | {% include "message.html" %}
13 | {% end %}
14 |
15 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/demos/websocket/templates/message.html:
--------------------------------------------------------------------------------
1 | {% module linkify(message["body"]) %}
2 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/readme.md:
--------------------------------------------------------------------------------
1 |
2 | ## tornado 3.2.2 说明:
3 |
4 |
5 | ### 1. 代码打印阅读:
6 |
7 | - ioloop.py
8 | - web.py
9 | - gen.py
10 |
11 |
12 |
13 | ### 2. 相关参考阅读:
14 |
15 | - [tornado 之 ioloop模块解读](https://github.com/dragondjf/dragondjfblog/blob/master/content/tornado%20%E4%B9%8B%20ioloop%E6%A8%A1%E5%9D%97%E8%A7%A3%E8%AF%BB.md)
16 | - 依赖的库,介绍.
17 | - [tornado 源码阅读-初步认识](https://segmentfault.com/a/1190000002971992)
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2009 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """The Tornado web server and tools."""
18 |
19 | from __future__ import absolute_import, division, print_function, with_statement
20 |
21 | # version is a human-readable version number.
22 |
23 | # version_info is a four-tuple for programmatic comparison. The first
24 | # three numbers are the components of the version number. The fourth
25 | # is zero for an official release, positive for a development branch,
26 | # or negative for a release candidate or beta (after the base version
27 | # number has been incremented)
28 | version = "3.2.2"
29 | version_info = (3, 2, 2, 0)
30 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-3.2.2/tornado/platform/__init__.py
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/auto.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2011 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """Implementation of platform-specific functionality.
18 |
19 | For each function or class described in `tornado.platform.interface`,
20 | the appropriate platform-specific implementation exists in this module.
21 | Most code that needs access to this functionality should do e.g.::
22 |
23 | from tornado.platform.auto import set_close_exec
24 | """
25 |
26 | from __future__ import absolute_import, division, print_function, with_statement
27 |
28 | import os
29 |
30 | if os.name == 'nt':
31 | from tornado.platform.common import Waker
32 | from tornado.platform.windows import set_close_exec
33 | else:
34 | from tornado.platform.posix import set_close_exec, Waker
35 |
36 | try:
37 | # monotime monkey-patches the time module to have a monotonic function
38 | # in versions of python before 3.3.
39 | import monotime
40 | except ImportError:
41 | pass
42 | try:
43 | from time import monotonic as monotonic_time
44 | except ImportError:
45 | monotonic_time = None
46 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/caresresolver.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 | import pycares
3 | import socket
4 |
5 | from tornado import gen
6 | from tornado.ioloop import IOLoop
7 | from tornado.netutil import Resolver, is_valid_ip
8 |
9 |
10 | class CaresResolver(Resolver):
11 | """Name resolver based on the c-ares library.
12 |
13 | This is a non-blocking and non-threaded resolver. It may not produce
14 | the same results as the system resolver, but can be used for non-blocking
15 | resolution when threads cannot be used.
16 |
17 | c-ares fails to resolve some names when ``family`` is ``AF_UNSPEC``,
18 | so it is only recommended for use in ``AF_INET`` (i.e. IPv4). This is
19 | the default for ``tornado.simple_httpclient``, but other libraries
20 | may default to ``AF_UNSPEC``.
21 | """
22 | def initialize(self, io_loop=None):
23 | self.io_loop = io_loop or IOLoop.current()
24 | self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb)
25 | self.fds = {}
26 |
27 | def _sock_state_cb(self, fd, readable, writable):
28 | state = ((IOLoop.READ if readable else 0) |
29 | (IOLoop.WRITE if writable else 0))
30 | if not state:
31 | self.io_loop.remove_handler(fd)
32 | del self.fds[fd]
33 | elif fd in self.fds:
34 | self.io_loop.update_handler(fd, state)
35 | self.fds[fd] = state
36 | else:
37 | self.io_loop.add_handler(fd, self._handle_events, state)
38 | self.fds[fd] = state
39 |
40 | def _handle_events(self, fd, events):
41 | read_fd = pycares.ARES_SOCKET_BAD
42 | write_fd = pycares.ARES_SOCKET_BAD
43 | if events & IOLoop.READ:
44 | read_fd = fd
45 | if events & IOLoop.WRITE:
46 | write_fd = fd
47 | self.channel.process_fd(read_fd, write_fd)
48 |
49 | @gen.coroutine
50 | def resolve(self, host, port, family=0):
51 | if is_valid_ip(host):
52 | addresses = [host]
53 | else:
54 | # gethostbyname doesn't take callback as a kwarg
55 | self.channel.gethostbyname(host, family, (yield gen.Callback(1)))
56 | callback_args = yield gen.Wait(1)
57 | assert isinstance(callback_args, gen.Arguments)
58 | assert not callback_args.kwargs
59 | result, error = callback_args.args
60 | if error:
61 | raise Exception('C-Ares returned error %s: %s while resolving %s' %
62 | (error, pycares.errno.strerror(error), host))
63 | addresses = result.addresses
64 | addrinfo = []
65 | for address in addresses:
66 | if '.' in address:
67 | address_family = socket.AF_INET
68 | elif ':' in address:
69 | address_family = socket.AF_INET6
70 | else:
71 | address_family = socket.AF_UNSPEC
72 | if family != socket.AF_UNSPEC and family != address_family:
73 | raise Exception('Requested socket family %d but got %d' %
74 | (family, address_family))
75 | addrinfo.append((address_family, (address, port)))
76 | raise gen.Return(addrinfo)
77 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/epoll.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2012 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 | """EPoll-based IOLoop implementation for Linux systems."""
17 | from __future__ import absolute_import, division, print_function, with_statement
18 |
19 | import select
20 |
21 | from tornado.ioloop import PollIOLoop
22 |
23 |
24 | class EPollIOLoop(PollIOLoop):
25 | def initialize(self, **kwargs):
26 | super(EPollIOLoop, self).initialize(impl=select.epoll(), **kwargs)
27 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/interface.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2011 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """Interfaces for platform-specific functionality.
18 |
19 | This module exists primarily for documentation purposes and as base classes
20 | for other tornado.platform modules. Most code should import the appropriate
21 | implementation from `tornado.platform.auto`.
22 | """
23 |
24 | from __future__ import absolute_import, division, print_function, with_statement
25 |
26 |
27 | def set_close_exec(fd):
28 | """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor."""
29 | raise NotImplementedError()
30 |
31 |
32 | class Waker(object):
33 | """A socket-like object that can wake another thread from ``select()``.
34 |
35 | The `~tornado.ioloop.IOLoop` will add the Waker's `fileno()` to
36 | its ``select`` (or ``epoll`` or ``kqueue``) calls. When another
37 | thread wants to wake up the loop, it calls `wake`. Once it has woken
38 | up, it will call `consume` to do any necessary per-wake cleanup. When
39 | the ``IOLoop`` is closed, it closes its waker too.
40 | """
41 | def fileno(self):
42 | """Returns the read file descriptor for this waker.
43 |
44 | Must be suitable for use with ``select()`` or equivalent on the
45 | local platform.
46 | """
47 | raise NotImplementedError()
48 |
49 | def write_fileno(self):
50 | """Returns the write file descriptor for this waker."""
51 | raise NotImplementedError()
52 |
53 | def wake(self):
54 | """Triggers activity on the waker's file descriptor."""
55 | raise NotImplementedError()
56 |
57 | def consume(self):
58 | """Called after the listen has woken up to do any necessary cleanup."""
59 | raise NotImplementedError()
60 |
61 | def close(self):
62 | """Closes the waker's file descriptor(s)."""
63 | raise NotImplementedError()
64 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/posix.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2011 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """Posix implementations of platform-specific functionality."""
18 |
19 | from __future__ import absolute_import, division, print_function, with_statement
20 |
21 | import fcntl
22 | import os
23 |
24 | from tornado.platform import interface
25 |
26 |
27 | def set_close_exec(fd):
28 | flags = fcntl.fcntl(fd, fcntl.F_GETFD)
29 | fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
30 |
31 |
32 | def _set_nonblocking(fd):
33 | flags = fcntl.fcntl(fd, fcntl.F_GETFL)
34 | fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
35 |
36 |
37 | class Waker(interface.Waker):
38 | def __init__(self):
39 | r, w = os.pipe()
40 | _set_nonblocking(r)
41 | _set_nonblocking(w)
42 | set_close_exec(r)
43 | set_close_exec(w)
44 | self.reader = os.fdopen(r, "rb", 0)
45 | self.writer = os.fdopen(w, "wb", 0)
46 |
47 | def fileno(self):
48 | return self.reader.fileno()
49 |
50 | def write_fileno(self):
51 | return self.writer.fileno()
52 |
53 | def wake(self):
54 | try:
55 | self.writer.write(b"x")
56 | except IOError:
57 | pass
58 |
59 | def consume(self):
60 | try:
61 | while True:
62 | result = self.reader.read()
63 | if not result:
64 | break
65 | except IOError:
66 | pass
67 |
68 | def close(self):
69 | self.reader.close()
70 | self.writer.close()
71 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/select.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2012 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 | """Select-based IOLoop implementation.
17 |
18 | Used as a fallback for systems that don't support epoll or kqueue.
19 | """
20 | from __future__ import absolute_import, division, print_function, with_statement
21 |
22 | import select
23 |
24 | from tornado.ioloop import IOLoop, PollIOLoop
25 |
26 |
27 | class _Select(object):
28 | """A simple, select()-based IOLoop implementation for non-Linux systems"""
29 | def __init__(self):
30 | self.read_fds = set()
31 | self.write_fds = set()
32 | self.error_fds = set()
33 | self.fd_sets = (self.read_fds, self.write_fds, self.error_fds)
34 |
35 | def close(self):
36 | pass
37 |
38 | def register(self, fd, events):
39 | if fd in self.read_fds or fd in self.write_fds or fd in self.error_fds:
40 | raise IOError("fd %d already registered" % fd)
41 | if events & IOLoop.READ:
42 | self.read_fds.add(fd)
43 | if events & IOLoop.WRITE:
44 | self.write_fds.add(fd)
45 | if events & IOLoop.ERROR:
46 | self.error_fds.add(fd)
47 | # Closed connections are reported as errors by epoll and kqueue,
48 | # but as zero-byte reads by select, so when errors are requested
49 | # we need to listen for both read and error.
50 | self.read_fds.add(fd)
51 |
52 | def modify(self, fd, events):
53 | self.unregister(fd)
54 | self.register(fd, events)
55 |
56 | def unregister(self, fd):
57 | self.read_fds.discard(fd)
58 | self.write_fds.discard(fd)
59 | self.error_fds.discard(fd)
60 |
61 | def poll(self, timeout):
62 | readable, writeable, errors = select.select(
63 | self.read_fds, self.write_fds, self.error_fds, timeout)
64 | events = {}
65 | for fd in readable:
66 | events[fd] = events.get(fd, 0) | IOLoop.READ
67 | for fd in writeable:
68 | events[fd] = events.get(fd, 0) | IOLoop.WRITE
69 | for fd in errors:
70 | events[fd] = events.get(fd, 0) | IOLoop.ERROR
71 | return events.items()
72 |
73 |
74 | class SelectIOLoop(PollIOLoop):
75 | def initialize(self, **kwargs):
76 | super(SelectIOLoop, self).initialize(impl=_Select(), **kwargs)
77 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/platform/windows.py:
--------------------------------------------------------------------------------
1 | # NOTE: win32 support is currently experimental, and not recommended
2 | # for production use.
3 |
4 |
5 | from __future__ import absolute_import, division, print_function, with_statement
6 | import ctypes
7 | import ctypes.wintypes
8 |
9 | # See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx
10 | SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
11 | SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)
12 | SetHandleInformation.restype = ctypes.wintypes.BOOL
13 |
14 | HANDLE_FLAG_INHERIT = 0x00000001
15 |
16 |
17 | def set_close_exec(fd):
18 | success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0)
19 | if not success:
20 | raise ctypes.GetLastError()
21 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/speedups.c:
--------------------------------------------------------------------------------
1 | #define PY_SSIZE_T_CLEAN
2 | #include
3 |
4 | static PyObject* websocket_mask(PyObject* self, PyObject* args) {
5 | const char* mask;
6 | Py_ssize_t mask_len;
7 | const char* data;
8 | Py_ssize_t data_len;
9 | Py_ssize_t i;
10 | PyObject* result;
11 | char* buf;
12 |
13 | if (!PyArg_ParseTuple(args, "s#s#", &mask, &mask_len, &data, &data_len)) {
14 | return NULL;
15 | }
16 |
17 | result = PyBytes_FromStringAndSize(NULL, data_len);
18 | if (!result) {
19 | return NULL;
20 | }
21 | buf = PyBytes_AsString(result);
22 | for (i = 0; i < data_len; i++) {
23 | buf[i] = data[i] ^ mask[i % 4];
24 | }
25 |
26 | return result;
27 | }
28 |
29 | static PyMethodDef methods[] = {
30 | {"websocket_mask", websocket_mask, METH_VARARGS, ""},
31 | {NULL, NULL, 0, NULL}
32 | };
33 |
34 | #if PY_MAJOR_VERSION >= 3
35 | static struct PyModuleDef speedupsmodule = {
36 | PyModuleDef_HEAD_INIT,
37 | "speedups",
38 | NULL,
39 | -1,
40 | methods
41 | };
42 |
43 | PyMODINIT_FUNC
44 | PyInit_speedups() {
45 | return PyModule_Create(&speedupsmodule);
46 | }
47 | #else // Python 2.x
48 | PyMODINIT_FUNC
49 | initspeedups() {
50 | Py_InitModule("tornado.speedups", methods);
51 | }
52 | #endif
53 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/README:
--------------------------------------------------------------------------------
1 | Test coverage is almost non-existent, but it's a start. Be sure to
2 | set PYTHONPATH apprioriately (generally to the root directory of your
3 | tornado checkout) when running tests to make sure you're getting the
4 | version of the tornado package that you expect.
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-3.2.2/tornado/test/__init__.py
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/csv_translations/fr_FR.csv:
--------------------------------------------------------------------------------
1 | "school","école"
2 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/gettext_translations/extract_me.py:
--------------------------------------------------------------------------------
1 | # Dummy source file to allow creation of the initial .po file in the
2 | # same way as a real project. I'm not entirely sure about the real
3 | # workflow here, but this seems to work.
4 | #
5 | # 1) xgettext --language=Python --keyword=_:1,2 -d tornado_test extract_me.py -o tornado_test.po
6 | # 2) Edit tornado_test.po, setting CHARSET and setting msgstr
7 | # 3) msgfmt tornado_test.po -o tornado_test.mo
8 | # 4) Put the file in the proper location: $LANG/LC_MESSAGES
9 |
10 | from __future__ import absolute_import, division, print_function, with_statement
11 | _("school")
12 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the PACKAGE package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: PACKAGE VERSION\n"
10 | "Report-Msgid-Bugs-To: \n"
11 | "POT-Creation-Date: 2012-06-14 01:10-0700\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=utf-8\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: extract_me.py:1
21 | msgid "school"
22 | msgstr "école"
23 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/import_test.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 | from tornado.test.util import unittest
3 |
4 |
5 | class ImportTest(unittest.TestCase):
6 | def test_import_everything(self):
7 | # Some of our modules are not otherwise tested. Import them
8 | # all (unless they have external dependencies) here to at
9 | # least ensure that there are no syntax errors.
10 | import tornado.auth
11 | import tornado.autoreload
12 | import tornado.concurrent
13 | # import tornado.curl_httpclient # depends on pycurl
14 | import tornado.escape
15 | import tornado.gen
16 | import tornado.httpclient
17 | import tornado.httpserver
18 | import tornado.httputil
19 | import tornado.ioloop
20 | import tornado.iostream
21 | import tornado.locale
22 | import tornado.log
23 | import tornado.netutil
24 | import tornado.options
25 | import tornado.process
26 | import tornado.simple_httpclient
27 | import tornado.stack_context
28 | import tornado.tcpserver
29 | import tornado.template
30 | import tornado.testing
31 | import tornado.util
32 | import tornado.web
33 | import tornado.websocket
34 | import tornado.wsgi
35 |
36 | # for modules with dependencies, if those dependencies can be loaded,
37 | # load them too.
38 |
39 | def test_import_pycurl(self):
40 | try:
41 | import pycurl
42 | except ImportError:
43 | pass
44 | else:
45 | import tornado.curl_httpclient
46 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/locale_test.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 |
3 | import datetime
4 | import os
5 | import tornado.locale
6 | from tornado.escape import utf8
7 | from tornado.test.util import unittest
8 | from tornado.util import u, unicode_type
9 |
10 |
11 | class TranslationLoaderTest(unittest.TestCase):
12 | # TODO: less hacky way to get isolated tests
13 | SAVE_VARS = ['_translations', '_supported_locales', '_use_gettext']
14 |
15 | def clear_locale_cache(self):
16 | if hasattr(tornado.locale.Locale, '_cache'):
17 | del tornado.locale.Locale._cache
18 |
19 | def setUp(self):
20 | self.saved = {}
21 | for var in TranslationLoaderTest.SAVE_VARS:
22 | self.saved[var] = getattr(tornado.locale, var)
23 | self.clear_locale_cache()
24 |
25 | def tearDown(self):
26 | for k, v in self.saved.items():
27 | setattr(tornado.locale, k, v)
28 | self.clear_locale_cache()
29 |
30 | def test_csv(self):
31 | tornado.locale.load_translations(
32 | os.path.join(os.path.dirname(__file__), 'csv_translations'))
33 | locale = tornado.locale.get("fr_FR")
34 | self.assertTrue(isinstance(locale, tornado.locale.CSVLocale))
35 | self.assertEqual(locale.translate("school"), u("\u00e9cole"))
36 |
37 | def test_gettext(self):
38 | tornado.locale.load_gettext_translations(
39 | os.path.join(os.path.dirname(__file__), 'gettext_translations'),
40 | "tornado_test")
41 | locale = tornado.locale.get("fr_FR")
42 | self.assertTrue(isinstance(locale, tornado.locale.GettextLocale))
43 | self.assertEqual(locale.translate("school"), u("\u00e9cole"))
44 |
45 |
46 | class LocaleDataTest(unittest.TestCase):
47 | def test_non_ascii_name(self):
48 | name = tornado.locale.LOCALE_NAMES['es_LA']['name']
49 | self.assertTrue(isinstance(name, unicode_type))
50 | self.assertEqual(name, u('Espa\u00f1ol'))
51 | self.assertEqual(utf8(name), b'Espa\xc3\xb1ol')
52 |
53 |
54 | class EnglishTest(unittest.TestCase):
55 | def test_format_date(self):
56 | locale = tornado.locale.get('en_US')
57 | date = datetime.datetime(2013, 4, 28, 18, 35)
58 | self.assertEqual(locale.format_date(date, full_format=True),
59 | 'April 28, 2013 at 6:35 pm')
60 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/options_test.cfg:
--------------------------------------------------------------------------------
1 | port=443
2 | port=443
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/resolve_test_helper.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 | from tornado.ioloop import IOLoop
3 | from tornado.netutil import ThreadedResolver
4 | from tornado.util import u
5 |
6 | # When this module is imported, it runs getaddrinfo on a thread. Since
7 | # the hostname is unicode, getaddrinfo attempts to import encodings.idna
8 | # but blocks on the import lock. Verify that ThreadedResolver avoids
9 | # this deadlock.
10 |
11 | resolver = ThreadedResolver()
12 | IOLoop.current().run_sync(lambda: resolver.resolve(u('localhost'), 80))
13 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/static/dir/index.html:
--------------------------------------------------------------------------------
1 | this is the index
2 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/static/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
3 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/templates/utf8.html:
--------------------------------------------------------------------------------
1 | Héllo
2 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/test.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICSDCCAbGgAwIBAgIJAN1oTowzMbkzMA0GCSqGSIb3DQEBBQUAMD0xCzAJBgNV
3 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRkwFwYDVQQKDBBUb3JuYWRvIFdl
4 | YiBUZXN0MB4XDTEwMDgyNTE4MjQ0NFoXDTIwMDgyMjE4MjQ0NFowPTELMAkGA1UE
5 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExGTAXBgNVBAoMEFRvcm5hZG8gV2Vi
6 | IFRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALirW3mX4jbdFse2aZwW
7 | zszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcLtKqv
8 | jnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+PzU39
9 | UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAGjUDBOMB0GA1UdDgQWBBRhJjMBYrzddCFr
10 | /0vvPyHMeqgo0TAfBgNVHSMEGDAWgBRhJjMBYrzddCFr/0vvPyHMeqgo0TAMBgNV
11 | HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGP6GaxSfb21bikcqaK3ZKCC1sRJ
12 | tiCuvJZbBUFUCAzl05dYUfJZim/oWK+GqyUkUB8ciYivUNnn9OtS7DnlTgT2ws2e
13 | lNgn5cuFXoAGcHXzVlHG3yoywYBf3y0Dn20uzrlLXUWJAzoSLOt2LTaXvwlgm7hF
14 | W1q8SQ6UBshRw2X0
15 | -----END CERTIFICATE-----
16 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/test.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALirW3mX4jbdFse2
3 | aZwWzszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcL
4 | tKqvjnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+P
5 | zU39UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAECgYEAiygNaWYrf95AcUQi9w00zpUr
6 | nj9fNvCwxr2kVbRMvd2balS/CC4EmXPCXdVcZ3B7dBVjYzSIJV0Fh/iZLtnVysD9
7 | fcNMZ+Cz71b/T0ItsNYOsJk0qUVyP52uqsqkNppIPJsD19C+ZeMLZj6iEiylZyl8
8 | 2U16c/kVIjER63mUEGkCQQDayQOTGPJrKHqPAkUqzeJkfvHH2yCf+cySU+w6ezyr
9 | j9yxcq8aZoLusCebDVT+kz7RqnD5JePFvB38cMuepYBLAkEA2BTFdZx30f4moPNv
10 | JlXlPNJMUTUzsXG7n4vNc+18O5ous0NGQII8jZWrIcTrP8wiP9fF3JwUsKrJhcBn
11 | xRs3hQJBAIDUgz1YIE+HW3vgi1gkOh6RPdBAsVpiXtr/fggFz3j60qrO7FswaAMj
12 | SX8c/6KUlBYkNjgP3qruFf4zcUNvEzcCQQCaioCPFVE9ByBpjLG6IUTKsz2R9xL5
13 | nfYqrbpLZ1aq6iLsYvkjugHE4X57sHLwNfdo4dHJbnf9wqhO2MVe25BhAkBdKYpY
14 | 7OKc/2mmMbJDhVBgoixz/muN/5VjdfbvVY48naZkJF1p1tmogqPC5F1jPCS4rM+S
15 | FfPJIHRNEn2oktw5
16 | -----END PRIVATE KEY-----
17 |
--------------------------------------------------------------------------------
/src/tornado-3.2.2/tornado/test/util.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 |
3 | import os
4 | import sys
5 |
6 | # Encapsulate the choice of unittest or unittest2 here.
7 | # To be used as 'from tornado.test.util import unittest'.
8 | if sys.version_info >= (2, 7):
9 | import unittest
10 | else:
11 | import unittest2 as unittest
12 |
13 | skipIfNonUnix = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin',
14 | "non-unix platform")
15 |
16 | # travis-ci.org runs our tests in an overworked virtual machine, which makes
17 | # timing-related tests unreliable.
18 | skipOnTravis = unittest.skipIf('TRAVIS' in os.environ,
19 | 'timing tests unreliable on travis')
20 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/.coveragerc:
--------------------------------------------------------------------------------
1 | # Test coverage configuration.
2 | # Usage:
3 | # pip install coverage
4 | # coverage erase # clears previous data if any
5 | # coverage run -m tornado.test.runtests
6 | # coverage report # prints to stdout
7 | # coverage html # creates ./htmlcov/*.html including annotated source
8 | [run]
9 | branch = true
10 | source = tornado
11 | omit =
12 | tornado/platform/*
13 | tornado/test/*
14 | */_auto2to3*
15 |
16 | [report]
17 | # Ignore missing source files, i.e. fake template-generated "files"
18 | ignore_errors = true
19 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include demos *.py *.yaml *.html *.css *.js *.xml *.sql README
2 | recursive-include docs *
3 | prune docs/build
4 | include tornado/speedups.c
5 | include tornado/test/README
6 | include tornado/test/csv_translations/fr_FR.csv
7 | include tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.mo
8 | include tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po
9 | include tornado/test/options_test.cfg
10 | include tornado/test/static/robots.txt
11 | include tornado/test/static/dir/index.html
12 | include tornado/test/templates/utf8.html
13 | include tornado/test/test.crt
14 | include tornado/test/test.key
15 | include README.rst
16 | include runtests.sh
17 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/README:
--------------------------------------------------------------------------------
1 | Running the Tornado AppEngine example
2 | =====================================
3 | This example is designed to run in Google AppEngine, so there are a couple
4 | of steps to get it running. You can download the Google AppEngine Python
5 | development environment at http://code.google.com/appengine/downloads.html.
6 |
7 | 1. Link or copy the tornado code directory into this directory:
8 |
9 | ln -s ../../tornado tornado
10 |
11 | AppEngine doesn't use the Python modules installed on this machine.
12 | You need to have the 'tornado' module copied or linked for AppEngine
13 | to find it.
14 |
15 | 3. Install and run dev_appserver
16 |
17 | If you don't already have the App Engine SDK, download it from
18 | http://code.google.com/appengine/downloads.html
19 |
20 | To start the tornado demo, run the dev server on this directory:
21 |
22 | dev_appserver.py .
23 |
24 | 4. Visit http://localhost:8080/ in your browser
25 |
26 | If you sign in as an administrator, you will be able to create and
27 | edit blog posts. If you sign in as anybody else, you will only see
28 | the existing blog posts.
29 |
30 |
31 | If you want to deploy the blog in production:
32 |
33 | 1. Register a new appengine application and put its id in app.yaml
34 |
35 | First register a new application at http://appengine.google.com/.
36 | Then edit app.yaml in this directory and change the "application"
37 | setting from "tornado-appenginge" to your new application id.
38 |
39 | 2. Deploy to App Engine
40 |
41 | If you registered an application id, you can now upload your new
42 | Tornado blog by running this command:
43 |
44 | appcfg update .
45 |
46 | After that, visit application_id.appspot.com, where application_id
47 | is the application you registered.
48 |
49 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/app.yaml:
--------------------------------------------------------------------------------
1 | application: tornado-appengine
2 | version: 2
3 | runtime: python27
4 | api_version: 1
5 | threadsafe: yes
6 |
7 | handlers:
8 | - url: /static/
9 | static_dir: static
10 |
11 | - url: /.*
12 | script: blog.application
13 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/static/blog.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Facebook
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | color: black;
20 | margin: 15px;
21 | margin-top: 0;
22 | }
23 |
24 | body,
25 | input,
26 | textarea {
27 | font-family: Georgia, serif;
28 | font-size: 12pt;
29 | }
30 |
31 | table {
32 | border-collapse: collapse;
33 | border: 0;
34 | }
35 |
36 | td {
37 | border: 0;
38 | padding: 0;
39 | }
40 |
41 | h1,
42 | h2,
43 | h3,
44 | h4 {
45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
46 | margin: 0;
47 | }
48 |
49 | h1 {
50 | font-size: 20pt;
51 | }
52 |
53 | pre,
54 | code {
55 | font-family: monospace;
56 | color: #060;
57 | }
58 |
59 | pre {
60 | margin-left: 1em;
61 | padding-left: 1em;
62 | border-left: 1px solid silver;
63 | line-height: 14pt;
64 | }
65 |
66 | a,
67 | a code {
68 | color: #00c;
69 | }
70 |
71 | #body {
72 | max-width: 800px;
73 | margin: auto;
74 | }
75 |
76 | #header {
77 | background-color: #3b5998;
78 | padding: 5px;
79 | padding-left: 10px;
80 | padding-right: 10px;
81 | margin-bottom: 1em;
82 | }
83 |
84 | #header,
85 | #header a {
86 | color: white;
87 | }
88 |
89 | #header h1 a {
90 | text-decoration: none;
91 | }
92 |
93 | #footer,
94 | #content {
95 | margin-left: 10px;
96 | margin-right: 10px;
97 | }
98 |
99 | #footer {
100 | margin-top: 3em;
101 | }
102 |
103 | .entry h1 a {
104 | color: black;
105 | text-decoration: none;
106 | }
107 |
108 | .entry {
109 | margin-bottom: 2em;
110 | }
111 |
112 | .entry .date {
113 | margin-top: 3px;
114 | }
115 |
116 | .entry p {
117 | margin: 0;
118 | margin-bottom: 1em;
119 | }
120 |
121 | .entry .body {
122 | margin-top: 1em;
123 | line-height: 16pt;
124 | }
125 |
126 | .compose td {
127 | vertical-align: middle;
128 | padding-bottom: 5px;
129 | }
130 |
131 | .compose td.field {
132 | padding-right: 10px;
133 | }
134 |
135 | .compose .title,
136 | .compose .submit {
137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
138 | font-weight: bold;
139 | }
140 |
141 | .compose .title {
142 | font-size: 20pt;
143 | }
144 |
145 | .compose .title,
146 | .compose .body_source {
147 | width: 100%;
148 | }
149 |
150 | .compose .body_source {
151 | height: 500px;
152 | line-height: 16pt;
153 | }
154 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/archive.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
20 | {% end %}
21 |
22 | {% block body %}
23 |
31 | {% end %}
32 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ handler.settings["blog_title"] }}
6 |
7 |
8 | {% block head %}{% end %}
9 |
10 |
11 |
12 |
25 |
{% block body %}{% end %}
26 |
27 | {% block bottom %}{% end %}
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/compose.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 |
5 |
6 | {{ entry.body_source if entry else "" }}
7 |
11 | {% if entry %}
12 |
13 | {% end %}
14 | {% module xsrf_form_html() %}
15 |
16 | {% end %}
17 |
18 | {% block bottom %}
19 |
20 |
40 | {% end %}
41 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/entry.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% module Entry(entry) %}
5 | {% end %}
6 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %}
4 | {{ handler.settings["blog_title"] }}
5 | {% if len(entries) > 0 %}
6 | {{ max(e.updated for e in entries).strftime(date_format) }}
7 | {% else %}
8 | {{ datetime.datetime.utcnow().strftime(date_format) }}
9 | {% end %}
10 | http://{{ request.host }}/
11 |
12 |
13 | {{ handler.settings["blog_title"] }}
14 | {% for entry in entries %}
15 |
16 | http://{{ request.host }}/entry/{{ entry.slug }}
17 | {{ entry.title }}
18 |
19 | {{ entry.updated.strftime(date_format) }}
20 | {{ entry.published.strftime(date_format) }}
21 |
22 | {% raw entry.html %}
23 |
24 |
25 | {% end %}
26 |
27 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% for entry in entries %}
5 | {% module Entry(entry) %}
6 | {% end %}
7 |
8 | {% end %}
9 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/appengine/templates/modules/entry.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user and current_user.administrator %}
6 |
7 | {% end %}
8 |
9 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/benchmark/benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # A simple benchmark of tornado's HTTP stack.
4 | # Requires 'ab' to be installed.
5 | #
6 | # Running without profiling:
7 | # demos/benchmark/benchmark.py
8 | # demos/benchmark/benchmark.py --quiet --num_runs=5|grep "Requests per second"
9 | #
10 | # Running with profiling:
11 | #
12 | # python -m cProfile -o /tmp/prof demos/benchmark/benchmark.py
13 | # python -m pstats /tmp/prof
14 | # % sort time
15 | # % stats 20
16 |
17 | from tornado.ioloop import IOLoop
18 | from tornado.options import define, options, parse_command_line
19 | from tornado.web import RequestHandler, Application
20 |
21 | import random
22 | import signal
23 | import subprocess
24 |
25 | try:
26 | xrange
27 | except NameError:
28 | xrange = range
29 |
30 | # choose a random port to avoid colliding with TIME_WAIT sockets left over
31 | # from previous runs.
32 | define("min_port", type=int, default=8000)
33 | define("max_port", type=int, default=9000)
34 |
35 | # Increasing --n without --keepalive will eventually run into problems
36 | # due to TIME_WAIT sockets
37 | define("n", type=int, default=15000)
38 | define("c", type=int, default=25)
39 | define("keepalive", type=bool, default=False)
40 | define("quiet", type=bool, default=False)
41 |
42 | # Repeat the entire benchmark this many times (on different ports)
43 | # This gives JITs time to warm up, etc. Pypy needs 3-5 runs at
44 | # --n=15000 for its JIT to reach full effectiveness
45 | define("num_runs", type=int, default=1)
46 |
47 | define("ioloop", type=str, default=None)
48 |
49 | class RootHandler(RequestHandler):
50 | def get(self):
51 | self.write("Hello, world")
52 |
53 | def _log(self):
54 | pass
55 |
56 | def handle_sigchld(sig, frame):
57 | IOLoop.instance().add_callback_from_signal(IOLoop.instance().stop)
58 |
59 | def main():
60 | parse_command_line()
61 | if options.ioloop:
62 | IOLoop.configure(options.ioloop)
63 | for i in xrange(options.num_runs):
64 | run()
65 |
66 | def run():
67 | app = Application([("/", RootHandler)])
68 | port = random.randrange(options.min_port, options.max_port)
69 | app.listen(port, address='127.0.0.1')
70 | signal.signal(signal.SIGCHLD, handle_sigchld)
71 | args = ["ab"]
72 | args.extend(["-n", str(options.n)])
73 | args.extend(["-c", str(options.c)])
74 | if options.keepalive:
75 | args.append("-k")
76 | if options.quiet:
77 | # just stops the progress messages printed to stderr
78 | args.append("-q")
79 | args.append("http://127.0.0.1:%d/" % port)
80 | subprocess.Popen(args)
81 | IOLoop.instance().start()
82 | IOLoop.instance().close()
83 | del IOLoop._instance
84 | assert not IOLoop.initialized()
85 |
86 | if __name__ == '__main__':
87 | main()
88 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/benchmark/chunk_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Downloads a large file in chunked encoding with both curl and simple clients
4 |
5 | import logging
6 | from tornado.curl_httpclient import CurlAsyncHTTPClient
7 | from tornado.simple_httpclient import SimpleAsyncHTTPClient
8 | from tornado.ioloop import IOLoop
9 | from tornado.options import define, options, parse_command_line
10 | from tornado.web import RequestHandler, Application
11 |
12 | define('port', default=8888)
13 | define('num_chunks', default=1000)
14 | define('chunk_size', default=2048)
15 |
16 |
17 | class ChunkHandler(RequestHandler):
18 | def get(self):
19 | for i in xrange(options.num_chunks):
20 | self.write('A' * options.chunk_size)
21 | self.flush()
22 | self.finish()
23 |
24 |
25 | def main():
26 | parse_command_line()
27 | app = Application([('/', ChunkHandler)])
28 | app.listen(options.port, address='127.0.0.1')
29 |
30 | def callback(response):
31 | response.rethrow()
32 | assert len(response.body) == (options.num_chunks * options.chunk_size)
33 | logging.warning("fetch completed in %s seconds", response.request_time)
34 | IOLoop.current().stop()
35 |
36 | logging.warning("Starting fetch with curl client")
37 | curl_client = CurlAsyncHTTPClient()
38 | curl_client.fetch('http://localhost:%d/' % options.port,
39 | callback=callback)
40 | IOLoop.current().start()
41 |
42 | logging.warning("Starting fetch with simple client")
43 | simple_client = SimpleAsyncHTTPClient()
44 | simple_client.fetch('http://localhost:%d/' % options.port,
45 | callback=callback)
46 | IOLoop.current().start()
47 |
48 |
49 | if __name__ == '__main__':
50 | main()
51 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/benchmark/gen_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # A simple benchmark of the tornado.gen module.
4 | # Runs in two modes, testing new-style (@coroutine and Futures)
5 | # and old-style (@engine and Tasks) coroutines.
6 |
7 | from timeit import Timer
8 |
9 | from tornado import gen
10 | from tornado.options import options, define, parse_command_line
11 |
12 | define('num', default=10000, help='number of iterations')
13 |
14 | # These benchmarks are delicate. They hit various fast-paths in the gen
15 | # machinery in order to stay synchronous so we don't need an IOLoop.
16 | # This removes noise from the results, but it's easy to change things
17 | # in a way that completely invalidates the results.
18 |
19 | @gen.engine
20 | def e2(callback):
21 | callback()
22 |
23 | @gen.engine
24 | def e1():
25 | for i in range(10):
26 | yield gen.Task(e2)
27 |
28 | @gen.coroutine
29 | def c2():
30 | pass
31 |
32 | @gen.coroutine
33 | def c1():
34 | for i in range(10):
35 | yield c2()
36 |
37 | def main():
38 | parse_command_line()
39 | t = Timer(e1)
40 | results = t.timeit(options.num) / options.num
41 | print('engine: %0.3f ms per iteration' % (results * 1000))
42 | t = Timer(c1)
43 | results = t.timeit(options.num) / options.num
44 | print('coroutine: %0.3f ms per iteration' % (results * 1000))
45 |
46 | if __name__ == '__main__':
47 | main()
48 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/benchmark/stack_context_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Benchmark for stack_context functionality."""
3 | import collections
4 | import contextlib
5 | import functools
6 | import subprocess
7 | import sys
8 |
9 | from tornado import stack_context
10 |
11 | class Benchmark(object):
12 | def enter_exit(self, count):
13 | """Measures the overhead of the nested "with" statements
14 | when using many contexts.
15 | """
16 | if count < 0:
17 | return
18 | with self.make_context():
19 | self.enter_exit(count - 1)
20 |
21 | def call_wrapped(self, count):
22 | """Wraps and calls a function at each level of stack depth
23 | to measure the overhead of the wrapped function.
24 | """
25 | # This queue is analogous to IOLoop.add_callback, but lets us
26 | # benchmark the stack_context in isolation without system call
27 | # overhead.
28 | queue = collections.deque()
29 | self.call_wrapped_inner(queue, count)
30 | while queue:
31 | queue.popleft()()
32 |
33 | def call_wrapped_inner(self, queue, count):
34 | if count < 0:
35 | return
36 | with self.make_context():
37 | queue.append(stack_context.wrap(
38 | functools.partial(self.call_wrapped_inner, queue, count - 1)))
39 |
40 | class StackBenchmark(Benchmark):
41 | def make_context(self):
42 | return stack_context.StackContext(self.__context)
43 |
44 | @contextlib.contextmanager
45 | def __context(self):
46 | yield
47 |
48 | class ExceptionBenchmark(Benchmark):
49 | def make_context(self):
50 | return stack_context.ExceptionStackContext(self.__handle_exception)
51 |
52 | def __handle_exception(self, typ, value, tb):
53 | pass
54 |
55 | def main():
56 | base_cmd = [
57 | sys.executable, '-m', 'timeit', '-s',
58 | 'from stack_context_benchmark import StackBenchmark, ExceptionBenchmark']
59 | cmds = [
60 | 'StackBenchmark().enter_exit(50)',
61 | 'StackBenchmark().call_wrapped(50)',
62 | 'StackBenchmark().enter_exit(500)',
63 | 'StackBenchmark().call_wrapped(500)',
64 |
65 | 'ExceptionBenchmark().enter_exit(50)',
66 | 'ExceptionBenchmark().call_wrapped(50)',
67 | 'ExceptionBenchmark().enter_exit(500)',
68 | 'ExceptionBenchmark().call_wrapped(500)',
69 | ]
70 | for cmd in cmds:
71 | print(cmd)
72 | subprocess.check_call(base_cmd + [cmd])
73 |
74 | if __name__ == '__main__':
75 | main()
76 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/benchmark/template_benchmark.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # A simple benchmark of tornado template rendering, based on
4 | # https://github.com/mitsuhiko/jinja2/blob/master/examples/bench.py
5 |
6 | import sys
7 | from timeit import Timer
8 |
9 | from tornado.options import options, define, parse_command_line
10 | from tornado.template import Template
11 |
12 | define('num', default=100, help='number of iterations')
13 | define('dump', default=False, help='print template generated code and exit')
14 |
15 | context = {
16 | 'page_title': 'mitsuhiko\'s benchmark',
17 | 'table': [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) for x in range(1000)]
18 | }
19 |
20 | tmpl = Template("""\
21 |
22 |
23 |
24 | {{ page_title }}
25 |
26 |
27 |
30 |
31 | {% for href, caption in [ \
32 | ('index.html', 'Index'), \
33 | ('downloads.html', 'Downloads'), \
34 | ('products.html', 'Products') \
35 | ] %}
36 | {{ caption }}
37 | {% end %}
38 |
39 |
40 |
41 | {% for row in table %}
42 |
43 | {% for cell in row %}
44 | {{ cell }}
45 | {% end %}
46 |
47 | {% end %}
48 |
49 |
50 |
51 | \
52 | """)
53 |
54 | def render():
55 | tmpl.generate(**context)
56 |
57 | def main():
58 | parse_command_line()
59 | if options.dump:
60 | print(tmpl.code)
61 | sys.exit(0)
62 | t = Timer(render)
63 | results = t.timeit(options.num) / options.num
64 | print('%0.3f ms per iteration' % (results*1000))
65 |
66 | if __name__ == '__main__':
67 | main()
68 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:2.7
2 |
3 | EXPOSE 8888
4 |
5 | RUN apt-get update && apt-get install -y mysql-client
6 |
7 | # based on python:2.7-onbuild, but if we use that image directly
8 | # the above apt-get line runs too late.
9 | RUN mkdir -p /usr/src/app
10 | WORKDIR /usr/src/app
11 |
12 | COPY requirements.txt /usr/src/app/
13 | RUN pip install -r requirements.txt
14 |
15 | COPY . /usr/src/app
16 |
17 | CMD python blog.py --mysql_host=mysql
18 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/README:
--------------------------------------------------------------------------------
1 | Running the Tornado Blog example app
2 | ====================================
3 | This demo is a simple blogging engine that uses MySQL to store posts and
4 | Google Accounts for author authentication. Since it depends on MySQL, you
5 | need to set up MySQL and the database schema for the demo to run.
6 |
7 | If you have `docker` and `docker-compose` installed, the demo and all
8 | its prerequisites can be installed with `docker-compose up`.
9 |
10 | 1. Install prerequisites and build tornado
11 |
12 | See http://www.tornadoweb.org/ for installation instructions. If you can
13 | run the "helloworld" example application, your environment is set up
14 | correctly.
15 |
16 | 2. Install MySQL if needed
17 |
18 | Consult the documentation for your platform. Under Ubuntu Linux you
19 | can run "apt-get install mysql". Under OS X you can download the
20 | MySQL PKG file from http://dev.mysql.com/downloads/mysql/
21 |
22 | 3. Install Python prerequisites
23 |
24 | Install the packages MySQL-python, torndb, and markdown (e.g. using pip or
25 | easy_install). Note that these packages currently only work on
26 | Python 2. Tornado supports Python 3, but this blog demo does not.
27 |
28 | 3. Connect to MySQL and create a database and user for the blog.
29 |
30 | Connect to MySQL as a user that can create databases and users:
31 | mysql -u root
32 |
33 | Create a database named "blog":
34 | mysql> CREATE DATABASE blog;
35 |
36 | Allow the "blog" user to connect with the password "blog":
37 | mysql> GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog';
38 |
39 | 4. Create the tables in your new database.
40 |
41 | You can use the provided schema.sql file by running this command:
42 | mysql --user=blog --password=blog --database=blog < schema.sql
43 |
44 | You can run the above command again later if you want to delete the
45 | contents of the blog and start over after testing.
46 |
47 | 5. Run the blog example
48 |
49 | With the default user, password, and database you can just run:
50 | ./blog.py
51 |
52 | If you've changed anything, you can alter the default MySQL settings
53 | with arguments on the command line, e.g.:
54 | ./blog.py --mysql_user=casey --mysql_password=happiness --mysql_database=foodblog
55 |
56 | 6. Visit your new blog
57 |
58 | Open http://localhost:8888/ in your web browser. You will be redirected to
59 | a Google account sign-in page because the blog uses Google accounts for
60 | authentication.
61 |
62 | Currently the first user to connect will automatically be given the
63 | ability to create and edit posts.
64 |
65 | Once you've created one blog post, subsequent users will not be
66 | prompted to sign in.
67 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/docker-compose.yml:
--------------------------------------------------------------------------------
1 | mysql:
2 | image: mysql:5.6
3 | environment:
4 | MYSQL_ROOT_PASSWORD: its_a_secret_to_everybody
5 | MYSQL_USER: blog
6 | MYSQL_PASSWORD: blog
7 | MYSQL_DATABASE: blog
8 | ports:
9 | - "3306"
10 | blog:
11 | build: .
12 | links:
13 | - mysql
14 | ports:
15 | - "8888:8888"
16 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/requirements.txt:
--------------------------------------------------------------------------------
1 | bcrypt
2 | futures
3 | MySQL-python
4 | markdown
5 | tornado
6 | torndb
7 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/schema.sql:
--------------------------------------------------------------------------------
1 | -- Copyright 2009 FriendFeed
2 | --
3 | -- Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | -- not use this file except in compliance with the License. You may obtain
5 | -- a copy of the License at
6 | --
7 | -- http://www.apache.org/licenses/LICENSE-2.0
8 | --
9 | -- Unless required by applicable law or agreed to in writing, software
10 | -- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | -- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | -- License for the specific language governing permissions and limitations
13 | -- under the License.
14 |
15 | -- To create the database:
16 | -- CREATE DATABASE blog;
17 | -- GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog';
18 | --
19 | -- To reload the tables:
20 | -- mysql --user=blog --password=blog --database=blog < schema.sql
21 |
22 | SET SESSION storage_engine = "InnoDB";
23 | SET SESSION time_zone = "+0:00";
24 | ALTER DATABASE CHARACTER SET "utf8";
25 |
26 | DROP TABLE IF EXISTS entries;
27 | CREATE TABLE entries (
28 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
29 | author_id INT NOT NULL REFERENCES authors(id),
30 | slug VARCHAR(100) NOT NULL UNIQUE,
31 | title VARCHAR(512) NOT NULL,
32 | markdown MEDIUMTEXT NOT NULL,
33 | html MEDIUMTEXT NOT NULL,
34 | published DATETIME NOT NULL,
35 | updated TIMESTAMP NOT NULL,
36 | KEY (published)
37 | );
38 |
39 | DROP TABLE IF EXISTS authors;
40 | CREATE TABLE authors (
41 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
42 | email VARCHAR(100) NOT NULL UNIQUE,
43 | name VARCHAR(100) NOT NULL,
44 | hashed_password VARCHAR(100) NOT NULL
45 | );
46 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/static/blog.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Facebook
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | color: black;
20 | margin: 15px;
21 | margin-top: 0;
22 | }
23 |
24 | body,
25 | input,
26 | textarea {
27 | font-family: Georgia, serif;
28 | font-size: 12pt;
29 | }
30 |
31 | table {
32 | border-collapse: collapse;
33 | border: 0;
34 | }
35 |
36 | td {
37 | border: 0;
38 | padding: 0;
39 | }
40 |
41 | h1,
42 | h2,
43 | h3,
44 | h4 {
45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
46 | margin: 0;
47 | }
48 |
49 | h1 {
50 | font-size: 20pt;
51 | }
52 |
53 | pre,
54 | code {
55 | font-family: monospace;
56 | color: #060;
57 | }
58 |
59 | pre {
60 | margin-left: 1em;
61 | padding-left: 1em;
62 | border-left: 1px solid silver;
63 | line-height: 14pt;
64 | }
65 |
66 | a,
67 | a code {
68 | color: #00c;
69 | }
70 |
71 | #body {
72 | max-width: 800px;
73 | margin: auto;
74 | }
75 |
76 | #header {
77 | background-color: #3b5998;
78 | padding: 5px;
79 | padding-left: 10px;
80 | padding-right: 10px;
81 | margin-bottom: 1em;
82 | }
83 |
84 | #header,
85 | #header a {
86 | color: white;
87 | }
88 |
89 | #header h1 a {
90 | text-decoration: none;
91 | }
92 |
93 | #footer,
94 | #content {
95 | margin-left: 10px;
96 | margin-right: 10px;
97 | }
98 |
99 | #footer {
100 | margin-top: 3em;
101 | }
102 |
103 | .entry h1 a {
104 | color: black;
105 | text-decoration: none;
106 | }
107 |
108 | .entry {
109 | margin-bottom: 2em;
110 | }
111 |
112 | .entry .date {
113 | margin-top: 3px;
114 | }
115 |
116 | .entry p {
117 | margin: 0;
118 | margin-bottom: 1em;
119 | }
120 |
121 | .entry .body {
122 | margin-top: 1em;
123 | line-height: 16pt;
124 | }
125 |
126 | .compose td {
127 | vertical-align: middle;
128 | padding-bottom: 5px;
129 | }
130 |
131 | .compose td.field {
132 | padding-right: 10px;
133 | }
134 |
135 | .compose .title,
136 | .compose .submit {
137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif;
138 | font-weight: bold;
139 | }
140 |
141 | .compose .title {
142 | font-size: 20pt;
143 | }
144 |
145 | .compose .title,
146 | .compose .markdown {
147 | width: 100%;
148 | }
149 |
150 | .compose .markdown {
151 | height: 500px;
152 | line-height: 16pt;
153 | }
154 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/archive.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head %}
4 |
20 | {% end %}
21 |
22 | {% block body %}
23 |
31 | {% end %}
32 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ escape(handler.settings["blog_title"]) }}
6 |
7 |
8 | {% block head %}{% end %}
9 |
10 |
11 |
12 |
23 |
{% block body %}{% end %}
24 |
25 | {% block bottom %}{% end %}
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/compose.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 |
5 |
6 | {{ entry.markdown if entry else "" }}
7 |
12 | {% if entry %}
13 |
14 | {% end %}
15 | {% module xsrf_form_html() %}
16 |
17 | {% end %}
18 |
19 | {% block bottom %}
20 |
21 |
41 | {% end %}
42 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/create_author.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 |
5 | Email:
6 | Name:
7 | Password:
8 | {% module xsrf_form_html() %}
9 |
10 |
11 | {% end %}
12 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/entry.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% module Entry(entry) %}
5 | {% end %}
6 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %}
4 | {{ handler.settings["blog_title"] }}
5 | {% if len(entries) > 0 %}
6 | {{ max(e.updated for e in entries).strftime(date_format) }}
7 | {% else %}
8 | {{ datetime.datetime.utcnow().strftime(date_format) }}
9 | {% end %}
10 | http://{{ request.host }}/
11 |
12 |
13 | {{ handler.settings["blog_title"] }}
14 | {% for entry in entries %}
15 |
16 | http://{{ request.host }}/entry/{{ entry.slug }}
17 | {{ entry.title }}
18 |
19 | {{ entry.updated.strftime(date_format) }}
20 | {{ entry.published.strftime(date_format) }}
21 |
22 | {% raw entry.html %}
23 |
24 |
25 | {% end %}
26 |
27 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% for entry in entries %}
5 | {% module Entry(entry) %}
6 | {% end %}
7 |
8 | {% end %}
9 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/login.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block body %}
4 | {% if error %}
5 | Error: {{ error }}
6 | {% end %}
7 |
8 |
9 | Email:
10 | Password:
11 | {% module xsrf_form_html() %}
12 |
13 |
14 | {% end %}
15 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/blog/templates/modules/entry.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user %}
6 |
7 | {% end %}
8 |
9 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/chat/static/chat.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 FriendFeed
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | margin: 10px;
20 | }
21 |
22 | body,
23 | input {
24 | font-family: sans-serif;
25 | font-size: 10pt;
26 | color: black;
27 | }
28 |
29 | table {
30 | border-collapse: collapse;
31 | border: 0;
32 | }
33 |
34 | td {
35 | border: 0;
36 | padding: 0;
37 | }
38 |
39 | #body {
40 | position: absolute;
41 | bottom: 10px;
42 | left: 10px;
43 | }
44 |
45 | #input {
46 | margin-top: 0.5em;
47 | }
48 |
49 | #inbox .message {
50 | padding-top: 0.25em;
51 | }
52 |
53 | #nav {
54 | float: right;
55 | z-index: 99;
56 | }
57 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/chat/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tornado Chat Demo
6 |
7 |
8 |
9 |
10 |
11 | {% for message in messages %}
12 | {% module Template("message.html", message=message) %}
13 | {% end %}
14 |
15 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/chat/templates/message.html:
--------------------------------------------------------------------------------
1 | {% module linkify(message["body"]) %}
2 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/facebook/README:
--------------------------------------------------------------------------------
1 | Running the Tornado Facebook example
2 | ====================================
3 |
4 | To run this example, you must register a Facebook application with a
5 | Connect URL set to the domain the this demo will be running on
6 | (i.e. http://localhost:8888/ by default). The API key and secret
7 | for this application must be passed on the command line:
8 |
9 | python facebook.py --facebook_api_key=ABC --facebook_secret=XYZ
10 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/facebook/static/facebook.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Facebook
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | color: black;
20 | margin: 15px;
21 | }
22 |
23 | body,
24 | input,
25 | textarea {
26 | font-family: "Lucida Grande", Tahoma, Verdana, sans-serif;
27 | font-size: 10pt;
28 | }
29 |
30 | table {
31 | border-collapse: collapse;
32 | border: 0;
33 | }
34 |
35 | td {
36 | border: 0;
37 | padding: 0;
38 | }
39 |
40 | img {
41 | border: 0;
42 | }
43 |
44 | a {
45 | text-decoration: none;
46 | color: #3b5998;
47 | }
48 |
49 | a:hover {
50 | text-decoration: underline;
51 | }
52 |
53 | .post {
54 | border-bottom: 1px solid #eeeeee;
55 | min-height: 50px;
56 | padding-bottom: 10px;
57 | margin-top: 10px;
58 | }
59 |
60 | .post .picture {
61 | float: left;
62 | }
63 |
64 | .post .picture img {
65 | height: 50px;
66 | width: 50px;
67 | }
68 |
69 | .post .body {
70 | margin-left: 60px;
71 | }
72 |
73 | .post .media img {
74 | border: 1px solid #cccccc;
75 | padding: 3px;
76 | }
77 |
78 | .post .media:hover img {
79 | border: 1px solid #3b5998;
80 | }
81 |
82 | .post a.actor {
83 | font-weight: bold;
84 | }
85 |
86 | .post .meta {
87 | font-size: 11px;
88 | }
89 |
90 | .post a.permalink {
91 | color: #777777;
92 | }
93 |
94 | #body {
95 | max-width: 700px;
96 | margin: auto;
97 | }
98 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/facebook/static/facebook.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/demos/facebook/static/facebook.js
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/facebook/templates/modules/post.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% set author_url="http://www.facebook.com/profile.php?id=" + escape(post["from"]["id"]) %}
4 |
5 |
6 |
7 |
{{ escape(post["from"]["name"]) }}
8 | {% if "message" in post %}
9 |
{{ escape(post["message"]) }}
10 | {% end %}
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/facebook/templates/stream.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tornado Facebook Stream Demo
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 | {% for post in stream["data"] %}
17 | {{ modules.Post(post) }}
18 | {% end %}
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/helloworld/helloworld.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2009 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | import tornado.httpserver
18 | import tornado.ioloop
19 | import tornado.options
20 | import tornado.web
21 |
22 | from tornado.options import define, options
23 |
24 | define("port", default=8888, help="run on the given port", type=int)
25 |
26 |
27 | class MainHandler(tornado.web.RequestHandler):
28 | def get(self):
29 | self.write("Hello, world")
30 |
31 |
32 | def main():
33 | tornado.options.parse_command_line()
34 | application = tornado.web.Application([
35 | (r"/", MainHandler),
36 | ])
37 | http_server = tornado.httpserver.HTTPServer(application)
38 | http_server.listen(options.port)
39 | tornado.ioloop.IOLoop.current().start()
40 |
41 |
42 | if __name__ == "__main__":
43 | main()
44 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/twitter/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tornado Twitter Demo
4 |
5 |
6 |
7 | {% for tweet in timeline %}
8 | {{ tweet['user']['screen_name'] }} : {{ tweet['text'] }}
9 | {% end %}
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/websocket/static/chat.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 FriendFeed
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 | * not use this file except in compliance with the License. You may obtain
6 | * a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | body {
18 | background: white;
19 | margin: 10px;
20 | }
21 |
22 | body,
23 | input {
24 | font-family: sans-serif;
25 | font-size: 10pt;
26 | color: black;
27 | }
28 |
29 | table {
30 | border-collapse: collapse;
31 | border: 0;
32 | }
33 |
34 | td {
35 | border: 0;
36 | padding: 0;
37 | }
38 |
39 | #body {
40 | position: absolute;
41 | bottom: 10px;
42 | left: 10px;
43 | }
44 |
45 | #input {
46 | margin-top: 0.5em;
47 | }
48 |
49 | #inbox .message {
50 | padding-top: 0.25em;
51 | }
52 |
53 | #nav {
54 | float: right;
55 | z-index: 99;
56 | }
57 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/websocket/static/chat.js:
--------------------------------------------------------------------------------
1 | // Copyright 2009 FriendFeed
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | $(document).ready(function() {
16 | if (!window.console) window.console = {};
17 | if (!window.console.log) window.console.log = function() {};
18 |
19 | $("#messageform").live("submit", function() {
20 | newMessage($(this));
21 | return false;
22 | });
23 | $("#messageform").live("keypress", function(e) {
24 | if (e.keyCode == 13) {
25 | newMessage($(this));
26 | return false;
27 | }
28 | });
29 | $("#message").select();
30 | updater.start();
31 | });
32 |
33 | function newMessage(form) {
34 | var message = form.formToDict();
35 | updater.socket.send(JSON.stringify(message));
36 | form.find("input[type=text]").val("").select();
37 | }
38 |
39 | jQuery.fn.formToDict = function() {
40 | var fields = this.serializeArray();
41 | var json = {}
42 | for (var i = 0; i < fields.length; i++) {
43 | json[fields[i].name] = fields[i].value;
44 | }
45 | if (json.next) delete json.next;
46 | return json;
47 | };
48 |
49 | var updater = {
50 | socket: null,
51 |
52 | start: function() {
53 | var url = "ws://" + location.host + "/chatsocket";
54 | updater.socket = new WebSocket(url);
55 | updater.socket.onmessage = function(event) {
56 | updater.showMessage(JSON.parse(event.data));
57 | }
58 | },
59 |
60 | showMessage: function(message) {
61 | var existing = $("#m" + message.id);
62 | if (existing.length > 0) return;
63 | var node = $(message.html);
64 | node.hide();
65 | $("#inbox").append(node);
66 | node.slideDown();
67 | }
68 | };
69 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/websocket/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Tornado Chat Demo
6 |
7 |
8 |
9 |
10 |
11 | {% for message in messages %}
12 | {% include "message.html" %}
13 | {% end %}
14 |
15 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/websocket/templates/message.html:
--------------------------------------------------------------------------------
1 | {% module linkify(message["body"]) %}
2 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/demos/webspider/webspider.py:
--------------------------------------------------------------------------------
1 | import HTMLParser
2 | import time
3 | import urlparse
4 | from datetime import timedelta
5 |
6 | from tornado import httpclient, gen, ioloop, queues
7 |
8 | base_url = 'http://www.tornadoweb.org/en/stable/'
9 | concurrency = 10
10 |
11 |
12 | @gen.coroutine
13 | def get_links_from_url(url):
14 | """Download the page at `url` and parse it for links.
15 |
16 | Returned links have had the fragment after `#` removed, and have been made
17 | absolute so, e.g. the URL 'gen.html#tornado.gen.coroutine' becomes
18 | 'http://www.tornadoweb.org/en/stable/gen.html'.
19 | """
20 | try:
21 | response = yield httpclient.AsyncHTTPClient().fetch(url)
22 | print('fetched %s' % url)
23 | urls = [urlparse.urljoin(url, remove_fragment(new_url))
24 | for new_url in get_links(response.body)]
25 | except Exception as e:
26 | print('Exception: %s %s' % (e, url))
27 | raise gen.Return([])
28 |
29 | raise gen.Return(urls)
30 |
31 |
32 | def remove_fragment(url):
33 | scheme, netloc, url, params, query, fragment = urlparse.urlparse(url)
34 | return urlparse.urlunparse((scheme, netloc, url, params, query, ''))
35 |
36 |
37 | def get_links(html):
38 | class URLSeeker(HTMLParser.HTMLParser):
39 | def __init__(self):
40 | HTMLParser.HTMLParser.__init__(self)
41 | self.urls = []
42 |
43 | def handle_starttag(self, tag, attrs):
44 | href = dict(attrs).get('href')
45 | if href and tag == 'a':
46 | self.urls.append(href)
47 |
48 | url_seeker = URLSeeker()
49 | url_seeker.feed(html)
50 | return url_seeker.urls
51 |
52 |
53 | @gen.coroutine
54 | def main():
55 | q = queues.Queue()
56 | start = time.time()
57 | fetching, fetched = set(), set()
58 |
59 | @gen.coroutine
60 | def fetch_url():
61 | current_url = yield q.get()
62 | try:
63 | if current_url in fetching:
64 | return
65 |
66 | print('fetching %s' % current_url)
67 | fetching.add(current_url)
68 | urls = yield get_links_from_url(current_url)
69 | fetched.add(current_url)
70 |
71 | for new_url in urls:
72 | # Only follow links beneath the base URL
73 | if new_url.startswith(base_url):
74 | yield q.put(new_url)
75 |
76 | finally:
77 | q.task_done()
78 |
79 | @gen.coroutine
80 | def worker():
81 | while True:
82 | yield fetch_url()
83 |
84 | q.put(base_url)
85 |
86 | # Start workers, then wait for the work queue to be empty.
87 | for _ in range(concurrency):
88 | worker()
89 | yield q.join(timeout=timedelta(seconds=300))
90 | assert fetching == fetched
91 | print('Done in %d seconds, fetched %s URLs.' % (
92 | time.time() - start, len(fetched)))
93 |
94 |
95 | if __name__ == '__main__':
96 | import logging
97 | logging.basicConfig()
98 | io_loop = ioloop.IOLoop.current()
99 | io_loop.run_sync(main)
100 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/README:
--------------------------------------------------------------------------------
1 | This directory contains tools and scripts that are used in the development
2 | and maintainance of Tornado itself, but are probably not of interest to
3 | Tornado users.
4 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/requirements.txt:
--------------------------------------------------------------------------------
1 | # Frozen pip requirements for tools used in the development of tornado.
2 | # This list is for python 3.4; for 2.7 add:
3 | # - backports.ssl-match-hostname
4 | # - futures
5 | # - mock
6 | #
7 | # Use virtualenv instead of venv; tox seems to get confused otherwise.
8 |
9 | # Tornado's required dependencies
10 | certifi==14.5.14
11 |
12 | # Tornado's optional dependencies
13 | Twisted==15.0.0
14 | # pip on python 3.4 currently has trouble installing pycares.
15 | #pycares==0.6.1
16 | pycurl==7.19.5.1
17 |
18 | # Other useful tools
19 | Sphinx==1.2.3
20 | autopep8==1.1
21 | coverage==3.7.1
22 | flake8==2.3.0
23 | pep8==1.6.0
24 | pyflakes==0.8.1
25 | sphinx-rtd-theme==0.1.6
26 | tox==1.8.1
27 | twine==1.4.0
28 | virtualenv==12.0.7
29 |
30 | # Indirect dependencies
31 | Jinja2==2.7.3
32 | MarkupSafe==0.23
33 | Pygments==2.0.2
34 | docutils==0.12
35 | mccabe==0.3
36 | pkginfo==1.2.1
37 | py==1.4.26
38 | requests==2.5.1
39 | zope.interface==4.1.2
40 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/scripts/custom_fixers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/maint/scripts/custom_fixers/__init__.py
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/scripts/custom_fixers/fix_future_imports.py:
--------------------------------------------------------------------------------
1 | """Updates all source files to import the same set of __future__ directives.
2 | """
3 | from lib2to3 import fixer_base
4 | from lib2to3 import pytree
5 | from lib2to3.pgen2 import token
6 | from lib2to3.fixer_util import FromImport, Name, Comma, Newline
7 |
8 | # copied from fix_tuple_params.py
9 | def is_docstring(stmt):
10 | return isinstance(stmt, pytree.Node) and \
11 | stmt.children[0].type == token.STRING
12 |
13 | class FixFutureImports(fixer_base.BaseFix):
14 | BM_compatible = True
15 |
16 | PATTERN = """import_from< 'from' module_name="__future__" 'import' any >"""
17 |
18 | def start_tree(self, tree, filename):
19 | self.found_future_import = False
20 |
21 | def new_future_import(self, old):
22 | new = FromImport("__future__",
23 | [Name("absolute_import", prefix=" "), Comma(),
24 | Name("division", prefix=" "), Comma(),
25 | Name("print_function", prefix=" "), Comma(),
26 | Name("with_statement", prefix=" ")])
27 | if old is not None:
28 | new.prefix = old.prefix
29 | return new
30 |
31 | def transform(self, node, results):
32 | self.found_future_import = True
33 | return self.new_future_import(node)
34 |
35 | def finish_tree(self, tree, filename):
36 | if self.found_future_import:
37 | return
38 | if not isinstance(tree, pytree.Node):
39 | # Empty files (usually __init__.py) show up as a single Leaf
40 | # instead of a Node, so leave them alone
41 | return
42 | first_stmt = tree.children[0]
43 | if is_docstring(first_stmt):
44 | # Skip a line and add the import after the docstring
45 | tree.insert_child(1, Newline())
46 | pos = 2
47 | elif first_stmt.prefix:
48 | # No docstring, but an initial comment (perhaps a #! line).
49 | # Transfer the initial comment to a new blank line.
50 | newline = Newline()
51 | newline.prefix = first_stmt.prefix
52 | first_stmt.prefix = ""
53 | tree.insert_child(0, newline)
54 | pos = 1
55 | else:
56 | # No comments or docstring, just insert at the start
57 | pos = 0
58 | tree.insert_child(pos, self.new_future_import(None))
59 | tree.insert_child(pos+1, Newline()) # terminates the import stmt
60 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/scripts/custom_fixers/fix_unicode_literal.py:
--------------------------------------------------------------------------------
1 | import re
2 | from lib2to3.pgen2 import token
3 | from lib2to3 import fixer_base
4 | from lib2to3.fixer_util import Name, Call
5 |
6 | _literal_re = re.compile(ur"[uU][rR]?[\'\"]")
7 |
8 | class FixUnicodeLiteral(fixer_base.BaseFix):
9 | BM_compatible = True
10 | PATTERN = """STRING"""
11 |
12 | def transform(self, node, results):
13 | if node.type == token.STRING and _literal_re.match(node.value):
14 | new = node.clone()
15 | new.value = new.value[1:]
16 | new.prefix = ''
17 | node.replace(Call(Name(u'u', prefix=node.prefix), [new]))
18 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/scripts/run_autopep8.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Runs autopep8 in the configuration used for tornado.
4 | #
5 | # W602 is "deprecated form of raising exception", but the fix is incorrect
6 | # (and I'm not sure if the three-argument form of raise is really deprecated
7 | # in the first place)
8 | # E501 is "line longer than 80 chars" but the automated fix is ugly.
9 | # E301 adds a blank line between docstring and first method
10 | # E309 adds a blank line between class declaration and docstring (?)
11 | autopep8 --ignore=W602,E501,E301,E309 -i tornado/*.py tornado/platform/*.py tornado/test/*.py
12 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/scripts/run_fixers.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Usage is like 2to3:
3 | # $ maint/scripts/run_fixers.py -wn --no-diffs tornado
4 |
5 | import sys
6 | from lib2to3.main import main
7 |
8 | sys.exit(main("custom_fixers"))
9 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/scripts/test_resolvers.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from __future__ import print_function
3 |
4 | import pprint
5 | import socket
6 |
7 | from tornado import gen
8 | from tornado.ioloop import IOLoop
9 | from tornado.netutil import Resolver, ThreadedResolver
10 | from tornado.options import parse_command_line, define, options
11 |
12 | try:
13 | import twisted
14 | except ImportError:
15 | twisted = None
16 |
17 | try:
18 | import pycares
19 | except ImportError:
20 | pycares = None
21 |
22 | define('family', default='unspec',
23 | help='Address family to query: unspec, inet, or inet6')
24 |
25 | @gen.coroutine
26 | def main():
27 | args = parse_command_line()
28 |
29 | if not args:
30 | args = ['localhost', 'www.google.com',
31 | 'www.facebook.com', 'www.dropbox.com']
32 |
33 | resolvers = [Resolver(), ThreadedResolver()]
34 |
35 | if twisted is not None:
36 | from tornado.platform.twisted import TwistedResolver
37 | resolvers.append(TwistedResolver())
38 |
39 | if pycares is not None:
40 | from tornado.platform.caresresolver import CaresResolver
41 | resolvers.append(CaresResolver())
42 |
43 | family = {
44 | 'unspec': socket.AF_UNSPEC,
45 | 'inet': socket.AF_INET,
46 | 'inet6': socket.AF_INET6,
47 | }[options.family]
48 |
49 | for host in args:
50 | print('Resolving %s' % host)
51 | for resolver in resolvers:
52 | addrinfo = yield resolver.resolve(host, 80, family)
53 | print('%s: %s' % (resolver.__class__.__name__,
54 | pprint.pformat(addrinfo)))
55 | print()
56 |
57 | if __name__ == '__main__':
58 | IOLoop.instance().run_sync(main)
59 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/README:
--------------------------------------------------------------------------------
1 | This directory contains additional tests that are not included in the main
2 | suite (because e.g. they have extra dependencies, run slowly, or produce
3 | more output than a simple pass/fail)
4 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/README:
--------------------------------------------------------------------------------
1 | Unit test support for app engine. Currently very limited as most of
2 | our tests depend on direct network access, but these tests ensure that the
3 | modules that are supposed to work on app engine don't depend on any
4 | forbidden modules.
5 |
6 | The code lives in maint/appengine/common, but should be run from the py25
7 | or py27 subdirectories (which contain an app.yaml and a bunch of symlinks).
8 | runtests.py is the entry point; cgi_runtests.py is used internally.
9 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/common/cgi_runtests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | import unittest
4 |
5 | # Most of our tests depend on IOLoop, which is not usable on app engine.
6 | # Run the tests that work, and check that everything else is at least
7 | # importable (via tornado.test.import_test)
8 | TEST_MODULES = [
9 | 'tornado.httputil.doctests',
10 | 'tornado.iostream.doctests',
11 | 'tornado.util.doctests',
12 | #'tornado.test.auth_test',
13 | #'tornado.test.concurrent_test',
14 | #'tornado.test.curl_httpclient_test',
15 | 'tornado.test.escape_test',
16 | #'tornado.test.gen_test',
17 | #'tornado.test.httpclient_test',
18 | #'tornado.test.httpserver_test',
19 | 'tornado.test.httputil_test',
20 | 'tornado.test.import_test',
21 | #'tornado.test.ioloop_test',
22 | #'tornado.test.iostream_test',
23 | 'tornado.test.locale_test',
24 | #'tornado.test.netutil_test',
25 | #'tornado.test.log_test',
26 | 'tornado.test.options_test',
27 | #'tornado.test.process_test',
28 | #'tornado.test.simple_httpclient_test',
29 | #'tornado.test.stack_context_test',
30 | 'tornado.test.template_test',
31 | #'tornado.test.testing_test',
32 | #'tornado.test.twisted_test',
33 | 'tornado.test.util_test',
34 | #'tornado.test.web_test',
35 | #'tornado.test.websocket_test',
36 | #'tornado.test.wsgi_test',
37 | ]
38 |
39 | def all():
40 | return unittest.defaultTestLoader.loadTestsFromNames(TEST_MODULES)
41 |
42 | def main():
43 | print "Content-Type: text/plain\r\n\r\n",
44 |
45 | try:
46 | unittest.main(defaultTest='all', argv=sys.argv[:1])
47 | except SystemExit, e:
48 | if e.code == 0:
49 | print "PASS"
50 | else:
51 | raise
52 |
53 | if __name__ == '__main__':
54 | main()
55 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/common/runtests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from __future__ import with_statement
3 |
4 | import contextlib
5 | import errno
6 | import os
7 | import random
8 | import signal
9 | import socket
10 | import subprocess
11 | import sys
12 | import time
13 | import urllib2
14 |
15 | if __name__ == "__main__":
16 | tornado_root = os.path.abspath(os.path.join(os.path.dirname(__file__),
17 | '../../..'))
18 | # dev_appserver doesn't seem to set SO_REUSEADDR
19 | port = random.randrange(10000, 11000)
20 | # does dev_appserver.py ever live anywhere but /usr/local/bin?
21 | proc = subprocess.Popen([sys.executable,
22 | "/usr/local/bin/dev_appserver.py",
23 | os.path.dirname(os.path.abspath(__file__)),
24 | "--port=%d" % port,
25 | "--skip_sdk_update_check",
26 | ],
27 | cwd=tornado_root)
28 |
29 | try:
30 | for i in xrange(50):
31 | with contextlib.closing(socket.socket()) as sock:
32 | err = sock.connect_ex(('localhost', port))
33 | if err == 0:
34 | break
35 | elif err != errno.ECONNREFUSED:
36 | raise Exception("Got unexpected socket error %d" % err)
37 | time.sleep(0.1)
38 | else:
39 | raise Exception("Server didn't start listening")
40 |
41 | resp = urllib2.urlopen("http://localhost:%d/" % port)
42 | print resp.read()
43 | finally:
44 | # dev_appserver sometimes ignores SIGTERM (especially on 2.5),
45 | # so try a few times to kill it.
46 | for sig in [signal.SIGTERM, signal.SIGTERM, signal.SIGKILL]:
47 | os.kill(proc.pid, sig)
48 | res = os.waitpid(proc.pid, os.WNOHANG)
49 | if res != (0,0):
50 | break
51 | time.sleep(0.1)
52 | else:
53 | os.waitpid(proc.pid, 0)
54 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/py27/app.yaml:
--------------------------------------------------------------------------------
1 | application: tornado-tests-appengine27
2 | version: 1
3 | runtime: python27
4 | threadsafe: false
5 | api_version: 1
6 |
7 | handlers:
8 | - url: /
9 | script: cgi_runtests.py
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/py27/cgi_runtests.py:
--------------------------------------------------------------------------------
1 | ../common/cgi_runtests.py
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/py27/runtests.py:
--------------------------------------------------------------------------------
1 | ../common/runtests.py
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/py27/tornado:
--------------------------------------------------------------------------------
1 | ../../../../tornado
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/setup.py:
--------------------------------------------------------------------------------
1 | # Dummy setup file to make tox happy. In the appengine world things aren't
2 | # installed through setup.py
3 | import distutils.core
4 | distutils.core.setup()
5 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/appengine/tox.ini:
--------------------------------------------------------------------------------
1 | # App Engine tests require the SDK to be installed separately.
2 | # Version 1.6.1 or newer is required (older versions don't work when
3 | # python is run from a virtualenv)
4 | #
5 | # These are currently excluded from the main tox.ini because their
6 | # logs are spammy and they're a little flaky.
7 | [tox]
8 | envlist = py27-appengine
9 |
10 | [testenv]
11 | changedir = {toxworkdir}
12 |
13 | [testenv:py27-appengine]
14 | basepython = python2.7
15 | commands = python {toxinidir}/py27/runtests.py {posargs:}
16 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/pyuv/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27
3 | setupdir = ../../..
4 |
5 | [testenv]
6 | commands =
7 | python -m tornado.test.runtests --ioloop=tornado_pyuv.UVLoop {posargs:}
8 | # twisted tests don't work on pyuv IOLoop currently.
9 | deps =
10 | pyuv
11 | git+https://github.com/saghul/tornado-pyuv.git
12 | futures
13 | mock
14 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/redbot/README:
--------------------------------------------------------------------------------
1 | Redbot is an HTTP validator that checks for common problems, especially
2 | related to cacheability. These tests ensure that Tornado's default behavior
3 | is correct (but note that this guarantee does not automatically extend
4 | to applications built on Tornado since application behavior can impact
5 | cacheability.
6 |
7 | http://redbot.org/about
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/redbot/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27
3 | setupdir=../../..
4 |
5 | [testenv]
6 | commands = python red_test.py
7 | deps =
8 | # Newer versions of thor have a bug with redbot (5/18/13)
9 | thor==0.2.0
10 | git+https://github.com/mnot/redbot.git
11 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/.gitignore:
--------------------------------------------------------------------------------
1 | reports/
2 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/client.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import logging
4 |
5 | from tornado import gen
6 | from tornado.ioloop import IOLoop
7 | from tornado.options import define, options, parse_command_line
8 | from tornado.websocket import websocket_connect
9 |
10 | define('url', default='ws://localhost:9001')
11 | define('name', default='Tornado')
12 |
13 | @gen.engine
14 | def run_tests():
15 | url = options.url + '/getCaseCount'
16 | control_ws = yield websocket_connect(url, None)
17 | num_tests = int((yield control_ws.read_message()))
18 | logging.info('running %d cases', num_tests)
19 | msg = yield control_ws.read_message()
20 | assert msg is None
21 |
22 | for i in range(1, num_tests + 1):
23 | logging.info('running test case %d', i)
24 | url = options.url + '/runCase?case=%d&agent=%s' % (i, options.name)
25 | test_ws = yield websocket_connect(url, None, compression_options={})
26 | while True:
27 | message = yield test_ws.read_message()
28 | if message is None:
29 | break
30 | test_ws.write_message(message, binary=isinstance(message, bytes))
31 |
32 | url = options.url + '/updateReports?agent=%s' % options.name
33 | update_ws = yield websocket_connect(url, None)
34 | msg = yield update_ws.read_message()
35 | assert msg is None
36 | IOLoop.instance().stop()
37 |
38 | def main():
39 | parse_command_line()
40 |
41 | IOLoop.instance().add_callback(run_tests)
42 |
43 | IOLoop.instance().start()
44 |
45 | if __name__ == '__main__':
46 | main()
47 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/fuzzingclient.json:
--------------------------------------------------------------------------------
1 | {
2 | "options": {"failByDrop": false},
3 | "outdir": "./reports/servers",
4 |
5 | "servers": [
6 | {"agent": "Tornado/py26", "url": "ws://localhost:9001",
7 | "options": {"version": 18}},
8 | {"agent": "Tornado/py27", "url": "ws://localhost:9002",
9 | "options": {"version": 18}},
10 | {"agent": "Tornado/py32", "url": "ws://localhost:9003",
11 | "options": {"version": 18}},
12 | {"agent": "Tornado/pypy", "url": "ws://localhost:9004",
13 | "options": {"version": 18}}
14 | ],
15 |
16 | "cases": ["*"],
17 | "exclude-cases": ["9.*", "12.*.1","12.2.*", "12.3.*", "12.4.*", "12.5.*", "13.*.1"],
18 | "exclude-agent-cases": {}
19 | }
20 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/fuzzingserver.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "url": "ws://localhost:9001",
4 |
5 | "options": {"failByDrop": false},
6 | "outdir": "./reports/clients",
7 | "webport": 8080,
8 |
9 | "cases": ["*"],
10 | "exclude-cases": ["9.*", "12.*.1","12.2.*", "12.3.*", "12.4.*", "12.5.*", "13.*.1"],
11 | "exclude-agent-cases": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/run-client.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | tox
6 |
7 | .tox/py27/bin/wstest -m fuzzingserver &
8 | FUZZING_SERVER_PID=$!
9 |
10 | sleep 1
11 |
12 | .tox/py26/bin/python client.py --name='Tornado/py26'
13 | .tox/py27/bin/python client.py --name='Tornado/py27'
14 | .tox/py32/bin/python client.py --name='Tornado/py32'
15 | .tox/pypy/bin/python client.py --name='Tornado/pypy'
16 |
17 | kill $FUZZING_SERVER_PID
18 | wait
19 |
20 | echo "Tests complete. Output is in ./reports/clients/index.html"
21 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/run-server.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Runs the autobahn websocket conformance test against tornado in both
4 | # python2 and python3. Output goes in ./reports/servers/index.html.
5 | #
6 | # The --cases and --exclude arguments can be used to run only part of
7 | # the suite. The default is --exclude="9.*" to skip the relatively slow
8 | # performance tests; pass --exclude="" to override and include them.
9 |
10 | set -e
11 |
12 | # build/update the virtualenvs
13 | tox
14 |
15 | .tox/py26/bin/python server.py --port=9001 &
16 | PY26_SERVER_PID=$!
17 |
18 | .tox/py27/bin/python server.py --port=9002 &
19 | PY27_SERVER_PID=$!
20 |
21 | .tox/py32/bin/python server.py --port=9003 &
22 | PY32_SERVER_PID=$!
23 |
24 | .tox/pypy/bin/python server.py --port=9004 &
25 | PYPY_SERVER_PID=$!
26 |
27 | sleep 1
28 |
29 | .tox/py27/bin/wstest -m fuzzingclient
30 |
31 | kill $PY26_SERVER_PID
32 | kill $PY27_SERVER_PID
33 | kill $PY32_SERVER_PID
34 | kill $PYPY_SERVER_PID
35 | wait
36 |
37 | echo "Tests complete. Output is in ./reports/servers/index.html"
38 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from tornado.ioloop import IOLoop
4 | from tornado.options import define, options, parse_command_line
5 | from tornado.websocket import WebSocketHandler
6 | from tornado.web import Application
7 |
8 | define('port', default=9000)
9 |
10 | class EchoHandler(WebSocketHandler):
11 | def on_message(self, message):
12 | self.write_message(message, binary=isinstance(message, bytes))
13 |
14 | def get_compression_options(self):
15 | return {}
16 |
17 | if __name__ == '__main__':
18 | parse_command_line()
19 | app = Application([
20 | ('/', EchoHandler),
21 | ])
22 | app.listen(options.port, address='127.0.0.1')
23 | IOLoop.instance().start()
24 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/test/websocket/tox.ini:
--------------------------------------------------------------------------------
1 | # We don't actually use tox to run this test, but it's the easiest way
2 | # to install autobahn and build the speedups module.
3 | # See run.sh for the real test runner.
4 | [tox]
5 | envlist = py27, py32, py26, pypy
6 | setupdir=../../..
7 |
8 | [testenv]
9 | commands = python -c pass
10 |
11 | [testenv:py27]
12 | deps = autobahntestsuite
13 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/README:
--------------------------------------------------------------------------------
1 | This directory contains virtual machine setup scripts for testing Tornado.
2 |
3 | Requirements:
4 |
5 | Vagrant (http://vagrantup.com) and VirtualBox (http://virtualbox.org).
6 | Vagrant provides an easy download for Ubuntu 10.04 (aka lucid64); base
7 | images for other platforms are harder to find and can be built with
8 | VeeWee (https://github.com/jedi4ever/veewee).
9 |
10 | Usage:
11 |
12 | cd to the appropriate directory and run `vagrant up`, then `vagrant ssh`.
13 | From there, simply run `tox` to run the full test suite, or cd to /tornado
14 | and test manually. Afterwards, use `vagrant suspend` or `vagrant destroy`
15 | to clean up.
16 |
17 | Notes:
18 |
19 | Python distutils (and therefore tox) assume that if the platform
20 | supports hard links, they can be used in the Tornado source directory.
21 | VirtualBox's shared folder filesystem does not support hard links (or
22 | symlinks), so we have to use NFS shared folders instead. (which has
23 | the unfortunate side effect of requiring sudo on the host machine)
24 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/freebsd/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5 | VAGRANTFILE_API_VERSION = "2"
6 |
7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8 | config.vm.box = "chef/freebsd-10.0"
9 |
10 | config.vm.network "private_network", type: "dhcp"
11 |
12 | # Share an additional folder to the guest VM. The first argument is
13 | # the path on the host to the actual folder. The second argument is
14 | # the path on the guest to mount the folder. And the optional third
15 | # argument is a set of non-required options.
16 | config.vm.synced_folder "../../..", "/tornado", type: "nfs"
17 |
18 | # Override the default /vagrant mapping to use nfs, since freebsd doesn't
19 | # support other folder types.
20 | config.vm.synced_folder ".", "/vagrant", type: "nfs"
21 |
22 | config.ssh.shell = "/bin/sh"
23 |
24 | config.vm.provision :shell, :path => "setup.sh"
25 | end
26 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/freebsd/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | chsh -s bash vagrant
4 |
5 | PACKAGES="
6 | curl
7 | python
8 | python34
9 | py27-pip
10 | py27-virtualenv
11 | "
12 |
13 | PIP_PACKAGES="
14 | futures
15 | pycurl
16 | tox
17 | "
18 |
19 | ASSUME_ALWAYS_YES=true pkg install $PACKAGES
20 |
21 | pip install $PIP_PACKAGES
22 |
23 | /tornado/maint/vm/shared-setup.sh
24 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/freebsd/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist=py27-full, py27, py34
3 | setupdir=/tornado
4 | # /home is a symlink to /usr/home, but tox doesn't like symlinks here
5 | toxworkdir=/usr/home/vagrant/tox-tornado
6 |
7 | [testenv]
8 | commands = python -m tornado.test.runtests {posargs:}
9 |
10 | [testenv:py27-full]
11 | # twisted's tests fail on freebsd
12 | deps =
13 | futures
14 | pycurl
15 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/shared-setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Run at the end of each vm's provisioning script
3 |
4 | set -e
5 |
6 | # Link tox.ini into the home directory so you can run tox immediately
7 | # after ssh'ing in without cd'ing to /vagrant (since cd'ing to /tornado
8 | # gets the wrong config)
9 | ln -sf /vagrant/tox.ini ~vagrant/tox.ini
10 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu10.04/Vagrantfile:
--------------------------------------------------------------------------------
1 | Vagrant::Config.run do |config|
2 | config.vm.box = "lucid64"
3 | config.vm.box_url = "http://files.vagrantup.com/lucid64.box"
4 |
5 | config.vm.network :hostonly, "172.19.1.2"
6 | config.vm.share_folder("tornado", "/tornado", "../../..", :nfs=> true)
7 |
8 | config.vm.provision :shell, :path => "setup.sh"
9 | end
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu10.04/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | apt-get update
6 |
7 | # libcurl4-gnutls-dev is the default if you ask for libcurl4-dev, but it
8 | # has bugs that make our tests deadlock (the relevant tests detect this and
9 | # disable themselves, but it means that to get full coverage we have to use
10 | # the openssl version).
11 | # The oddly-named python-software-properties includes add-apt-repository.
12 | APT_PACKAGES="
13 | python-pip
14 | python-dev
15 | libcurl4-openssl-dev
16 | python-software-properties
17 | "
18 |
19 | apt-get -y install $APT_PACKAGES
20 |
21 |
22 | # Ubuntu 10.04 has python 2.6 as default; install more from here.
23 | add-apt-repository ppa:fkrull/deadsnakes
24 | apt-get update
25 |
26 | DEADSNAKES_PACKAGES="
27 | python2.7
28 | python2.7-dev
29 | python3.2
30 | python3.2-dev
31 | "
32 | apt-get -y install $DEADSNAKES_PACKAGES
33 |
34 |
35 | PIP_PACKAGES="
36 | futures
37 | pycurl
38 | tox
39 | twisted
40 | virtualenv
41 | "
42 |
43 | pip install $PIP_PACKAGES
44 |
45 | /tornado/maint/vm/shared-setup.sh
46 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu10.04/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27-full, py32, py26, py26-full, py27
3 | setupdir=/tornado
4 | toxworkdir=/home/vagrant/tox-tornado
5 |
6 | [testenv]
7 | commands = python -m tornado.test.runtests {posargs:}
8 |
9 | [testenv:py26]
10 | deps = unittest2
11 |
12 | [testenv:py26-full]
13 | deps =
14 | futures
15 | pycurl
16 | twisted==11.0.0
17 | unittest2
18 |
19 | [testenv:py27-full]
20 | basepython = python2.7
21 | deps =
22 | futures
23 | pycurl
24 | twisted==11.0.0
25 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu12.04/Vagrantfile:
--------------------------------------------------------------------------------
1 | Vagrant::Config.run do |config|
2 | config.vm.box = "precise64"
3 | config.vm.box_url = "http://files.vagrantup.com/precise64.box"
4 |
5 | config.vm.network :hostonly, "172.19.1.5"
6 | config.vm.share_folder("tornado", "/tornado", "../../..", :nfs=> true)
7 |
8 | config.vm.provision :shell, :path => "setup.sh"
9 | end
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu12.04/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | apt-get update
6 |
7 | # libcurl4-gnutls-dev is the default if you ask for libcurl4-dev, but it
8 | # has bugs that make our tests deadlock (the relevant tests detect this and
9 | # disable themselves, but it means that to get full coverage we have to use
10 | # the openssl version).
11 | # The oddly-named python-software-properties includes add-apt-repository.
12 | APT_PACKAGES="
13 | python-pip
14 | python-dev
15 | libcurl4-openssl-dev
16 | python-software-properties
17 | "
18 |
19 | apt-get -y install $APT_PACKAGES
20 |
21 |
22 | # Ubuntu 12.04 has python 2.7 as default; install more from here.
23 | add-apt-repository ppa:fkrull/deadsnakes
24 | apt-get update
25 |
26 | DEADSNAKES_PACKAGES="
27 | python3.2
28 | python3.2-dev
29 | "
30 | apt-get -y install $DEADSNAKES_PACKAGES
31 |
32 |
33 | PIP_PACKAGES="
34 | futures
35 | pycurl
36 | tox
37 | twisted
38 | virtualenv
39 | "
40 |
41 | pip install $PIP_PACKAGES
42 |
43 | /tornado/maint/vm/shared-setup.sh
44 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu12.04/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27-full, py32, py27, py27-select, py27-twisted
3 | setupdir=/tornado
4 | toxworkdir=/home/vagrant/tox-tornado
5 |
6 | [testenv]
7 | commands = python -m tornado.test.runtests {posargs:}
8 |
9 | [testenv:py27-full]
10 | basepython = python2.7
11 | deps =
12 | futures
13 | pycurl
14 | twisted==12.2.0
15 |
16 | [testenv:py27-select]
17 | basepython = python2.7
18 | deps =
19 | futures
20 | pycurl
21 | twisted==12.2.0
22 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.select.SelectIOLoop {posargs:}
23 |
24 | [testenv:py27-twisted]
25 | basepython = python2.7
26 | deps =
27 | futures
28 | pycurl
29 | twisted==12.2.0
30 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.twisted.TwistedIOLoop {posargs:}
31 |
32 | [testenv:py32]
33 | basepython = python3.2
34 | commands = python -bb -m tornado.test.runtests {posargs:}
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu14.04/Vagrantfile:
--------------------------------------------------------------------------------
1 | Vagrant::Config.run do |config|
2 | config.vm.box = "ubuntu/trusty64"
3 |
4 | config.vm.network :hostonly, "172.19.1.8"
5 | config.vm.share_folder("tornado", "/tornado", "../../..", :nfs=> true)
6 |
7 | config.vm.provision :shell, :path => "setup.sh"
8 | end
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu14.04/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | apt-get update
6 |
7 | # libcurl4-gnutls-dev is the default if you ask for libcurl4-dev, but it
8 | # has bugs that make our tests deadlock (the relevant tests detect this and
9 | # disable themselves, but it means that to get full coverage we have to use
10 | # the openssl version).
11 | APT_PACKAGES="
12 | python-pip
13 | python-dev
14 | python3-pycurl
15 | libcurl4-openssl-dev
16 | "
17 |
18 | apt-get -y install $APT_PACKAGES
19 |
20 | # Ubuntu 14.04 includes python 2.7 and 3.4.
21 |
22 | PIP_PACKAGES="
23 | futures
24 | pycurl
25 | tox
26 | twisted
27 | virtualenv
28 | "
29 |
30 | pip install $PIP_PACKAGES
31 |
32 | /tornado/maint/vm/shared-setup.sh
33 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/ubuntu14.04/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27-full, py34, py27, py27-select, py27-twisted
3 | setupdir=/tornado
4 | toxworkdir=/home/vagrant/tox-tornado
5 |
6 | [testenv]
7 | commands = python -m tornado.test.runtests {posargs:}
8 |
9 | [testenv:py27-full]
10 | basepython = python2.7
11 | deps =
12 | futures
13 | mock
14 | pycurl
15 | twisted==14.0.0
16 |
17 | [testenv:py27-select]
18 | basepython = python2.7
19 | deps =
20 | futures
21 | mock
22 | pycurl
23 | twisted==14.0.0
24 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.select.SelectIOLoop {posargs:}
25 |
26 | [testenv:py27-twisted]
27 | basepython = python2.7
28 | deps =
29 | futures
30 | mock
31 | pycurl
32 | twisted==14.0.0
33 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.twisted.TwistedIOLoop {posargs:}
34 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/maint/vm/windows/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27-full, py32-full, py26, py26-full, py27, py32, py33, py27-opt, py33-monotonic
3 | setupdir = e:\
4 | toxworkdir = c:\tox-tornado
5 |
6 | [testenv]
7 | commands = python -m tornado.test.runtests {posargs:}
8 |
9 | [testenv:py26]
10 | deps = unittest2
11 |
12 | [testenv:py26-full]
13 | basepython = python2.6
14 | deps =
15 | futures
16 | mock
17 | unittest2
18 |
19 | [testenv:py27-full]
20 | basepython = python2.7
21 | deps =
22 | futures
23 | mock
24 |
25 | [testenv:py32-full]
26 | basepython = python3.2
27 | deps =
28 | mock
29 |
30 | [testenv:py33]
31 | # tox's path mappings haven't been updated for py33 yet.
32 | basepython = c:\python33\python.exe
33 |
34 | [testenv:py33-monotonic]
35 | basepython = c:\python33\python.exe
36 | commands = python -m tornado.test.runtests --ioloop_time_monotonic {posargs:}
37 |
38 | [testenv:py27-opt]
39 | basepython = python2.7
40 | deps =
41 | futures
42 | mock
43 | commands = python -O -m tornado.test.runtests {posargs:}
44 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/runtests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Run the Tornado test suite.
3 | #
4 | # Also consider using tox, which uses virtualenv to run the test suite
5 | # under multiple versions of python.
6 |
7 | cd $(dirname $0)
8 |
9 | # "python -m" differs from "python tornado/test/runtests.py" in how it sets
10 | # up the default python path. "python -m" uses the current directory,
11 | # while "python file.py" uses the directory containing "file.py" (which is
12 | # not what you want if file.py appears within a package you want to import
13 | # from)
14 | python -m tornado.test.runtests "$@"
15 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2009 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """The Tornado web server and tools."""
18 |
19 | from __future__ import absolute_import, division, print_function, with_statement
20 |
21 | # version is a human-readable version number.
22 |
23 | # version_info is a four-tuple for programmatic comparison. The first
24 | # three numbers are the components of the version number. The fourth
25 | # is zero for an official release, positive for a development branch,
26 | # or negative for a release candidate or beta (after the base version
27 | # number has been incremented)
28 | version = "4.2"
29 | version_info = (4, 2, 0, 0)
30 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/tornado/platform/__init__.py
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/auto.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2011 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """Implementation of platform-specific functionality.
18 |
19 | For each function or class described in `tornado.platform.interface`,
20 | the appropriate platform-specific implementation exists in this module.
21 | Most code that needs access to this functionality should do e.g.::
22 |
23 | from tornado.platform.auto import set_close_exec
24 | """
25 |
26 | from __future__ import absolute_import, division, print_function, with_statement
27 |
28 | import os
29 |
30 | if 'APPENGINE_RUNTIME' in os.environ:
31 | from tornado.platform.common import Waker
32 |
33 | def set_close_exec(fd):
34 | pass
35 | elif os.name == 'nt':
36 | from tornado.platform.common import Waker
37 | from tornado.platform.windows import set_close_exec
38 | else:
39 | from tornado.platform.posix import set_close_exec, Waker
40 |
41 | try:
42 | # monotime monkey-patches the time module to have a monotonic function
43 | # in versions of python before 3.3.
44 | import monotime
45 | # Silence pyflakes warning about this unused import
46 | monotime
47 | except ImportError:
48 | pass
49 | try:
50 | from time import monotonic as monotonic_time
51 | except ImportError:
52 | monotonic_time = None
53 |
54 | __all__ = ['Waker', 'set_close_exec', 'monotonic_time']
55 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/caresresolver.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 | import pycares
3 | import socket
4 |
5 | from tornado import gen
6 | from tornado.ioloop import IOLoop
7 | from tornado.netutil import Resolver, is_valid_ip
8 |
9 |
10 | class CaresResolver(Resolver):
11 | """Name resolver based on the c-ares library.
12 |
13 | This is a non-blocking and non-threaded resolver. It may not produce
14 | the same results as the system resolver, but can be used for non-blocking
15 | resolution when threads cannot be used.
16 |
17 | c-ares fails to resolve some names when ``family`` is ``AF_UNSPEC``,
18 | so it is only recommended for use in ``AF_INET`` (i.e. IPv4). This is
19 | the default for ``tornado.simple_httpclient``, but other libraries
20 | may default to ``AF_UNSPEC``.
21 |
22 | .. versionchanged:: 4.1
23 | The ``io_loop`` argument is deprecated.
24 | """
25 | def initialize(self, io_loop=None):
26 | self.io_loop = io_loop or IOLoop.current()
27 | self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb)
28 | self.fds = {}
29 |
30 | def _sock_state_cb(self, fd, readable, writable):
31 | state = ((IOLoop.READ if readable else 0) |
32 | (IOLoop.WRITE if writable else 0))
33 | if not state:
34 | self.io_loop.remove_handler(fd)
35 | del self.fds[fd]
36 | elif fd in self.fds:
37 | self.io_loop.update_handler(fd, state)
38 | self.fds[fd] = state
39 | else:
40 | self.io_loop.add_handler(fd, self._handle_events, state)
41 | self.fds[fd] = state
42 |
43 | def _handle_events(self, fd, events):
44 | read_fd = pycares.ARES_SOCKET_BAD
45 | write_fd = pycares.ARES_SOCKET_BAD
46 | if events & IOLoop.READ:
47 | read_fd = fd
48 | if events & IOLoop.WRITE:
49 | write_fd = fd
50 | self.channel.process_fd(read_fd, write_fd)
51 |
52 | @gen.coroutine
53 | def resolve(self, host, port, family=0):
54 | if is_valid_ip(host):
55 | addresses = [host]
56 | else:
57 | # gethostbyname doesn't take callback as a kwarg
58 | self.channel.gethostbyname(host, family, (yield gen.Callback(1)))
59 | callback_args = yield gen.Wait(1)
60 | assert isinstance(callback_args, gen.Arguments)
61 | assert not callback_args.kwargs
62 | result, error = callback_args.args
63 | if error:
64 | raise Exception('C-Ares returned error %s: %s while resolving %s' %
65 | (error, pycares.errno.strerror(error), host))
66 | addresses = result.addresses
67 | addrinfo = []
68 | for address in addresses:
69 | if '.' in address:
70 | address_family = socket.AF_INET
71 | elif ':' in address:
72 | address_family = socket.AF_INET6
73 | else:
74 | address_family = socket.AF_UNSPEC
75 | if family != socket.AF_UNSPEC and family != address_family:
76 | raise Exception('Requested socket family %d but got %d' %
77 | (family, address_family))
78 | addrinfo.append((address_family, (address, port)))
79 | raise gen.Return(addrinfo)
80 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/epoll.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2012 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 | """EPoll-based IOLoop implementation for Linux systems."""
17 | from __future__ import absolute_import, division, print_function, with_statement
18 |
19 | import select
20 |
21 | from tornado.ioloop import PollIOLoop
22 |
23 |
24 | class EPollIOLoop(PollIOLoop):
25 | def initialize(self, **kwargs):
26 | super(EPollIOLoop, self).initialize(impl=select.epoll(), **kwargs)
27 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/interface.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2011 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """Interfaces for platform-specific functionality.
18 |
19 | This module exists primarily for documentation purposes and as base classes
20 | for other tornado.platform modules. Most code should import the appropriate
21 | implementation from `tornado.platform.auto`.
22 | """
23 |
24 | from __future__ import absolute_import, division, print_function, with_statement
25 |
26 |
27 | def set_close_exec(fd):
28 | """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor."""
29 | raise NotImplementedError()
30 |
31 |
32 | class Waker(object):
33 | """A socket-like object that can wake another thread from ``select()``.
34 |
35 | The `~tornado.ioloop.IOLoop` will add the Waker's `fileno()` to
36 | its ``select`` (or ``epoll`` or ``kqueue``) calls. When another
37 | thread wants to wake up the loop, it calls `wake`. Once it has woken
38 | up, it will call `consume` to do any necessary per-wake cleanup. When
39 | the ``IOLoop`` is closed, it closes its waker too.
40 | """
41 | def fileno(self):
42 | """Returns the read file descriptor for this waker.
43 |
44 | Must be suitable for use with ``select()`` or equivalent on the
45 | local platform.
46 | """
47 | raise NotImplementedError()
48 |
49 | def write_fileno(self):
50 | """Returns the write file descriptor for this waker."""
51 | raise NotImplementedError()
52 |
53 | def wake(self):
54 | """Triggers activity on the waker's file descriptor."""
55 | raise NotImplementedError()
56 |
57 | def consume(self):
58 | """Called after the listen has woken up to do any necessary cleanup."""
59 | raise NotImplementedError()
60 |
61 | def close(self):
62 | """Closes the waker's file descriptor(s)."""
63 | raise NotImplementedError()
64 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/posix.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2011 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 |
17 | """Posix implementations of platform-specific functionality."""
18 |
19 | from __future__ import absolute_import, division, print_function, with_statement
20 |
21 | import fcntl
22 | import os
23 |
24 | from tornado.platform import interface
25 |
26 |
27 | def set_close_exec(fd):
28 | flags = fcntl.fcntl(fd, fcntl.F_GETFD)
29 | fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
30 |
31 |
32 | def _set_nonblocking(fd):
33 | flags = fcntl.fcntl(fd, fcntl.F_GETFL)
34 | fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
35 |
36 |
37 | class Waker(interface.Waker):
38 | def __init__(self):
39 | r, w = os.pipe()
40 | _set_nonblocking(r)
41 | _set_nonblocking(w)
42 | set_close_exec(r)
43 | set_close_exec(w)
44 | self.reader = os.fdopen(r, "rb", 0)
45 | self.writer = os.fdopen(w, "wb", 0)
46 |
47 | def fileno(self):
48 | return self.reader.fileno()
49 |
50 | def write_fileno(self):
51 | return self.writer.fileno()
52 |
53 | def wake(self):
54 | try:
55 | self.writer.write(b"x")
56 | except IOError:
57 | pass
58 |
59 | def consume(self):
60 | try:
61 | while True:
62 | result = self.reader.read()
63 | if not result:
64 | break
65 | except IOError:
66 | pass
67 |
68 | def close(self):
69 | self.reader.close()
70 | self.writer.close()
71 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/select.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright 2012 Facebook
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 | # not use this file except in compliance with the License. You may obtain
7 | # a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 | # License for the specific language governing permissions and limitations
15 | # under the License.
16 | """Select-based IOLoop implementation.
17 |
18 | Used as a fallback for systems that don't support epoll or kqueue.
19 | """
20 | from __future__ import absolute_import, division, print_function, with_statement
21 |
22 | import select
23 |
24 | from tornado.ioloop import IOLoop, PollIOLoop
25 |
26 |
27 | class _Select(object):
28 | """A simple, select()-based IOLoop implementation for non-Linux systems"""
29 | def __init__(self):
30 | self.read_fds = set()
31 | self.write_fds = set()
32 | self.error_fds = set()
33 | self.fd_sets = (self.read_fds, self.write_fds, self.error_fds)
34 |
35 | def close(self):
36 | pass
37 |
38 | def register(self, fd, events):
39 | if fd in self.read_fds or fd in self.write_fds or fd in self.error_fds:
40 | raise IOError("fd %s already registered" % fd)
41 | if events & IOLoop.READ:
42 | self.read_fds.add(fd)
43 | if events & IOLoop.WRITE:
44 | self.write_fds.add(fd)
45 | if events & IOLoop.ERROR:
46 | self.error_fds.add(fd)
47 | # Closed connections are reported as errors by epoll and kqueue,
48 | # but as zero-byte reads by select, so when errors are requested
49 | # we need to listen for both read and error.
50 | # self.read_fds.add(fd)
51 |
52 | def modify(self, fd, events):
53 | self.unregister(fd)
54 | self.register(fd, events)
55 |
56 | def unregister(self, fd):
57 | self.read_fds.discard(fd)
58 | self.write_fds.discard(fd)
59 | self.error_fds.discard(fd)
60 |
61 | def poll(self, timeout):
62 | readable, writeable, errors = select.select(
63 | self.read_fds, self.write_fds, self.error_fds, timeout)
64 | events = {}
65 | for fd in readable:
66 | events[fd] = events.get(fd, 0) | IOLoop.READ
67 | for fd in writeable:
68 | events[fd] = events.get(fd, 0) | IOLoop.WRITE
69 | for fd in errors:
70 | events[fd] = events.get(fd, 0) | IOLoop.ERROR
71 | return events.items()
72 |
73 |
74 | class SelectIOLoop(PollIOLoop):
75 | def initialize(self, **kwargs):
76 | super(SelectIOLoop, self).initialize(impl=_Select(), **kwargs)
77 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/platform/windows.py:
--------------------------------------------------------------------------------
1 | # NOTE: win32 support is currently experimental, and not recommended
2 | # for production use.
3 |
4 |
5 | from __future__ import absolute_import, division, print_function, with_statement
6 | import ctypes
7 | import ctypes.wintypes
8 |
9 | # See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx
10 | SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
11 | SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)
12 | SetHandleInformation.restype = ctypes.wintypes.BOOL
13 |
14 | HANDLE_FLAG_INHERIT = 0x00000001
15 |
16 |
17 | def set_close_exec(fd):
18 | success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0)
19 | if not success:
20 | raise ctypes.GetLastError()
21 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/speedups.c:
--------------------------------------------------------------------------------
1 | #define PY_SSIZE_T_CLEAN
2 | #include
3 |
4 | static PyObject* websocket_mask(PyObject* self, PyObject* args) {
5 | const char* mask;
6 | Py_ssize_t mask_len;
7 | const char* data;
8 | Py_ssize_t data_len;
9 | Py_ssize_t i;
10 | PyObject* result;
11 | char* buf;
12 |
13 | if (!PyArg_ParseTuple(args, "s#s#", &mask, &mask_len, &data, &data_len)) {
14 | return NULL;
15 | }
16 |
17 | result = PyBytes_FromStringAndSize(NULL, data_len);
18 | if (!result) {
19 | return NULL;
20 | }
21 | buf = PyBytes_AsString(result);
22 | for (i = 0; i < data_len; i++) {
23 | buf[i] = data[i] ^ mask[i % 4];
24 | }
25 |
26 | return result;
27 | }
28 |
29 | static PyMethodDef methods[] = {
30 | {"websocket_mask", websocket_mask, METH_VARARGS, ""},
31 | {NULL, NULL, 0, NULL}
32 | };
33 |
34 | #if PY_MAJOR_VERSION >= 3
35 | static struct PyModuleDef speedupsmodule = {
36 | PyModuleDef_HEAD_INIT,
37 | "speedups",
38 | NULL,
39 | -1,
40 | methods
41 | };
42 |
43 | PyMODINIT_FUNC
44 | PyInit_speedups() {
45 | return PyModule_Create(&speedupsmodule);
46 | }
47 | #else // Python 2.x
48 | PyMODINIT_FUNC
49 | initspeedups() {
50 | Py_InitModule("tornado.speedups", methods);
51 | }
52 | #endif
53 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/tornado/test/__init__.py
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/__main__.py:
--------------------------------------------------------------------------------
1 | """Shim to allow python -m tornado.test.
2 |
3 | This only works in python 2.7+.
4 | """
5 | from __future__ import absolute_import, division, print_function, with_statement
6 |
7 | from tornado.test.runtests import all, main
8 |
9 | # tornado.testing.main autodiscovery relies on 'all' being present in
10 | # the main module, so import it here even though it is not used directly.
11 | # The following line prevents a pyflakes warning.
12 | all = all
13 |
14 | main()
15 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/asyncio_test.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 | # not use this file except in compliance with the License. You may obtain
3 | # a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 | # License for the specific language governing permissions and limitations
11 | # under the License.
12 |
13 | from __future__ import absolute_import, division, print_function, with_statement
14 |
15 | import sys
16 | import textwrap
17 |
18 | from tornado import gen
19 | from tornado.testing import AsyncTestCase, gen_test
20 | from tornado.test.util import unittest
21 |
22 | try:
23 | from tornado.platform.asyncio import asyncio, AsyncIOLoop
24 | except ImportError:
25 | asyncio = None
26 |
27 | skipIfNoSingleDispatch = unittest.skipIf(
28 | gen.singledispatch is None, "singledispatch module not present")
29 |
30 |
31 | @unittest.skipIf(asyncio is None, "asyncio module not present")
32 | class AsyncIOLoopTest(AsyncTestCase):
33 | def get_new_ioloop(self):
34 | io_loop = AsyncIOLoop()
35 | asyncio.set_event_loop(io_loop.asyncio_loop)
36 | return io_loop
37 |
38 | def test_asyncio_callback(self):
39 | # Basic test that the asyncio loop is set up correctly.
40 | asyncio.get_event_loop().call_soon(self.stop)
41 | self.wait()
42 |
43 | @skipIfNoSingleDispatch
44 | @gen_test
45 | def test_asyncio_future(self):
46 | # Test that we can yield an asyncio future from a tornado coroutine.
47 | # Without 'yield from', we must wrap coroutines in asyncio.async.
48 | x = yield asyncio.async(
49 | asyncio.get_event_loop().run_in_executor(None, lambda: 42))
50 | self.assertEqual(x, 42)
51 |
52 | @unittest.skipIf(sys.version_info < (3, 3),
53 | 'PEP 380 not available')
54 | @skipIfNoSingleDispatch
55 | @gen_test
56 | def test_asyncio_yield_from(self):
57 | # Test that we can use asyncio coroutines with 'yield from'
58 | # instead of asyncio.async(). This requires python 3.3 syntax.
59 | global_namespace = dict(globals(), **locals())
60 | local_namespace = {}
61 | exec(textwrap.dedent("""
62 | @gen.coroutine
63 | def f():
64 | event_loop = asyncio.get_event_loop()
65 | x = yield from event_loop.run_in_executor(None, lambda: 42)
66 | return x
67 | """), global_namespace, local_namespace)
68 | result = yield local_namespace['f']()
69 | self.assertEqual(result, 42)
70 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/csv_translations/fr_FR.csv:
--------------------------------------------------------------------------------
1 | "school","école"
2 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/gettext_translations/extract_me.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa
2 | # Dummy source file to allow creation of the initial .po file in the
3 | # same way as a real project. I'm not entirely sure about the real
4 | # workflow here, but this seems to work.
5 | #
6 | # 1) xgettext --language=Python --keyword=_:1,2 --keyword=pgettext:1c,2 --keyword=pgettext:1c,2,3 extract_me.py -o tornado_test.po
7 | # 2) Edit tornado_test.po, setting CHARSET, Plural-Forms and setting msgstr
8 | # 3) msgfmt tornado_test.po -o tornado_test.mo
9 | # 4) Put the file in the proper location: $LANG/LC_MESSAGES
10 |
11 | from __future__ import absolute_import, division, print_function, with_statement
12 | _("school")
13 | pgettext("law", "right")
14 | pgettext("good", "right")
15 | pgettext("organization", "club", "clubs", 1)
16 | pgettext("stick", "club", "clubs", 1)
17 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the PACKAGE package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: PACKAGE VERSION\n"
10 | "Report-Msgid-Bugs-To: \n"
11 | "POT-Creation-Date: 2015-01-27 11:05+0300\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=utf-8\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 | "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 |
21 | #: extract_me.py:11
22 | msgid "school"
23 | msgstr "école"
24 |
25 | #: extract_me.py:12
26 | msgctxt "law"
27 | msgid "right"
28 | msgstr "le droit"
29 |
30 | #: extract_me.py:13
31 | msgctxt "good"
32 | msgid "right"
33 | msgstr "le bien"
34 |
35 | #: extract_me.py:14
36 | msgctxt "organization"
37 | msgid "club"
38 | msgid_plural "clubs"
39 | msgstr[0] "le club"
40 | msgstr[1] "les clubs"
41 |
42 | #: extract_me.py:15
43 | msgctxt "stick"
44 | msgid "club"
45 | msgid_plural "clubs"
46 | msgstr[0] "le bâton"
47 | msgstr[1] "les bâtons"
48 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/import_test.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa
2 | from __future__ import absolute_import, division, print_function, with_statement
3 | from tornado.test.util import unittest
4 |
5 |
6 | class ImportTest(unittest.TestCase):
7 | def test_import_everything(self):
8 | # Some of our modules are not otherwise tested. Import them
9 | # all (unless they have external dependencies) here to at
10 | # least ensure that there are no syntax errors.
11 | import tornado.auth
12 | import tornado.autoreload
13 | import tornado.concurrent
14 | # import tornado.curl_httpclient # depends on pycurl
15 | import tornado.escape
16 | import tornado.gen
17 | import tornado.http1connection
18 | import tornado.httpclient
19 | import tornado.httpserver
20 | import tornado.httputil
21 | import tornado.ioloop
22 | import tornado.iostream
23 | import tornado.locale
24 | import tornado.log
25 | import tornado.netutil
26 | import tornado.options
27 | import tornado.process
28 | import tornado.simple_httpclient
29 | import tornado.stack_context
30 | import tornado.tcpserver
31 | import tornado.template
32 | import tornado.testing
33 | import tornado.util
34 | import tornado.web
35 | import tornado.websocket
36 | import tornado.wsgi
37 |
38 | # for modules with dependencies, if those dependencies can be loaded,
39 | # load them too.
40 |
41 | def test_import_pycurl(self):
42 | try:
43 | import pycurl
44 | except ImportError:
45 | pass
46 | else:
47 | import tornado.curl_httpclient
48 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/options_test.cfg:
--------------------------------------------------------------------------------
1 | port=443
2 | port=443
3 | username='李康'
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/resolve_test_helper.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 | from tornado.ioloop import IOLoop
3 | from tornado.netutil import ThreadedResolver
4 | from tornado.util import u
5 |
6 | # When this module is imported, it runs getaddrinfo on a thread. Since
7 | # the hostname is unicode, getaddrinfo attempts to import encodings.idna
8 | # but blocks on the import lock. Verify that ThreadedResolver avoids
9 | # this deadlock.
10 |
11 | resolver = ThreadedResolver()
12 | IOLoop.current().run_sync(lambda: resolver.resolve(u('localhost'), 80))
13 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/static/dir/index.html:
--------------------------------------------------------------------------------
1 | this is the index
2 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/static/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
3 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/tcpserver_test.py:
--------------------------------------------------------------------------------
1 | import socket
2 |
3 | from tornado import gen
4 | from tornado.iostream import IOStream
5 | from tornado.log import app_log
6 | from tornado.stack_context import NullContext
7 | from tornado.tcpserver import TCPServer
8 | from tornado.testing import AsyncTestCase, ExpectLog, bind_unused_port, gen_test
9 |
10 |
11 | class TCPServerTest(AsyncTestCase):
12 | @gen_test
13 | def test_handle_stream_coroutine_logging(self):
14 | # handle_stream may be a coroutine and any exception in its
15 | # Future will be logged.
16 | class TestServer(TCPServer):
17 | @gen.coroutine
18 | def handle_stream(self, stream, address):
19 | yield gen.moment
20 | stream.close()
21 | 1/0
22 |
23 | server = client = None
24 | try:
25 | sock, port = bind_unused_port()
26 | with NullContext():
27 | server = TestServer()
28 | server.add_socket(sock)
29 | client = IOStream(socket.socket())
30 | with ExpectLog(app_log, "Exception in callback"):
31 | yield client.connect(('localhost', port))
32 | yield client.read_until_close()
33 | yield gen.moment
34 | finally:
35 | if server is not None:
36 | server.stop()
37 | if client is not None:
38 | client.close()
39 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/templates/utf8.html:
--------------------------------------------------------------------------------
1 | Héllo
2 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/test.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICSDCCAbGgAwIBAgIJAN1oTowzMbkzMA0GCSqGSIb3DQEBBQUAMD0xCzAJBgNV
3 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRkwFwYDVQQKDBBUb3JuYWRvIFdl
4 | YiBUZXN0MB4XDTEwMDgyNTE4MjQ0NFoXDTIwMDgyMjE4MjQ0NFowPTELMAkGA1UE
5 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExGTAXBgNVBAoMEFRvcm5hZG8gV2Vi
6 | IFRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALirW3mX4jbdFse2aZwW
7 | zszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcLtKqv
8 | jnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+PzU39
9 | UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAGjUDBOMB0GA1UdDgQWBBRhJjMBYrzddCFr
10 | /0vvPyHMeqgo0TAfBgNVHSMEGDAWgBRhJjMBYrzddCFr/0vvPyHMeqgo0TAMBgNV
11 | HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGP6GaxSfb21bikcqaK3ZKCC1sRJ
12 | tiCuvJZbBUFUCAzl05dYUfJZim/oWK+GqyUkUB8ciYivUNnn9OtS7DnlTgT2ws2e
13 | lNgn5cuFXoAGcHXzVlHG3yoywYBf3y0Dn20uzrlLXUWJAzoSLOt2LTaXvwlgm7hF
14 | W1q8SQ6UBshRw2X0
15 | -----END CERTIFICATE-----
16 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/test.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALirW3mX4jbdFse2
3 | aZwWzszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcL
4 | tKqvjnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+P
5 | zU39UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAECgYEAiygNaWYrf95AcUQi9w00zpUr
6 | nj9fNvCwxr2kVbRMvd2balS/CC4EmXPCXdVcZ3B7dBVjYzSIJV0Fh/iZLtnVysD9
7 | fcNMZ+Cz71b/T0ItsNYOsJk0qUVyP52uqsqkNppIPJsD19C+ZeMLZj6iEiylZyl8
8 | 2U16c/kVIjER63mUEGkCQQDayQOTGPJrKHqPAkUqzeJkfvHH2yCf+cySU+w6ezyr
9 | j9yxcq8aZoLusCebDVT+kz7RqnD5JePFvB38cMuepYBLAkEA2BTFdZx30f4moPNv
10 | JlXlPNJMUTUzsXG7n4vNc+18O5ous0NGQII8jZWrIcTrP8wiP9fF3JwUsKrJhcBn
11 | xRs3hQJBAIDUgz1YIE+HW3vgi1gkOh6RPdBAsVpiXtr/fggFz3j60qrO7FswaAMj
12 | SX8c/6KUlBYkNjgP3qruFf4zcUNvEzcCQQCaioCPFVE9ByBpjLG6IUTKsz2R9xL5
13 | nfYqrbpLZ1aq6iLsYvkjugHE4X57sHLwNfdo4dHJbnf9wqhO2MVe25BhAkBdKYpY
14 | 7OKc/2mmMbJDhVBgoixz/muN/5VjdfbvVY48naZkJF1p1tmogqPC5F1jPCS4rM+S
15 | FfPJIHRNEn2oktw5
16 | -----END PRIVATE KEY-----
17 |
--------------------------------------------------------------------------------
/src/tornado-4.2.0/tornado/test/util.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function, with_statement
2 |
3 | import os
4 | import socket
5 | import sys
6 |
7 | from tornado.testing import bind_unused_port
8 |
9 | # Encapsulate the choice of unittest or unittest2 here.
10 | # To be used as 'from tornado.test.util import unittest'.
11 | if sys.version_info < (2, 7):
12 | # In py26, we must always use unittest2.
13 | import unittest2 as unittest
14 | else:
15 | # Otherwise, use whichever version of unittest was imported in
16 | # tornado.testing.
17 | from tornado.testing import unittest
18 |
19 | skipIfNonUnix = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin',
20 | "non-unix platform")
21 |
22 | # travis-ci.org runs our tests in an overworked virtual machine, which makes
23 | # timing-related tests unreliable.
24 | skipOnTravis = unittest.skipIf('TRAVIS' in os.environ,
25 | 'timing tests unreliable on travis')
26 |
27 | # Set the environment variable NO_NETWORK=1 to disable any tests that
28 | # depend on an external network.
29 | skipIfNoNetwork = unittest.skipIf('NO_NETWORK' in os.environ,
30 | 'network access disabled')
31 |
32 | skipIfNoIPv6 = unittest.skipIf(not socket.has_ipv6, 'ipv6 support not present')
33 |
34 |
35 | def refusing_port():
36 | """Returns a local port number that will refuse all connections.
37 |
38 | Return value is (cleanup_func, port); the cleanup function
39 | must be called to free the port to be reused.
40 | """
41 | # On travis-ci, port numbers are reassigned frequently. To avoid
42 | # collisions with other tests, we use an open client-side socket's
43 | # ephemeral port number to ensure that nothing can listen on that
44 | # port.
45 | server_socket, port = bind_unused_port()
46 | server_socket.setblocking(1)
47 | client_socket = socket.socket()
48 | client_socket.connect(("127.0.0.1", port))
49 | conn, client_addr = server_socket.accept()
50 | conn.close()
51 | server_socket.close()
52 | return (client_socket.close, client_addr[1])
53 |
--------------------------------------------------------------------------------