web API: HTTP 400 Bad Request on /command/setPreferences

Windows specific questions, problems.
Post Reply
brx86

web API: HTTP 400 Bad Request on /command/setPreferences

Post by brx86 »

Hello Team,
I have been playing around with the API for a while now, but whatever I do, i cannot solve the following situation:
I have a python script connecting to the qb web api using the "requests" module. /login and therefore obtaining an authentication cookie work fine, following commands like /query/preferences work just as fine.
But whenever I try to set qb preferences using /command/setPreferences I get a 400 Bad Request response.
This is the raw data directly from fiddler:

Code: Select all

POST http://localhost:1234/command/setPreferences HTTP/1.1
Host: localhost:1234
Content-Length: 21
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.9.1
Connection: keep-alive
Cookie: SID=iWMAADoeAACZaAAAVgkAAAIaAAAFeAAA
Content-Type: application/x-www-form-urlencoded

{"listen_port": 4728}
The webservers response is pretty plain.

Code: Select all

HTTP/1.1 400 Bad Request
The python snippet (i know this is python specific, but maybe someone recognizes any foolish code.)

Code: Select all

jsonData={"listen_port":4728}
headerData = {
'Cookie' : cookie,
'Content-Type' : 'application/x-www-form-urlencoded'
}
response = requests.post(server + ":" + port + "/command/setPreferences", json=jsonData, headers=headerData)
As far as the documentation of the API is concerned, all the requirements should be fulfilled, right? Content-Length, Cookie and Content-Type should be crucial for the post request. JSON is being interpreted as well.
What is it that I am doing wrong though? Thank you very much in advance,

-b
Last edited by brx86 on Mon Apr 11, 2016 6:43 pm, edited 1 time in total.
ciaobaby

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by ciaobaby »

What client version? and are you using the correct API documentation?
brx86

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by brx86 »

Whoops, lol, i forgot to add the most important information...
I am using version 3.3.4 and the documentation located at https://github.com/qbittorrent/qBittorr ... umentation
brx86

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by brx86 »

Well, i guess this can be closed then. Thanks for listening to my request though.
KitKat

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by KitKat »

Shouldnt this line
[quote="brx86"]
jsonData={"listen_port":4728}
[/quote]
Be: jsonData={"listen_port":"4728"}

IIRC you have to encapsulate everything when parsing json.
I didnt reply to this because i wasnt 100% sure/dont use the webui.

You also dont seem to authenticate yourself but you're not geting a 5XX deny error you're getting a "malformed response" error.
Because you dont authenticate yourself im assuming you're also localhost /w localhost no PW required?
Why not directly edit qbittorent.ini?
its found at %appdata%/qbittorrent/qbittorrent.ini
brx86

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by brx86 »

Hello KitKat, thank you very much for your quick reply! I almost gave up on this, but maybe we can solve this and learn something from it.
I'll try to elaborate:

"listen_port" is explicitly listed as an integer, and as such it must be transmitted unquoted (the documentation tells us so). As per Fiddler's output, this seems to be the correct behavior and is used by the web GUI as well.

The "requests" module for python is genuinely a masterpiece, since, among other things, it handles things like header data (content-length, host etc.etc..) for you. The same goes for the interpretation and transmission of json data. The attribute "json" within the request.post() call does exactly that. It tells the function to interpret the following dict as a json payload. Fiddler tells me that the payload was wrapped into the packet just fine. It looks just the same as the payload coming from the web GUI.

Authentication, as per documentation (3.3.4), is dealt with by using cookies. I supply the post request with a cookie that was obtained with a former login request.

Is there something I am missing? Do you think it would be best to dig through the source? I have no experience reading c++, but I guess there won't be a way around it ;)

Edit: I took the time to try it with an older version of qbittorrent (3.1.10). That version uses an older and seemingly deprecated api, but has the same symptoms.

And about your question why i don't just edit the .ini: I honestly think that by trying to understand mechanisms - that seem like a black box at first - always give you something back in return. Maybe in solving this problem, we can achieve an improvement in the documentation, and learn something along the way. See, i had no idea about the 'requests' module at first, nor did i have any experience with the http protocol. Just by dealing with this problem, i learned a bunch of things that will help me help others. Maybe by reading this you just learned that a 'requests' module exists and how powerful it may be - and maybe you'll have a use for it someday. For me thats enough of a reason to hack into those things.
Last edited by brx86 on Mon Apr 25, 2016 8:57 pm, edited 1 time in total.
brx86

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by brx86 »

I have to change my former statement: When using 3.1.10, the server responds with a 200 OK, but does not make any changes to the settings. So the behavior differs between 3.1.10 and 3.3.4.
KitKat

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by KitKat »

[quote="brx86"]
I have to change my former statement: When using 3.1.10, the server responds with a 200 OK, but does not make any changes to the settings. So the behavior differs between 3.1.10 and 3.3.4.
[/quote]
I had a quick read through the API documentation and it appears what you're doing is infact the correct way to do it.
I would suggest reposting this thread or linking to it on the github as a WebAPI issue/request for the 3.3.4 documentation to be updated.
Sorry, i personally cannot help you :(

Github Issues: https://github.com/qbittorrent/qBittorrent/issues

/e: For the 3.1.10 version are you running the browser that manages webui as admin?
Your command probably succeeds but lacks the local filesystem permissions to modify the file it needs to.

/e2: Probably nothing but..
[quote="brx86"]

Code: Select all

POST http://localhost:1234/command/setPreferences HTTP/1.1
Host: localhost:1234
Content-Length: 21
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.9.1
Connection: keep-alive
Cookie: SID=iWMAADoeAACZaAAAVgkAAAIaAAAFeAAA
Content-Type: application/x-www-form-urlencoded

{"listen_port": 4728}
[/quote]
Is there meant to be a space in the {"listen_port": 4728} line?
In the webapi examples there is no space after the :

Does your verification cookie allow you to return/get the existing preferences?
https://github.com/qbittorrent/qBittorr ... references

And is the problem only with attempting to set them?
(Im simply asking whether "simple" webapi queeries like getting the torrent list work)
Last edited by KitKat on Tue Apr 26, 2016 7:54 am, edited 1 time in total.
vidgen13
Newbie
Newbie
Posts: 1
Joined: Thu Dec 28, 2023 3:24 pm

Re: web API: HTTP 400 Bad Request on /command/setPreferences

Post by vidgen13 »

Can't get it to work either

import requests

login = { "username":username, "password":password }
port = 10247
payload = { "listen_port":port }

r = requests.post( url + "/api/v2/auth/login", data=login) --> THIS WORKS
# r = requests.post( url + "/api/v2/app/preferences", cookies=r.cookies ) --> THIS WORKS TOO
r = requests.post( url + "/api/v2/app/setPreferences", cookies=r.cookies, json=payload ) --> NOT WORKING
Post Reply