I'm sending a POST request to a Django server through Postman. This is what the body of my request looks like
POST /update/ HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 0764e56c-0fd8-fcce-5248-34f7d05f2748
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="UploadDownloadSettings"
dssssss
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="settings";
filename="settings.zip"
Content-Type: application/zip
When I try to access request.POST['UploadDownloadSettings'], the program says the key is not valid.
When I loop through the keys in request.POST I get a bunch of keys from the zip file and the key name.
According to the docs, this should parse out form-data. This seems like standard form data as far as I understand.
https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.HttpRequest.POST
Am I misunderstanding the way the django post request works?
Output of request.POST
Key:
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition
Value:
form-data
Key:
name
Value:
"UploadDownloadSettings"
Key:
//actual filenames from the zip with their value
Value:
Blank
Output of request.FILES: blank map
Output of request.content_type: application/x-www-form-urlencoded
Related
Hopefully, my question makes sense, but I'll try to explain it better here.
So, this is the post request data that was sent to the server when I analyzed the post request headers:
------WebKitFormBoundaryq4q6NLNtlzAsbRBY
Content-Disposition: form-data; name="form_type"
product
------WebKitFormBoundaryq4q6NLNtlzAsbRBY
Content-Disposition: form-data; name="utf8"
✓
------WebKitFormBoundaryq4q6NLNtlzAsbRBY
Content-Disposition: form-data; name="id"
36110014939287
------WebKitFormBoundaryq4q6NLNtlzAsbRBY
Content-Disposition: form-data; name="add"
I have two issues here. I am trying to use this data to send as my payload in a post request like a dictionary, but I'm not really sure how I would do this as I've never seen anything like this before.
Second, I see there is a hidden value for the "utf8" name, so how would I go about decoding that value and converting it back to a string.
Again, hopefully this makes sense and I'm sorry if it doesn't - I will do my best to respond to any follow up questions.
Thanks!
if you are using ajax use contentType: false;
or
use enctype="application/x-www-form-urlencoded" in form
<form enctype="application/x-www-form-urlencoded">
I´m trying to log in to a website using my account. In python code, I use:
login_response = session.post('mysite.com', login_data, cookies=session.cookies)
where session is a requests session object, the cookies are exactly the cookies that are also sent when I try the same in a browser (it´s two specific cookies that are sent by the browser as part of the request when I log in), and login_data is a dictionary of form data that is sent in the post request.
However, the expected response is: code 303, a redirect link is sent, and two new cookies (that are the use login session). This is what happens in the browser.
When I want to do this with the code above, I get instead code 200, no redirect link, and no cookies. It´s as if the site just 'reloads'. The form data itself (password + user) is correct.
I read the request content from my browser:
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="login__standard_submitted"
1
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="csrfKey"
2fcc7af2aa54f0e3ab85a6bdeca26f98
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="ref"
aHR0cHM6Ly9jcmltZW1hcmtldC53by8=
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="MAX_FILE_SIZE"
20971520
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="plupload"
92ee7fd8f0a2249c2327184c5b95d6c9
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="auth"
myusername
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="password"
password
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="remember_me"
0
-----------------------------366521339228594542373308740035
Content-Disposition: form-data; name="remember_me_checkbox"
1
-----------------------------366521339228594542373308740035--
The data I get from this, I just wrote into a dictionary of key: values, e.g.
'auth': 'myusername'
Again a tl;dr:
I send the right cookies and what I observed as seemingly correct data when performing the POST request in code. However, I get an entirely different result than in the browser, and fail to log in.
Did I misunderstand something? What do I need to change to log in by code?
EDIT: In the headers, I also set 'Content-Type' to 'multipart/form-data', just as in the browser.
EDIT 2: Instead if I set login_data with files=, it still doesn´t work.
From what I have seen you have to use files= to send a multipart/form-data request using request.post however you have to use tuples and set the filename to NOne so they are not sent as files.
login_data = (
('login__standard_submitted', (None, '1')),
('csrfKey', (None, '2fcc7af2aa54f0e3ab85a6bdeca26f98')),
('ref', (None, 'aHR0cHM6Ly9jcmltZW1hcmtldC53by8')),
...
)
login_response = session.post('mysite.com', files=login_data, cookies=session.cookies)
I wonder if your session object is sending an http: request and should instead send a https: request. This could lead to a redirect with 303 response. The "requests" package seems to handle this type of response.
import requests
res = requests.get('http://google.com')
print(res.url)
res = requests.get('http://stackoverflow.com')
print(res.url)
The output to those above are
http://www.google.com/
https://stackoverflow.com/
I want to change header of request and change destination IP and pass it to the correct destination.
How can I do it by flask and python.
This is my header
Host: 10.1.3.127:5000
Accept-Encoding: identity
X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Content-Length: 0
X-Amz-Date: 20191110T122830Z
Authorization: AWS4-HMAC-SHA256 Credential=yasin1/20191110/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=08610e134c60ffdfe3b4d8159d740b398b38565d0d38481cb405739bc401adea
User-Agent: Boto3/1.10.2 Python/2.7.12 Linux/4.4.0-142-generic Botocore/1.13.2 Resource
I want to change Host to 10.1.3.41:8080 and make requset to this destination.
I have this webservice, based on the Pyramid framework, that accepts a multipart/form-data request.
Everything works when I send the request from cURL;
however from the Android application, it fails with the following error
TypeError: must be str, not bytes
when I try to access any field : e.g. request.POST.get('smartphoneId', None)
The difference is that the Android library adds a few headers to the fields, notably the Content-Transfer-Encoding. From cURL each value is sent as follows :
--------------------------5f28b737bc4e4813
Content-Disposition: form-data; name="smartphoneId"
2
whereas from Android (with retrofit) :
--0e0a43aa-3156-48ee-a949-931dcc4eb8be
Content-Disposition: form-data; name="smartphoneId"
Content-Type: text/plain; charset=UTF-8
Content-Length: 3
Content-Transfer-Encoding: 8BIT
999
Initially the Content-Transfer-Encoding was binary ; I manually changed it to 8BIT, but I get the same error. Seems that Python can't parse / handle the content of each field.
Any idea ?
I had the same problem (with Python 3.4). To solve the problem, I created a patch for the following module "webob/compat.py" : replace the existing patch of multi_read by the current version from python cgi 3.5. And now, it works. I will create a pr on the github repository.
See https://bugs.python.org/issue27777.
I created a pull request for webob : https://github.com/Pylons/webob/pull/281
In a specific case I'd like to respond with a text/html content-type for an error as follows:
class MyResource(Resource):
def get(self):
if some_condition:
return 'bad argument', 400
The code above returns an application/json content-type: '"bad argument"'
instead of a text/html content-type: 'bad argument'
How can I force flask-restful to respond with text/html content-type?
You'll have to use flask.make_response() to return a 'pre-baked' response object:
return flask.make_response('bad argument', 400)
Flask-Restful will pass full-on Response objects unaltered, rather than try and convert them to a specific requested mime type.