mpris-scrobbler icon indicating copy to clipboard operation
mpris-scrobbler copied to clipboard

Scrobbling long track+album+artist to last.fm fails with "Invalid method signature"

Open ChandlerSwift opened this issue 4 months ago • 0 comments

MAX_PROPERTY_LENGTH is defined to be 384:

https://github.com/mariusor/mpris-scrobbler/blob/0d42d4ff9fab38ecf63a1d08d4a447f1c04b639b/src/structs.h#L43

This comes into play when we generate the signature for the request[^process]:

[^process]: Because I had to look it up: the signature process is documented at https://www.last.fm/api/webauth#_6-sign-your-calls

https://github.com/mariusor/mpris-scrobbler/blob/0d42d4ff9fab38ecf63a1d08d4a447f1c04b639b/src/audioscrobbler_api.h#L256-L277

Specifically, the string argument passed to this function is a string of the format album{album}api_key{api_key,32char}artist{artist}methodtrack.updateNowPlayingsk{sk,32char}track{track}. Every value but those for album, artist, and track are constant-length, and total 117 characters.

Line 267 truncates the string if it ever exceeds MAX_PROPERTY_LENGTH/2 == 192 characters: https://github.com/mariusor/mpris-scrobbler/blob/0d42d4ff9fab38ecf63a1d08d4a447f1c04b639b/src/audioscrobbler_api.h#L267

Then the signature is created based on the truncated string, but the full-length string is submitted to last.fm, which leads to the titular signature mismatch.

There are at least a handful of songs in my library that do this. The one I was using for debugging was this one: "When the Time Has Come" (22 characters) by Huey Lewis & the News (21 characters) off the album "Time Flies… The Best of Huey Lewis & the News" (47 characters). With the 117 constant characters, above, we have a string of length 117+22+21+47 == 207, well exceeding the max size of 192 characters.

As a kludge to help fix this, I doubled MAX_PROPERTY_LENGTH. This fixes all the songs I tested. That said, there may be album/artist/track combinations that are long enough to still cause issues even with a higher limit[^absurd] -- would it make sense for this to be dynamically allocated?

[^absurd]: And they can really get absurd! e.g. a few from https://web.archive.org/web/20241002044440/https://dustri.org/b/horrible-edge-cases-to-consider-when-dealing-with-music.html

I'm not a particularly good C programmer, but I'd be happy to put together an attempt at dynamic allocation for the buffer in that particular function, and maybe try to add some test cases to make sure things work with a reasonable length of album/artist/track, if you'd like!

Here's the specific error I was seeing in the logs (when run with some number of v's, also compiled in debug mode, I think?)

TRACING curl::transfer::done[0]: https://ws.audioscrobbler.com/2.0/?format=json in check_multi_info() src/curl.h:82
TRACING   response::status: 400 
TRACING     response(0x194e80b0:58): {"message":"Invalid method signature supplied","error":13}
TRACING     response::headers[0]: server: openresty/1.13.6.2
TRACING     response::headers[1]: date: Sat, 05 Oct 2024 04:47:20 GMT
TRACING     response::headers[2]: content-type: application/json
TRACING     response::headers[3]: content-length: 58
TRACING     response::headers[4]: access-control-allow-methods: POST, GET, OPTIONS
TRACING     response::headers[5]: access-control-allow-origin: *
TRACING     response::headers[6]: access-control-max-age: 86400
TRACING     response::headers[7]: via: 1.1 google
TRACING     response::headers[8]: alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
INFO     api::submitted_to[last.fm]: nok

ChandlerSwift avatar Oct 05 '24 05:10 ChandlerSwift