Author Topic: HTTP 400 bad request on /command/setForceStart in WebUI API  (Read 163 times)

mavaddat

  • Newbie
  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
I am trying to write a Powershell script to automatically force resume certain torrents. However, I am having trouble reaching the /command/setForceStart endpoint with the Invoke-WebRequest module.
Here is my script at the relevant part:
Code: [Select]
$r = @()
$dest = ls $env:TEMP\  -Filter Any_HnR_Ts* | where -EQ "Directory" -Property Attributes
$torrents = Get-ChildItem -Path $dest.FullName -Filter *.torrent
$r += Invoke-WebRequest -Uri "http://localhost:8080/login" -WebSession $my_session -Headers @{Referer="http://localhost:8080"} -Method Post -UserAgent "Fiddler" -ContentType "application/x-www-form-urlencoded" -Body "username=mavaddat&password="
[System.Reflection.Assembly]::LoadFrom("C:\Users\mavad\Documents\WindowsPowerShell\Modules\BencodeNET\BencodeNET.dll")
[email protected]()
foreach ($torrent in $torrents){
   $h += Get-Hash -Algorithm SHA1 -StringEncoding utf8 -InputObject $(([BencodeNET.Parsing.BencodeParser]::new().Parse($torrent.FullName)['info']).EncodeAsBytes())
   $r += Invoke-WebRequest -Uri 'http://localhost:8080/command/resume' -WebSession $my_session -UserAgent 'Fiddler' -Method Post -ContentType 'application/x-www-form-urlencoded' -Body "hash=$($h.ToString())"
   }
$r += Invoke-WebRequest -Uri 'http://localhost:8080/command/setForceStart' -WebSession $my_session -UserAgent 'Fiddler' -Method Post -ContentType 'application/x-www-form-urlencoded' -Body ("hashes={0}`?value=true" -f $($h -join "|"))
This should get a list of all the torrents to resume (targets), log into the WebUI landing page, then individually soft resume each target torrent, and finally force start all the target torrents.
However, the attempt to force start returns a 400 bad request with the following web response:
IsMutuallyAuthenticated False
Cookies {SID=wxbQZkcVRPSJwpO4o91JZ3x03j6gzTd2}
Headers
connectionkeep-alive
content-security-policydefault-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none';
x-content-type-optionsnosniff
x-frame-optionsSAMEORIGIN
x-xss-protection1; mode=block
Content-Length0
DateWed, 16 May 2018 17:47:43 GMT
Set-Cookie
SID=wxbQZkcVRPSJwpO4o91JZ3x03j6gzTd2; HttpOnly; path=/
SupportsHeaders True
ContentLength 0
ContentEncoding
ContentType
CharacterSet
Server
LastModified 2018-05-16 10:49:13 AM
StatusCode BadRequest
StatusDescription Bad Request
ProtocolVersion 1.1
ResponseUri http://localhost:8080/command/setForceStart
Method POST
IsFromCache False
Does anyone know what I might be doing wrong?
Please note I am using BencodeNET to parse the torrent files, which does correctly parse them. Then I calculate the SHA1 hash for each torrent using the bytes of the torrent info, which also correctly derives their hashes (in uppercase base64). I've tried converting them to lowercase without any difference in the result.
I am currently running the latest qBitTorrent v4.1.0 x64 with Qt: 5.10.1 Libtorrent: 1.1.7.0 Boost: 1.67.0
Also, I have verified that the hashes I am looking for are valid. So I notice that the WebUI API documentation says
Quote from: WebUI API documentation
If your torrent hash is invalid, the server will reply with:

Code: [Select]
HTTP/1.1 404 Not Found
but I don't think this should apply.
To verify my hashes, I have run this example:
Code: [Select]
$info = Invoke-WebRequest -Uri "http://localhost:8080/api/v2/torrents/info?category=Books" -WebSession $my_session -UserAgent Fiddler -Method Get | ConvertFrom-Json
foreach ($book in $info) {if ($book.hash -eq $h[0]){$book.name}}
These two commands will return the correct book title for the given hash (i.e., the first hash computed in my list as stored in $h[0]).
A more thorough examination of each hash (in the code below) shows that every computed hash matches some torrent in my list:
Code: [Select]
$info = Invoke-WebRequest -Uri "http://localhost:8080/api/v2/torrents/info?category=Books" -WebSession $my_session -UserAgent Fiddler -Method Get | ConvertFrom-Json
foreach ($hash in $h) {foreach ($book in $info) {if ($book.hash -eq $hash){$found = $book.name}}; Write-Host $found; Remove-Variable -Name found }
This nested for-loop will test every hash against every torrent listed by the WebUI API and it successfully verifies every hash without any errors or exceptions.
More simply, this set difference will return no results:
Code: [Select]
$h.HashString | ?{ -not $info.hash -contains $_}
« Last Edit: May 16, 2018, 10:46:34 PM by mavaddat »