2016-10-28 4 views
3

でPOSTを行うとき、私は、リモートサーバーにデータをポストするための簡単なコードを持っている:奇妙な行動PyCurl

def main(): 
    headers = {} 
    headers['Content-Type'] = 'application/json' 

    target_url = r'the_url' 

    data = {"bodyTextPlain": "O estimulante concorrente dos azulzinhos\r\nConhe\u00e7a a nova tend\u00eancia em estimulante masculino e feminino\r\n\r\nEste estimulante ficou conhecido por seus efeitos similares as p\u00edlulas\r\nazuis,\r\ndestacando-se por n\u00e3o possuir contraindica\u00e7\u00e3o ou efeito colateral.\r\n\r\nSucesso de vendas e principal concorrente natural dos azulzinhos,\r\nsua f\u00f3rmula \u00e9 totalmente natural e livre de qu\u00edmicos.\r\n\r\nPossuindo registro no Minist\u00e9rio da Sa\u00fade (ANVISA) e atestado de\r\nautenticidade.\r\n\r\nSaiba mais http://www5.somenteagora.com.br/maca\r\nAdquirindo 3 frascos voc\u00ea ganha +1 de brinde. Somente esta semana!\r\n\r\n\r\n\r\n\r\nPare de receber\r\nhttp://www5.somenteagora.com.br/app/sair/3056321/1\r\n\r\n"} 

    buffer = StringIO() 
    curl = pycurl.Curl() 
    curl.setopt(curl.URL, target_url) 
    curl.setopt(pycurl.HTTPHEADER, ['%s: %s' % (k, v) for k, v in headers.items()]) 

    # this line causes the problem 
    curl.setopt(curl.POSTFIELDS, json.dumps(data)) 

    curl.setopt(pycurl.SSL_VERIFYPEER, False) 
    curl.setopt(pycurl.SSL_VERIFYHOST, False) 
    curl.setopt(pycurl.WRITEFUNCTION, buffer.write) 
    curl.perform() 

    response = buffer.getvalue() 

    print curl.getinfo(pycurl.HTTP_CODE) 
    print response 

リモートサーバーは、私が送っJSON文字列解析エラーがあります。しかし

500 { "status" : "Error", "message" : "Unexpected IOException (of type java.io.CharConversionException): Invalid UTF-32 character 0x3081a901(above 10ffff) at char #7, byte #31)" }

を私はjson.dumpsから変数にポストデータを保存し、ポストを行う場合:

#curl.setopt(curl.POSTFIELDS, json.dumps(data)) 

    data_s = json.dumps(data) 
    curl.setopt(curl.POSTFIELDS, data_s) 

その後エラーはありません。

200

これらの2つのケースに違いはありますか?

ありがとうございました。

+0

リクエストではなくpycurlを使用している理由は何ですか? – maxymoo

+0

特別な理由はありません。 [パフォーマンス](http://example.com)がうまく見えるので、私はそれを使ってこの問題を解決しようとしています。 – pppk520

+0

@ pppk520あなたはこの質問に興味があるかもしれません:https://stackoverflow.com/questions/15461995/python-requests-vs-pycurl-performance – augurar

答えて

3

これは驚異的な微妙な質問です。答えはdocumentation for Curl.setopt_string(option, value)にこの警告にある:

Warning: No checking is performed that option does, in fact, expect a string value. Using this method incorrectly can crash the program and may lead to a security vulnerability. Furthermore, it is on the application to ensure that the value object does not get garbage collected while libcurl is using it. libcurl copies most string options but not all; one option whose value is not copied by libcurl is CURLOPT_POSTFIELDS .

変数を使用する場合、それはゴミが収集されませんので、これは文字列への参照を作成します。式をインライン化すると、libcurlが使用を終了する前に文字列の割り当てが解除され、予期しない結果が生じます。

オブジェクトの寿命を気にする必要がないように、代わりにCURLOPT_COPYPOSTFIELDSを使用できます。

+0

完璧!ありがとう@augurar :-) – pppk520