Imitating a client only works when the set matches the original: panels match
subscription requests by header rules, and a surplus header identifies a forgery
as reliably as a missing one. The real Happ client sends no Accept header and no
X-App-Version at all — that header does not exist in Happ — and its locale is a
bare language code, so those three differences marked our requests as an
imitation and could be answered with 403.
On Windows locale.getlocale() reports a human readable name such as
Russian_Russia, which no client writes into a header; it is now translated into
a language code before it is sent.
A 403 is explained instead of being reported as a bare status: the panel refused
the client, or the site protection in front of it did, and the two need different
answers from the user.
The subscription dialog now rejects an identifier that panels silently ignore.
An HWID outside the Happ format never reaches the device limit, so the user
would otherwise see no effect and no error.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>