转发:base64引起的血案

这几天将图片输出至csv文件,期望的是将图片转换为字节后存放在一个单元格,但是导出时候却发现,数据自动换行了,搞了两天,今天借助大神的经验,可算解决了,以下内容转发自:http://www.cnblogs.com/qualitysong/archive/2012/10/27/2742665.html

  

一个同事,使用jira的REST api对jira进行修改,用python的httplib发请求,发现发出POST请求后,服务器总是返回json缺少close marker。

于是自己搞了个nginx,把post请求的内容打出来,发现后面的确少了2个字符,很奇怪,开始怀疑httplib对content-len的计算有问题,于是在httplib中加了一些print打印中间结果。把请求头和请求+body的字符串msg都打印出来

复制代码
def _send_output(self, message_body=None):
        """Send the currently buffered request and clear the buffer.

        Appends an extra \\r\\n to the buffer.
        A message_body may be specified, to be appended to the request.
        """
        self._buffer.extend(("", ""))
        msg = "\r\n".join(self._buffer)
        print msg
        del self._buffer[:]
        # If msg and message_body are sent in a single send() call,
        # it will avoid performance problems caused by the interaction
        # between delayed ack and the Nagle algorithim.
        if isinstance(message_body, str):
            msg += message_body
            message_body = None
            print msg
        self.send(msg)
        if message_body is not None:
            #message_body was not a string (i.e. it is a file) and
            #we must run the risk of Nagle
            self.send(message_body)
复制代码

结果发现header跟body之间多了一个换行符('\r\n'),http协议默认header和body之间有一个空行隔开,也就是一个只含有\r\n的行,但是多了一个\r\n,就会导致服务器取body的时候从这个多出来的\r\n开始取content-length个字符,这样body里最后的两个字符就被这个多出来的\r\n挤掉了

而通过观察,这个原因是由于header的最后一个字段Authorization: Basic eHh4eHh4eDp4eHh4eHh4后面多了一个"\n"导致,

这个字段的值是同事经过base64.encodestring("XXXXXX:XXXXXX")编码后得到的字符串,查看了一下python的lib doc,发现这个函数默认返回一个以"\n"结尾的字符串,这就这个问题的根本原因,replace掉其中的\n,一切就都OK了

base64.encodestring返回的字符串默认结尾带"\n",而且产生的base64编码字符串每76个字符就会用"\n"隔开,所以最安全的方法不是strip去掉结尾的\n,而是用replace去掉其中所有的\n。为啥base64.ecodestring每76字符就换行,这个是mime协议的规定,用于email发送,具体查看mime协议吧。

posted on 2014-10-11 13:51  小太阳550  阅读(1027)  评论(0编辑  收藏  举报

导航