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

Bug #89350: media type validation #1462

Merged
merged 4 commits into from
Apr 7, 2022

Conversation

mitchell-fox
Copy link
Contributor

@mitchell-fox mitchell-fox commented Mar 28, 2022

Description

PS3.18 (nema.org):
"An mtp-value can be transmitted either as a token or quoted-string. The quoted and unquoted values are equivalent."

Currently, WADO with Accept: multipart/related; type=application/dicom will throw an error. It will accept Accept: multipart/related; type="application/dicom", but they should be equivalent.

##Changes
Altered AcceptContentFilterAttribute.cs to account for media type values with missing quotes such as "multipart/related; type=application/dicom" instead of the usual "multipart/related; type='application/dicom'".

Addresses

#1396 and AB#89350

Testing

Added new tests to AcceptContentFilterAttributeTests.cs.

@mitchell-fox mitchell-fox requested a review from a team as a code owner March 28, 2022 13:12
@ghost
Copy link

ghost commented Mar 28, 2022

CLA assistant check
All CLA requirements met.

@jovinson-ms
Copy link
Contributor

jovinson-ms commented Mar 30, 2022

As discussed, the Dicom standard requires the type parameter of the Accept header to be quoted, since it can include a / special character. This is already reflected in our conformance statement.

As an example, this is not a valid Accept header: multipart/related; type=application/dicom
but this is valid: multipart/related; type="application/dicom"

Enforcing this constraint allows us to leverage the built in header parsing libraries in ASP.NET Core and greatly simplify our code.

shivakumar-ms
shivakumar-ms previously approved these changes Mar 31, 2022
…ving allowSingle and allowMultiple, as allowSingle was always true and allowMultiple was always false.
@mitchell-fox
Copy link
Contributor Author

Committed code for updated PR scope. New code simplifies AcceptContentFilterAttribute so it no longer handles multipart Accept headers as it was never used in the codebase.

@bcarthic
Copy link
Contributor

bcarthic commented Apr 4, 2022

I am surprised none of our E2E tests are broken. Should we add a test?

@mitchell-fox
Copy link
Contributor Author

mitchell-fox commented Apr 4, 2022

That's a good idea. I can put them under Microsoft.Health.Dicom.Web.Tests.E2E -> Rest -> AcceptHeaderTests.cs. Should only need a couple E2E tests to validate everything past the updated unit tests.

EDIT: After standup discussion, adding E2E test is not necessary.


private readonly HashSet<MediaTypeHeaderValue> _mediaTypes;

public AcceptContentFilterAttribute(string[] mediaTypes, bool allowSingle, bool allowMultiple)
public AcceptContentFilterAttribute(string[] mediaTypes)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we confirm this change also works down stream? There are places like dicom-server\src\Microsoft.Health.Dicom.Api\Extensions\MediaTypeHeaderValueExtensions.cs, where the acceptHeader gets converted to internal objects and passed into service, is the type with and without quotes passed in as same value downstream?

Copy link
Contributor

@jovinson-ms jovinson-ms Apr 5, 2022

Choose a reason for hiding this comment

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

The service currently uses two code paths to handle media type content negotiation - AcceptContentFilterAttribute is used only for single part media types like application/dicom (example), and the GetAcceptHeaders extension method is only used on controller actions that use the Produces attribute for multipart/related media types (example), and then parses to find the media type from the type parameter.

Once we realized that the AcceptContentFilterAttribute doesn't handle multipart/related, we decided to explicitly handle only single part media types there, and consider a future refactor to handle multipart media type content negotiation at the API layer as well.


foreach (MediaTypeHeaderValue acceptHeader in acceptHeaders)
{
if (_mediaTypes.Any(x => x.MatchesMediaType(acceptHeader.MediaType)))
Copy link
Contributor

Choose a reason for hiding this comment

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

As discussed, we will flip this check - the defined media types for this action should be a subset of the Accept header media range, e.g. application/dicom is a subset of application/* and so will match.

…pt header, like application/*. Also removed a now-redundant E2E test.
@jovinson-ms jovinson-ms enabled auto-merge (squash) April 7, 2022 00:42
@jovinson-ms jovinson-ms merged commit ee93cf5 into main Apr 7, 2022
@jovinson-ms jovinson-ms deleted the users/v-mitfox/AB#89350-MediaTypeValidation branch April 7, 2022 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants