mpris-scrobbler
mpris-scrobbler copied to clipboard
Scrobbling long track+album+artist to last.fm fails with "Invalid method signature"
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