2011-06-10 19 views
7

Şu anda başka biri tarafından yazılmış bir kod parçası ile çalışıyorum. Sunucuya istekte bulunmak için httplib kullanır. Doğru bir biçimde sağlanan tüm verilere sahiptir - örneğin, mesaj gövdesi, başlık değerleri, vb.Python httplib ve POST

Sorun, POST istekleri göndermeye çalıştığı her seferde, oradaki verilerdir. İstemci tarafı, ancak sunucuya hiçbir şey gelmiyor. Kütüphane spesifikasyonunu okudum ve kullanım doğru görünüyor.

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() 

bu bazı bilinen sorun mıdır nedir şu şekildedir:

çıkarılan kütüphane çağrıları

gitmek? Python 2.7 kullanıyorum. Httplib sürümünü nasıl kontrol edeceğinizden emin değilsiniz.

Gerçekten benzer bir şey olmadıkça (httplib2 belki de) başka bir şey için https göndermeyi önermeyin. Dediğim gibi, kod benimki değil ve daha önce yüklediğimden çok daha büyük miktarlarda geliyor. Refactoring, büyük bir soruna neden olur. Güvenilir bir çözümle ilgileniyorum.

DÜZENLEME

ayıklama çıkışı:

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 

Not olduğunu bu durumda boş sunucu cevapta, istekle değil kendisiyle ilgili cevap aslında görüşmeler sonrasında bilgileri.

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

Ve bu üç satırı:

`` 
<QueryDict: {}> 
<QueryDict: {}> 

üzerinden:

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

birincil nedeni istek gövdesi kendisi ben bir günlük alarak gözlemlemek hangi boş olmasıdır Django sunucusu. Öyleyse bedeni göndermeye çalışıyor ama sonunda göndermiyor.

DÜZENLEME (2)

Tamam, bir dökümü aldı ve gerçekten tarayıcıdan gönderilen mesajda dahil edilmemiştir, 'Content-Length' adında ek bir parametre olduğunu söyledi kütüphanenin düzenli kullanımı. Aptal ben. ekleyerek

+2

BTW, size bu şeyi çok hata ayıklama olacak düşünüyorsanız, ([Wireshark] http://www.wireshark.org/ yüklemek) ve telden ne geçtiğini gözetlemek için kullanın. – Darien

+0

Teşekkürler, başlangıçta bir inançsızdım ama aslında beni çözüme götürdü. Tekrar teşekkürler – julkiewicz

+0

Sunucuda şunlar bulunur: response.set_header ('Erişim-Kontrol-İzin-Kökeni', '*') ???? –

cevap

5

deneyin: kodunuzu

conn.set_debuglevel(1) 

aslında neler olduğunu görebilirsiniz.

0

httplib belgelerini kontrol ettiniz mi? httplib standart Python kütüphanesi, ve Python çevrimiçi belgelerine sahip hakkında da çok iyidir: http://docs.python.org/library/httplib.html

o sayfadan örnek:

>>> 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() 

Sizin örnekte, bu daha fazla iş gibi görünüyor ve siz okursanız API dokümanı - örneğin putrequest için - örneğinizde yanlış kullandığınızı göreceksiniz. Spesifik olarak, varsayılan olarak Accept üstbilgisini otomatik olarak ekler.

Kodunuzu daha işlevsel bir örnek gibi yapmaya çalışın, hem kodunuzda hem de çalışma örneğinde kullanılan çağrıları anlamaya çalışın.

+1

Evet, API belgelerini okudum ve her şey iyi görünüyor. Sorun şu ki, iyi değil. Aynı talep çeşitli başka yollarla yapılmıştır - bir tarayıcı veya başka bir kütüphane iyi çalışır. 'Kabul et' başlığını kaldırmak hiçbir şeyi değiştirmez. API'dan yapıştırdığınız örnek, tamamen farklı bir şey yapıyor. Bu bir POST değil ve mesaj gövdesini yüklemeye çalışmıyor. – julkiewicz

6

putrequest yöntemi, İçerik Uzunluğu üstbilgisini otomatik olarak eklemez, bunu kendiniz yapmanız veya request yöntemini kullanmanız gerekir.

for döngü yukarıdaki kodunuzu ekleyin:

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