tornado解析http body的过程分析

在最近写的一个RESTful API Server过程中,发现tornaod对解析POST BODY的内容有限制。

而在以前用web.py则没有这个限制,使用httplib2作为客户端。

客户端代码:

def request(self, url, method, **kwargs):
request_kwargs = copy.copy(kwargs)
request_kwargs.setdefault('headers', kwargs.get('headers', {}))
request_kwargs['headers']['Accept'] = 'application/json'
request_kwargs['headers']['Content-type'] = 'application/x-www-form-urlencoded'

try:
request_kwargs['body']['token'] = self.token
request_kwargs['body'] = urllib.urlencode(kwargs['body'])
except KeyError:
pass
resp, body = super(HTTPClient, self).request(self.api_url + url, method, **request_kwargs) return resp, body

上面加粗的部分中,设置header的Content-type参数,为 application/x-www-form-urlencoded,否则tornado不会解析request body中的内容。

tornado解析uri中参数的过程就不解释了,关键的地方是解析body中的内容。

body中可以有两种类型的内容,一为form提交的,二为被urlencod过的内容(也放在body)里面。

因为httplib2在使用POST/PUT/PATCH提交body内容时,不会自动设置Content-type参数,导致了tornado找不到对应的类型。

在使用self.get_argument函数时,根本得不到字段的内容。

关键代码:

首先是在HTTPConnection类中的_on_request_body回调函数:

1 def _on_request_body(self, data):
2 self._request.body = data
3 if self._request.method in ("POST", "PATCH", "PUT"):
4 httputil.parse_body_arguments(
5 self._request.headers.get("Content-Type", ""), data,
6 self._request.arguments, self._request.files)
7 self.request_callback(self._request)

httputil.parse_body_arguments函数完成对客户端使用POST/PATCH/PUT方法时,BODY内容的解析:

 1 def parse_body_arguments(content_type, body, arguments, files):
2 """Parses a form request body.
3
4 Supports "application/x-www-form-urlencoded" and "multipart/form-data".
5 The content_type parameter should be a string and body should be
6 a byte string. The arguments and files parameters are dictionaries
7 that will be updated with the parsed contents.
8 """
9 if content_type.startswith("application/x-www-form-urlencoded"):
10 uri_arguments = parse_qs_bytes(native_str(body))
11 for name, values in uri_arguments.iteritems():
12 values = [v for v in values if v]
13 if values:
14 arguments.setdefault(name, []).extend(values)
15 elif content_type.startswith("multipart/form-data"):
16 fields = content_type.split(";")
17 for field in fields:
18 k, sep, v = field.strip().partition("=")
19 if k == "boundary" and v:
20 parse_multipart_form_data(utf8(v), body, arguments, files)
21 break
22 else:
23 logging.warning("Invalid multipart/form-data")

函数的注释里面已经写的很清楚了:

Supports "application/x-www-form-urlencoded" and "multipart/form-data".

只支持 application/x-www-form-urlencoded 和 multipart/form-data这两种在body中提交内容的方式。

tornado解析http body的过程分析的更多相关文章

  1. tornado解析post数据的问题

    解析tornado查询参数: self.request.query_arguments self.get_query_argument[s](参数名称) 解析tornado的post参数: self. ...

  2. tornado解析 第一篇

    一.tornado介绍 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 we ...

  3. spring beans源码解读之--XmlBeanFactory

    导读: XmlBeanFactory继承自DefaultListableBeanFactory,扩展了从xml文档中读取bean definition的能力.从本质上讲,XmlBeanFactory等 ...

  4. 《AngularJs实战》学习笔记(慕课网)

    1. Controller使用过程中的注意点 不要试图去复用Controller, 一个控制器一般只负责一小块视图 不要在Controller中操作DOM, 这不是控制器的职责. 封装在指令里. 不要 ...

  5. Android系统Recovery工作原理之使用update.zip升级过程分析(八)---解析并执行升级脚本updater-script【转】

    本文转载自:http://blog.csdn.net/mu0206mu/article/details/7465551  Android系统Recovery工作原理之使用update.zip升级过程分 ...

  6. Python+Tornado+Tampermonkey 获取某讯等主流视频网站的会员视频解析播放

    近期,<哪吒之魔童降世>在各大视频软件可以看了,然而却是一贯的套路,非会员谢绝观看!!!只能从国内那些五花八门的视频网站上找着看了,或者通过之前本人说的 Chrome 的油猴插件,传送门  ...

  7. tornado反向解析

    tornado反向解析 在路由中添加name属性,并且不能使用元组路由,应当由tornado.web.url定义路由. app = tornado.web.Application([ (r'/', I ...

  8. Netty 源码解析(九): connect 过程和 bind 过程分析

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 今天是猿灯塔“365篇原创计划”第九篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源 ...

  9. Linux移植之tag参数列表解析过程分析

    在Linux移植之内核启动过程start_kernel函数简析中已经指出了start_kernel函数的调用层次,这篇主要是对具体的tag参数列表进行解析. 1.内存参数ATAG_MEM参数解析 2. ...

随机推荐

  1. hdu 2057 A+B Again

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2057 题目分析:涉及到16进制内的加法,可以用%I64x直接来处理,要注意到16进制中负数是用补码来表 ...

  2. JDK 与 JRE (转)

    很多程序员已经干了一段时间java了依然不明白jdk与jre的区别.JDK就是Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境. ...

  3. 转:Android studio Gradle

    提高Android Studio中Gradle执行效率 分类: android studio2015-06-26 11:54 2374人阅读 评论(2) 收藏 举报 android studiogra ...

  4. 【原】WinForm中的DataGridView加入Combbox或者DropDownButton后,操作变慢

    DataGridView里加入了DropDownButto列,加载数据后点击这一列,反应很慢;要点击三到四次才会展示下拉列表; 原因是DataGridView的EditMode设置问题; 将DataG ...

  5. nodejs ssh2

    https://www.npmjs.com/package/ssh2 npm install ssh2  ssh2文件下载: //前台命令下发 app.get('/test/fileDownload' ...

  6. Linux 如何设置只允许域名访问站点而禁止IP访问站点

    最近在论坛里看到有人问到 Linux 如何设置只允许域名访问站点而禁止IP访问站点的问题,之前自己也用过这个功能,可以防止别人用 IP 地址来访问到自己的网站,下面我就我自己的环境给出解决方法,我用的 ...

  7. QQ好友列表向左滑动出现置顶、删除--第三方开源--SwipeMenuListView

    SwipeMenuListView是在github上的第三方开源项目,该项目在github上的链接地址是:https://github.com/baoyongzhang/SwipeMenuListVi ...

  8. jQuery实现分页

    转载地址 http://www.cnblogs.com/xiaoruoen/archive/2012/01/11/2318199.html ;( function($){ $.extend({ &qu ...

  9. Linux环境下Python的安装过程

    Linux环境下Python的安装过程 前言 一般情况下,Linux都会预装 Python了,但是这个预装的Python版本一般都非常低,很多 Python的新特性都没有,必须重新安装新一点的版本,从 ...

  10. C# 生成简单验证码

    网站登录总是会用到验证码,生成验证码对于C#来说很简单.因为有专门封装好的GDI+类可以直接调用使用具体代码如下 using System; using System.Collections.Gene ...