python urllib2请求预先添加换行符以发布数据

时间:2014-04-16 21:35:37

标签: python django newline urllib2 urllib

我有一个简单的python(2.7.5)脚本,使用urllib2将数据发布到服务器上的django(1.6.2)应用程序。当请求到达服务器时,其中一个已发布的值已被截断,其中一个字段名称已添加CR / LF前缀。这似乎是一个编码问题,但我不知道如何解决它。

python脚本会像这样发布到服务器:

auth = 'Basic ' + base64.encodestring('%s:%s' % (user, pwd))
header = {'Authorization': auth }

data = {
    'status': 'TEST',
    'activity_code': 'TEST',
    'sw_version': 'TEST',
    'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
data = urllib.urlencode(data)

request = urllib2.Request(url, data, header)
response = urllib2.urlopen(request)
result = json.loads(response.read())
print 'result = ', str(result), '\n'

在服务器上,有一个django应用程序可以像这样处理请求:

data = request.POST.copy()
error = {}

try:
    required = ['activity_code', 'timestamp', 'sw_version', 'status']
    for field in required:
        assert len(data.get(field)) > 0
except:
    error['message'] = 'required field is missing (' + field + ')'
    error['debug'] = data

if error:
    content = json.dumps(error, cls=DjangoJSONEncoder)
    return HttpResponse(content, content_type='application/json')

以下是从服务器收到响应后脚本的输出:

result = {u'debug': {u'timestamp': u'2014-04-16 14:22:15', u'\r\nstatus': u'TEST', u'activity_code': u'TEST', u'sw_version': u'TE'}, u'message': u'required field is missing (status)'}

请注意,status字段名称以某种方式以CR / LF为前缀,sw_version值从“TEST”截断为“TE”。

为什么会这样?

1 个答案:

答案 0 :(得分:2)

您没有打印header变量的值,但如果header值以\r\n结尾,则可能会出现您所描述的问题。原因如下:

HTTP请求标头应以两个\ r \ n(CRLF)结束,然后POST数据到来。 urllib2模块不会验证标头值以检查您的值中是否有CRLF。如果这样做,服务器认为标题“太早”结束了一个CRLF。这将导致POST数据以实际标题结束标记的最后一个CRLF开始。这反过来会使内容长度标题(计算原始帖子数据的长度)将帖子数据截断两个字符。

所以我建议仔细检查你的标题。