-
Notifications
You must be signed in to change notification settings - Fork 313
api: Send simple User-Agent header #471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chrisbobbe for picking this up! I edited the description to cross-reference it with the previous PR #450.
The code generally all looks good; small comments below.
What manual testing have you done to confirm it resolves #460, and resolves #440 for older servers? (For the latter, I guess it'd suffice to test on a current server but without passing read_by_sender
.)
lib/api/core.dart
Outdated
// Putting "ZulipMobile" in the string helps users on pre-8 servers: | ||
// - When a user sends a message from the app, | ||
// the message is read instead of unread, avoiding #440. | ||
// (With servers 8+, this is accomplished | ||
// with a new param in the send-message API; see #456.) | ||
// - Login notifications say something specific instead of | ||
// "an unknown browser on an unknown operating system", avoiding #460. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this latter part work if we say "ZulipFlutter" instead of "ZulipMobile"? (If not, then we might need further server changes but we'll want to figure those out.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I just tested manually by changing the string from 'ZulipMobile (actually ZulipFlutter)' to just 'ZulipFlutter' and seeing what the login-notification email said, by visiting /emails
on the dev server. It said:
Device: Zulip on an unknown operating system.
, the same as it does with 'ZulipMobile (actually ZulipFlutter)' (#471 (comment)).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Er, and I've just tested this on a dev server at 7.x (zulip/zulip@c4a8264), and got the same result. I realized that my original test here must have been done on an 8+ dev server.
test/widgets/content_test.dart
Outdated
check(await actualAuthHeader(tester, Uri.parse('https://chat.example/image.png'))) | ||
.isNotNull().equals(authHeaders['Authorization']!); | ||
check(await actualHeaders(tester, Uri.parse('https://chat.example/image.png'))) | ||
..['Authorization'].single.equals(authHeaders['Authorization']!) | ||
..['User-Agent'].single.equals(userAgentHeader()['User-Agent']!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than check only these two headers, I think I'd prefer to continue to have a check that there aren't any unexpected additional headers. That can be done by a deepEquals
on the headers map.
Oh, hmm, doing this now… Visiting
And this is what I see at the tip of the PR branch:
Unfortunate that it doesn't even say Android or iOS, but it makes sense; in this first pass, the user-agent header doesn't carry that information (#467). |
Cool. I think the change from "An unknown browser" to "Zulip" is enough to say this resolves #460 — I think that "unknown browser" is probably the most disconcerting part. There'll still be a sort of followup to #460 which is to fix the operating-system part. But we can track that as just a note on #467 of something to test in a PR that fixes it. |
Ah hmm, well here's a problem. The string used in this PR, pattern = re.compile(
"""^ (?P<name> [^/ ]* [^0-9/(]* )
(/ (?P<version> [^/ ]* ))?
([ /] .*)?
$""",
re.X,
) As a consequence, |
That seems pretty busted. The server will fail to respond to a request if its bundle of heuristics for interpreting user-agent strings doesn't understand your user-agent? |
Aha: def is_pronouns_field_type_supported(user_agent_str: Optional[str]) -> bool:
# In order to avoid users having a bad experience with these
# custom profile fields disappearing after applying migration
# 0421_migrate_pronouns_custom_profile_fields, we provide this
# compatibility shim to show such custom profile fields as
# SHORT_TEXT to older mobile app clients.
#
# TODO/compatibility(7.0): Because this is a relatively minor
# detail, we can remove this compatibility hack once most users
# have upgraded to a sufficiently new mobile client.
if user_agent_str is None:
return True
user_agent = parse_user_agent(user_agent_str)
if user_agent["name"] != "ZulipMobile":
return True
FIRST_VERSION_TO_SUPPORT_PRONOUNS_FIELD = "27.192"
if version_lt(user_agent["version"], FIRST_VERSION_TO_SUPPORT_PRONOUNS_FIELD):
return False
return True |
Hmm, I see. Let's discuss in |
ac00529
to
5363be5
Compare
Revision pushed, following CZO discussion: https://chat.zulip.org/#narrow/stream/378-api-design/topic/zulip-flutter.20user.20agent/near/1712928
See: #471 (comment) Also, while I had that 7.x dev server handy, I went ahead and tested the 'ZulipMobile/flutter' override on send-message requests, as another way to confirm that it fixes #440 for older servers. With the override, the messages were marked as read; without it, they were not marked as read. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the revision! This all looks good, with one nit below.
Since you're out today, I'll just fix that and merge.
test/api/route/messages_test.dart
Outdated
expectedBodyFields: { | ||
'type': 'stream', | ||
'to': streamId.toString(), | ||
'topic': topic, | ||
'content': content, | ||
}, | ||
readBySender: null, | ||
expectedUserAgent: 'ZulipMobile/flutter'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
expectedBodyFields: { | |
'type': 'stream', | |
'to': streamId.toString(), | |
'topic': topic, | |
'content': content, | |
}, | |
readBySender: null, | |
expectedUserAgent: 'ZulipMobile/flutter'); | |
readBySender: null, | |
expectedBodyFields: { | |
'type': 'stream', | |
'to': streamId.toString(), | |
'topic': topic, | |
'content': content, | |
}, | |
expectedUserAgent: 'ZulipMobile/flutter'); |
because readBySender
specifies what to do, and so comes logically before what to expect from the result
This will make it easy to check the 'User-Agent' header in these tests, coming up.
The one caller passes read_by_sender, so these tests are now more representative of how the binding actually gets exercised. Next, we'll have the binding condition something on whether or not read_by_sender is passed, and that'll call for tests that omit it, which we'll add.
This resolves zulip#440 for older servers.
5363be5
to
a0f4462
Compare
Revises: #450
Fixes: #406
Fixes: #460