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

Do not reorder HTTP header values #65249

Merged
merged 31 commits into from
Mar 28, 2022
Merged

Do not reorder HTTP header values #65249

merged 31 commits into from
Mar 28, 2022

Conversation

feiyun0112
Copy link
Contributor

@feiyun0112 feiyun0112 commented Feb 12, 2022

fix #63833

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Feb 12, 2022
@ghost
Copy link

ghost commented Feb 12, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

fix #63833 & #63831

Author: feiyun0112
Assignees: -
Labels:

area-System.Net.Http

Milestone: -

@MihaZupan
Copy link
Member

This will now additionally allocate a List<HeaderStoreItemInfoValue>, HeaderStoreItemInfoValue[] and HeaderStoreItemInfoValue even if only a single valid value was added.

I think we should keep the field as object and allocate the List<object> on demand if more than 1 value is added.

We can also avoid allocating the HeaderStoreItemInfoValue for each parsed value. Instead, we can store the values as objects like before, but use a new internal record InvalidValue(string Value) to differentiate between parsed/invalid values. I.e. only paying the extra cost for invalid values.

I also don't believe this will solve #63831 as that deals with the enumeration order when values are both parsed and unparsed.

@MihaZupan
Copy link
Member

What I meant is that you would have a field

internal object ParsedAndInvalidValues;

where that object can be null/object/InvalidValue/List<object>.

If only a single value is added (common case), the field will store an InvalidValue or a different object (e.g. a boxed DateTime value).
The List<object> is only allocated if more values are added.

public bool ContainsParsedValues()
{
    object parsedAndInvalidValues = ParsedAndInvalidValues;
    if (parsedAndInvalidValues is null)
    {
        return false;
    }

    if (parsedAndInvalidValues is List<object> list)
    {
        foreach (object value in list)
        {
            if (value is not InvalidValue)
            {
                return true;
            }
        }

        return false;
    }
    else
    {
        return parsedAndInvalidValues is not InvalidValue;
    }
}

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

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

This is looking a lot better! Thanks for sticking with me here :)

The main missing parts here are changes to HttpHeaderParsers that rely on the storeValue passed to them. Before, they may have been relying on there being a single value, but now it may be a list that includes invalid values.
For example the CacheControlHeaderParser has to be updated to account for the possibility of being passed a List when extracting a possible existing CacheControlHeaderValue. Having more test coverage here would also be great.

@MihaZupan MihaZupan added this to the 7.0.0 milestone Feb 21, 2022
Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

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

The parsers should still be updated to account for InvalidValues. See #65249 (review)

feiyun0112 and others added 3 commits March 16, 2022 09:57
…eControlHeaderParser.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
…Headers.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
@geoffkizer
Copy link
Contributor

I don't think this fixes #63831, does it? At least, I didn't see where, and I didn't see a test case for it. Did I miss it?

@MihaZupan
Copy link
Member

I don't think this fixes #63831, does it?

It does not. I removed it from the PR description to avoid confusion.

@MihaZupan
Copy link
Member

@feiyun0112 It appears this comment has been marked as resolved multiple times - is there an associated change I missed?

feiyun0112 and others added 3 commits March 22, 2022 14:32
…Headers.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
…Headers.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

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

Thanks @feiyun0112

@MihaZupan
Copy link
Member

/azp run runtime-libraries-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MihaZupan MihaZupan merged commit 5653909 into dotnet:main Mar 28, 2022
radekdoulik pushed a commit to radekdoulik/runtime that referenced this pull request Mar 30, 2022
* Do not reorder HTTP header values

* fix complie error

* make the changes @ danmoseley recommended

* make the changes @MihaZupan recommended

* make the changes @MihaZupan recommended

* make the changes @MihaZupan recommended

* make the changes @MihaZupan recommended

* make the changes @MihaZupan recommended

* check array length

* fix unit test

* Update src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* make the changes @MihaZupan recommended

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* chang unit test

* GetParsedValueLength

* fix build error

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* unit test

* make changes @geoffkizer recommended

* CloneAndAddValue for InvalidValues

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* Update src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>

* Final nits

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
@ghost ghost locked as resolved and limited conversation to collaborators Apr 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Http community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handling of "invalid" HTTP header values results in values being incorrectly reordered
4 participants