Python httplib y POST

Actualmente estoy trabajando con un código que ha sido escrito por otra persona. Utiliza httplib para hacer solicitudes al servidor. Tiene todos los datos suministrados en un formato correcto, por ejemplo, cuerpo del mensaje, valores de encabezado, etc.

El problema es que cada vez que intenta enviar solicitudes POST, los datos están allí; puedo verlos en el lado del cliente, sin embargo, no llega nada al servidor. He leído la especificación de la biblioteca y el uso parece correcto.

Las llamadas extraídas a la biblioteca son las siguientes:

 import httplib conn = httplib.HTTPConnection('monkeylabs.pl', 80) conn.connect() request = conn.putrequest('POST', '/api/snippet/') headers = {} headers['Content-Type'] = 'application/json' headers['User-Agent'] = 'Envjs/1.618 (SpyderMonkey; U; Linux x86_64 2.6.38-10-generic; pl_PL.utf8; rv:2.7.1) Resig/20070309 PilotFish/1.3.pre03' headers['Accept'] = '*/*' for k in headers: conn.putheader(k, headers[k]) conn.endheaders() conn.send('[{"id":"route"}]') resp = conn.getresponse() print resp.status print resp.reason print resp.read() conn.close() 

¿Es este un problema conocido, o qué? Estoy usando Python 2.7. No estoy seguro de cómo comprobar la versión de httplib.

Por favor, no sugiera intercambiar httplib por otra cosa a menos que sea algo realmente similar (httplib2 quizás). Como dije, el código no es mío y viene en cantidades mucho mayores que lo que acabo de publicar. Refactorizarlo causaría un gran problema. Estoy interesado en cualquier solución confiable.

EDITAR

La salida de depuración:

 send: 'POST /api/snippet/ HTTP/1.1\r\nHost: monkeylabs.pl\r\nAccept-Encoding: identity\r\nContent-Type: application/json\r\nAccept: */*\r\nUser-Agent: Envjs/1.618 (SpyderMonkey; U; Linux x86_64 2.6.38-10-generic; pl_PL.utf8; rv:2.7.1) Resig/20070309 PilotFish/1.3.pre03\r\n\r\n[{"id":"route"}]' reply: 'HTTP/1.0 201 CREATED\r\n' header: Date: Fri, 10 Jun 2011 23:54:00 GMT header: Server: WSGIServer/0.1 Python/2.7.1+ header: Vary: Cookie header: Content-Type: application/json header: Content-Length: 0 201 CREATED 

Tenga en cuenta que la información después de la respuesta realmente habla de la respuesta del servidor, no de la solicitud en sí, que en este caso está vacía. La causa principal es que el cuerpo de la solicitud está vacío, lo que puedo observar al obtener un registro:

 [11/Jun/2011 01:54:00] "POST /api/snippet/ HTTP/1.1" 201 0 

Y esas tres líneas:

 ``   

fuera de:

 print '`%s`' % request.raw_post_data print request.GET print request.POST 

en el servidor Django. Así que parece que intenta enviar el cuerpo pero no lo envía al final.

EDITAR (2)

Bien, tomé un volcado y, de hecho, me dijo que en el mensaje enviado desde el navegador hay un parámetro adicional llamado ‘Contenido-Longitud’ que se ha omitido en el uso regular de la biblioteca. Tonto de mí.

intente agregar:

 conn.set_debuglevel(1) 

a su código para que pueda ver lo que realmente está sucediendo.

El método putrequest no agrega automáticamente el encabezado Content Length, debe hacerlo usted mismo o usar el método de request .

Agregue esto a su código sobre el bucle for :

 headers['Content-Length'] = "%d"%(len('[{"id":"route"}]')) 

¿Has revisado la documentación de httplib? httplib es una biblioteca estándar de Python, y Python también es muy bueno al tener documentación en línea: http://docs.python.org/library/httplib.html

El ejemplo de esa página:

 >>> import httplib, urllib >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) >>> headers = {"Content-type": "application/x-www-form-urlencoded", ... "Accept": "text/plain"} >>> conn = httplib.HTTPConnection("musi-cal.mojam.com:80") >>> conn.request("POST", "/cgi-bin/query", params, headers) >>> response = conn.getresponse() >>> print response.status, response.reason 200 OK >>> data = response.read() >>> conn.close() 

Su ejemplo parece ser más putrequest que esto, y si lee la documentación de la API, por ejemplo para putrequest , verá que lo está utilizando mal en su muestra. Específicamente, agrega automáticamente el encabezado Aceptar de forma predeterminada.

Intente hacer que su código sea más parecido al ejemplo funcional, también intente comprender las llamadas utilizadas tanto en su código como en el ejemplo de trabajo.