我有一个简单的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”。
为什么会这样?
答案 0 :(得分:2)
您没有打印header
变量的值,但如果header
值以\r\n
结尾,则可能会出现您所描述的问题。原因如下:
HTTP请求标头应以两个\ r \ n(CRLF)结束,然后POST数据到来。 urllib2
模块不会验证标头值以检查您的值中是否有CRLF。如果这样做,服务器认为标题“太早”结束了一个CRLF。这将导致POST数据以实际标题结束标记的最后一个CRLF开始。这反过来会使内容长度标题(计算原始帖子数据的长度)将帖子数据截断两个字符。
所以我建议仔细检查你的标题。