POST请求正文中删除了换行符? (Google App Engine)

时间:2016-07-12 12:26:01

标签: python google-app-engine post newline

我正在Google App Engine(不使用端点)上构建REST API,允许用户上传CSV或制表符分隔文件并搜索可能的重复项。由于它是API,因此我无法使用<form>或BlobStore upload_url。我也不能依赖于拥有一个可以调用此API的Web客户端。相反,理想情况下,用户将在请求的body中发送文件。

我的问题是,当我尝试读取制表符分隔文件的内容时,我发现所有换行符都已删除,因此无法将内容拆分为行。

如果我直接在Python解释器上检查文件的内容,我会看到选项卡和换行符(示例中的输出被截断)

>>> with open('./data/occ_sample.txt') as o:
...     o.read()
... 
'id\ttype\tmodified\tlanguage\trights\n123456\tPhysicalObject\t2015-11-11 11:50:59.0\ten\thttp://creativecommons.org/licenses/by-nc/3.0\n...'

RequestHandler记录请求正文的内容:

import logging
class ReportApi(webapp2.RequestHandler):
    def post(self):
        logging.info(self.request.body)
        ...

因此,当我通过dev_appserver

调用curl中的API时
curl -X POST -d @data/occ_sample.txt http://localhost:8080/api/v0/report

这显示在日志中:

id  type    modified    language    rights123456    PhysicalObject  2015-11-11 11:50:59.0   en  http://creativecommons.org/licenses/by-nc/3.0

正如您所看到的,标题的最后一个值与第一个记录(分别为rights123456之间没有任何内容),每个记录的最后一个值和第一个记录也是如此下一个。

我错过了一些明显的东西吗?我尝试使用self.request.bodyself.request.body_fileself.request.POST加载数据,但似乎都没有效果。我还尝试在请求标头中应用Content-Typetext/csvtext/plainapplication/csv,但没有成功。我应该添加不同的Content-Type吗?

1 个答案:

答案 0 :(得分:1)

您使用错误的curl命令行选项发送文件数据,此选项正在剥离换行符。

-d选项解析您的数据并发送application/x-www-form-urlencoded请求,删除换行符。来自curl manpage

  

-d, --data <data>

     

[...]

     

如果您使用字母@启动数据,其余的应该是用于读取数据的文件名,或者-如果您希望curl从stdin读取数据。也可以指定多个文件。因此,可以使用'foobar'来发布名为--data @foobar的文件中的数据。当--data被告知从这样的文件中读取时,回车并且新行将被删除

大胆强调我的。

改为使用--data-binary选项:

  

--data-binary <data>

     

(HTTP)这完全按照指定发布数据,无需任何额外处理。

     

如果您使用字母@启动数据,则其余应为文件名。数据以与--data-ascii类似的方式发布,除了保留换行符和回车符,并且永远不会进行转换。

可能希望在这种情况下包含Content-Type标题;当然,如果你关心那个标题,这取决于你的处理程序。