Skip to content
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

Fix parsing complex accept headers #2603

Merged
merged 9 commits into from
Apr 12, 2021

Conversation

schwmi
Copy link
Contributor

@schwmi schwmi commented Apr 11, 2021

Fixes an issue when parsing complex Accept headers, e.g. text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 The accept header should now be correctly parsed and all accepted types available. Also fixes an issue in HTTPMediaTypePreference when comparing two media types. (#2603)

Fixes #2283

Comment on lines 43 to +48
if aq == bq {
return .orderedSame
} else if aq > bq {
return .orderedAscending
} else {
return .orderedDescending
} else {
return .orderedAscending
Copy link
Contributor Author

@schwmi schwmi Apr 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was twisted - as aq is the left hand side input parameter the return value should be .orderedDescending when larger than the right hand side.

self.pop()
} else if let comma = self.current.firstIndex(of: .comma) {
value = self.pop(to: comma)
} else if let separatorMatch = self.firstIndex(matchingAnyOf: .comma, .semicolon) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of always preferring semicolon first we also check if there are comma along the way.

@0xTim 0xTim added the semver-patch Internal changes only label Apr 12, 2021
Copy link
Member

@0xTim 0xTim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! Just a couple of changes around shoring up the tests and we're good to go!


// Simple accept type
do {
headers.replaceOrAdd(name: .accept, value: "text/html")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for complete sanity and to avoid future regressions could you add an assert to these tests that ensures that the accepted media types match the ones in the header. E.g.

XCTAssertTrue(headers.accept.mediaTypes.contains(.html))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback. I've added some cases + removed the catchall from the second, more complex test to allow testing for concrete types…

@0xTim
Copy link
Member

0xTim commented Apr 12, 2021

Original comment:

Fixes #2283

This PR fixes an issue that parsing more complex accept headers like text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 failed.
Reason was that during directive parsing the semicolon was parsed in greedy way, preferred over comma. (.e.g parsing the mentioned header would lead to "text/html,application/xhtml+xml,application/xml;q=0.9" as single directive). I fixed that by also considering commas when parsing the next semicolon.
As this directive parsing code is used also for other header types I am not sure if it suits all other needs, or if some other logic relies on the former behaviour - all existing unit tests still pass (but the test coverage isn't that high)

When adding unit tests for those more complex accept headers I realized that also the logic in HTTPMediaTypePreference.swift for comparing two media types is incorrect. I fixed this along the way and also added a test for this

Copy link
Member

@0xTim 0xTim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@0xTim 0xTim merged commit 5c3f170 into vapor:main Apr 12, 2021
@VaporBot
Copy link
Contributor

These changes are now available in 4.44.1

@schwmi schwmi deleted the bugfix/complex-accept-headers branch April 12, 2021 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-patch Internal changes only
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Complex Accept header parsing fails
3 participants