kali2fan kali2fan - 1 month ago 12
Python Question

python-requests broken after upgrade from 0.12.1 to 2.7.0


  1. Was On kali 1:
    Python 2.7.3 (default, Mar 13 2014, 11:03:55)[GCC 4.7.2] on linux2. Version of requests module is 0.12.1

  2. Now On kali 2:
    Python 2.7.9 (default, Mar 1 2015, 12:57:24) [GCC 4.9.2] on linux2. Version of requests module is 2.7.0



There was easy api_query for cryptsy:

import hashlib
import hmac
import requests
import time
import urllib

def api_query( method, req = {}):
# API settings
key = API_KEY # your API-key
secret = API_SECRET # your Secret-key
req['method'] = method
req['nonce'] = int( time.time() )
# generate the POST data string
post_data = urllib.urlencode( req )
sign = hmac.new( secret, post_data, hashlib.sha512)
# generate the extra headers
headers = { 'Sign': sign.hexdigest(), 'Key': key }
url = 'https://api.cryptsy.com/api'
print 'post_data = ' + post_data
print 'headers = ' + str( headers )
r = requests.post( url, data=post_data, headers = headers )
print r
for i in r.__dict__:
print ''
print i, r.__dict__[i]
return r.text


It works on kali 1, but kali 2 - NOT.

>>> print api_query("getinfo")
{"success":"0","error":"Unable to Authorize Request - Check Your Post Data"}


For the first time, I've launched kali 1 in qemu and started to compare two similar codes. I've to setted
nonce
to one number and tested the difference between two
post_datas
. Everything was equal. Even
Sign(kali1) == Sign(kali2)
.

I'm changing address from api.cryptsy.com to 127.0.0.1. And I can see, that:


  • 0.12.1 send
    Data
    as one encoded string. - Good.

  • 2.7.0 converted string back to
    HTML Form URL Encoded
    .


Answer

As Yaroslav Admin mentioned, new version of requests need no urlencode anymore. Otherwise, its convert this html-request-like string, like ?a=b&c=1&d=hello backward to dictionary-like payload, which is wrong on the server side.

That is why, need to improve only one string in my cryptsy's api_query example:

r = requests.post( url, data = post_data, headers = headers )

to

r = requests.post( url, data = req, headers = headers )

Everything else is correct.