[net] internal/httpsfv: add parsing functionality for types defined in RFC 8941

1 view
Skip to first unread message

Nicholas Husin (Gerrit)

unread,
Oct 1, 2025, 3:40:40 PM (13 hours ago) Oct 1
to goph...@pubsubhelper.golang.org, Damien Neil, Go LUCI, golang-co...@googlegroups.com
Attention needed from Damien Neil

New activity on the change

Open in Gerrit

Related details

Attention is currently required from:
  • Damien Neil
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: net
Gerrit-Branch: master
Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
Gerrit-Change-Number: 708435
Gerrit-PatchSet: 4
Gerrit-Owner: Nicholas Husin <n...@golang.org>
Gerrit-Reviewer: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Nicholas Husin <n...@golang.org>
Gerrit-Attention: Damien Neil <dn...@google.com>
Gerrit-Comment-Date: Wed, 01 Oct 2025 19:40:35 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
unsatisfied_requirement
satisfied_requirement
open
diffy

Damien Neil (Gerrit)

unread,
Oct 1, 2025, 8:40:10 PM (8 hours ago) Oct 1
to Nicholas Husin, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
Attention needed from Nicholas Husin

Damien Neil voted and added 3 comments

Votes added by Damien Neil

Code-Review+2

3 comments

File internal/httpsfv/httpsfv.go
Line 372, Patchset 4 (Latest):// Structured Field Values.
Damien Neil . unresolved

Simpler:

ParseInteger parses an Integer value.

Line 378, Patchset 4 (Latest):func ParseInteger(s string) (parsed int64, ok bool) {
Damien Neil . resolved

This is fine for the moment, but I think we're going to want to change this a bit if we externalize this package. (And I realize that the current function signature was my suggestion in the first place, so apologies.)

ParseInteger parses an Integer value. If a user is trying to parse a SFV header containing an Integer, it will be tempting to write something like:

```
v, ok := httpsfv.ParseInteger(header.Get("Some-Integer-Field"))
```

However, this will be wrong: It won't handle leading and trailing whitespace, and it won't handle attributes. We'll either need a `ParseIntegerField` function, or a `ParseItem` which returns a value which should subsequently be passed to `ParseInteger`.

I'm not sure what the right API is yet (and what we have here is fine for our immediate internal needs) but if we externalize this, we'll want to make it hard to accidentally do the wrong thing.

Line 388, Patchset 4 (Latest):// ParseDecimal used to parse a string that represents a decimal in an HTTP
Damien Neil . unresolved

Missing "is", but "ParseDecimal parses a Decimal value" is simpler.

Open in Gerrit

Related details

Attention is currently required from:
  • Nicholas Husin
Submit Requirements:
  • requirement satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: net
Gerrit-Branch: master
Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
Gerrit-Change-Number: 708435
Gerrit-PatchSet: 4
Gerrit-Owner: Nicholas Husin <n...@golang.org>
Gerrit-Reviewer: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Nicholas Husin <n...@golang.org>
Gerrit-Attention: Nicholas Husin <n...@golang.org>
Gerrit-Comment-Date: Thu, 02 Oct 2025 00:40:05 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Nicholas Husin (Gerrit)

unread,
Oct 1, 2025, 9:47:15 PM (7 hours ago) Oct 1
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Nicholas Husin

Nicholas Husin uploaded new patchset

Nicholas Husin uploaded patch set #5 to this change.
Following approvals got outdated and were removed:
  • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit

Related details

Attention is currently required from:
  • Nicholas Husin
Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: newpatchset
    Gerrit-Project: net
    Gerrit-Branch: master
    Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
    Gerrit-Change-Number: 708435
    Gerrit-PatchSet: 5
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Nicholas Husin (Gerrit)

    unread,
    Oct 1, 2025, 9:47:32 PM (7 hours ago) Oct 1
    to goph...@pubsubhelper.golang.org, Damien Neil, Go LUCI, golang-co...@googlegroups.com

    Nicholas Husin added 3 comments

    File internal/httpsfv/httpsfv.go
    Line 372, Patchset 4:// Structured Field Values.
    Damien Neil . resolved

    Simpler:

    ParseInteger parses an Integer value.

    Nicholas Husin

    Thanks! Updated it along with all other comments.

    Line 378, Patchset 4:func ParseInteger(s string) (parsed int64, ok bool) {
    Damien Neil . resolved

    This is fine for the moment, but I think we're going to want to change this a bit if we externalize this package. (And I realize that the current function signature was my suggestion in the first place, so apologies.)

    ParseInteger parses an Integer value. If a user is trying to parse a SFV header containing an Integer, it will be tempting to write something like:

    ```
    v, ok := httpsfv.ParseInteger(header.Get("Some-Integer-Field"))
    ```

    However, this will be wrong: It won't handle leading and trailing whitespace, and it won't handle attributes. We'll either need a `ParseIntegerField` function, or a `ParseItem` which returns a value which should subsequently be passed to `ParseInteger`.

    I'm not sure what the right API is yet (and what we have here is fine for our immediate internal needs) but if we externalize this, we'll want to make it hard to accidentally do the wrong thing.

    Nicholas Husin

    Hmm, that makes sense...

    We'll either need a ParseIntegerField function, or a ParseItem which returns a value which should subsequently be passed to ParseInteger.

    We do have a `ParseItem` already. Although, I'm not sure it'll help much with the temptation you outlined (if I imagine myself as a user wanting to get an integer, I'd probably look for `ParseInteger` first and roll with that before I found `ParseItem`). Item parsing also do not allow leading whitespace, following the spec.

    Some initial ideas here:

    • We don't expose individual `ParseXxx` functions, but instead just give `ParseBareItem(s string) (any, ParsedType)`, where `ParsedType` indicates which type we detected (`Integer`, `Decimal`, `Unknown` for error). So, the expectation is clear that we only expect bare items.
    • We change the signatures to `ParseInteger(s string, mustParseAll bool) (parsed int64, ok bool)`. if `mustParseAll` is `false`, we don't return `ok = false` when we cannot consume the entire string. That way, the expectation is clearer to the caller, and they can choose to ignore attached parameters if they so desire.
    • Maybe we can just rename these to `ParseBareXxx`? Or, expose different variants (at the risk of a large API surface, so leaning no here personally) such as `MustParseXxx` (errors out if it cannot consume all the string) and `ParseXxx`.
    Line 388, Patchset 4:// ParseDecimal used to parse a string that represents a decimal in an HTTP
    Damien Neil . resolved

    Missing "is", but "ParseDecimal parses a Decimal value" is simpler.

    Nicholas Husin

    Fixed, thanks!

    Open in Gerrit

    Related details

    Attention set is empty
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: net
    Gerrit-Branch: master
    Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
    Gerrit-Change-Number: 708435
    Gerrit-PatchSet: 5
    Gerrit-Owner: Nicholas Husin <n...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Nicholas Husin <n...@golang.org>
    Gerrit-Comment-Date: Thu, 02 Oct 2025 01:47:29 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Damien Neil <dn...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Nicholas Husin (Gerrit)

    unread,
    Oct 1, 2025, 9:49:23 PM (7 hours ago) Oct 1
    to Nicholas Husin, goph...@pubsubhelper.golang.org, Damien Neil, Go LUCI, golang-co...@googlegroups.com
    Attention needed from Nicholas Husin

    Nicholas Husin voted Code-Review+1

    Code-Review+1
    Open in Gerrit

    Related details

    Attention is currently required from:
    • Nicholas Husin
    Submit Requirements:
      • requirement satisfiedCode-Review
      • requirement satisfiedNo-Unresolved-Comments
      • requirement satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
      Gerrit-Change-Number: 708435
      Gerrit-PatchSet: 5
      Gerrit-Owner: Nicholas Husin <n...@golang.org>
      Gerrit-Reviewer: Damien Neil <dn...@google.com>
      Gerrit-Reviewer: Nicholas Husin <hu...@google.com>
      Gerrit-Reviewer: Nicholas Husin <n...@golang.org>
      Gerrit-Attention: Nicholas Husin <n...@golang.org>
      Gerrit-Comment-Date: Thu, 02 Oct 2025 01:49:19 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Damien Neil (Gerrit)

      unread,
      Oct 1, 2025, 9:54:43 PM (6 hours ago) Oct 1
      to Nicholas Husin, goph...@pubsubhelper.golang.org, Go LUCI, Nicholas Husin, golang-co...@googlegroups.com
      Attention needed from Nicholas Husin

      Damien Neil voted and added 1 comment

      Votes added by Damien Neil

      Code-Review+2

      1 comment

      File internal/httpsfv/httpsfv.go
      Line 378, Patchset 4:func ParseInteger(s string) (parsed int64, ok bool) {
      Damien Neil . resolved

      This is fine for the moment, but I think we're going to want to change this a bit if we externalize this package. (And I realize that the current function signature was my suggestion in the first place, so apologies.)

      ParseInteger parses an Integer value. If a user is trying to parse a SFV header containing an Integer, it will be tempting to write something like:

      ```
      v, ok := httpsfv.ParseInteger(header.Get("Some-Integer-Field"))
      ```

      However, this will be wrong: It won't handle leading and trailing whitespace, and it won't handle attributes. We'll either need a `ParseIntegerField` function, or a `ParseItem` which returns a value which should subsequently be passed to `ParseInteger`.

      I'm not sure what the right API is yet (and what we have here is fine for our immediate internal needs) but if we externalize this, we'll want to make it hard to accidentally do the wrong thing.

      Nicholas Husin

      Hmm, that makes sense...

      We'll either need a ParseIntegerField function, or a ParseItem which returns a value which should subsequently be passed to ParseInteger.

      We do have a `ParseItem` already. Although, I'm not sure it'll help much with the temptation you outlined (if I imagine myself as a user wanting to get an integer, I'd probably look for `ParseInteger` first and roll with that before I found `ParseItem`). Item parsing also do not allow leading whitespace, following the spec.

      Some initial ideas here:

      • We don't expose individual `ParseXxx` functions, but instead just give `ParseBareItem(s string) (any, ParsedType)`, where `ParsedType` indicates which type we detected (`Integer`, `Decimal`, `Unknown` for error). So, the expectation is clear that we only expect bare items.
      • We change the signatures to `ParseInteger(s string, mustParseAll bool) (parsed int64, ok bool)`. if `mustParseAll` is `false`, we don't return `ok = false` when we cannot consume the entire string. That way, the expectation is clearer to the caller, and they can choose to ignore attached parameters if they so desire.
      • Maybe we can just rename these to `ParseBareXxx`? Or, expose different variants (at the risk of a large API surface, so leaning no here personally) such as `MustParseXxx` (errors out if it cannot consume all the string) and `ParseXxx`.
      Damien Neil

      `ParseBareInteger` etc. seems like good naming to make the behavior clear. We may as well do that.

      For a final API (sorry, this is a lousy place to do design but I'm already typing), one possibility is something like:

      ```
      // item and attrs are strings.
      // ParseItem discards leading and trailing whitespace and splits off the attribute.
      item, attrs, err := httpsfv.ParseItem(value)

      // try to parse item
      s, err := httpsfv.ParseBareString(item)
      ```

      Another is to introduce an item type:

      ```
      // item is an httpsfv.Item
      item, err := httpsfv.ParseItem(value)

      // iterate over the item's attributes
      item.Attributes(func(key string, value Item) {
      })

      // try to interpret item as a String
      s, err := item.String()
      ```

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Nicholas Husin
      Submit Requirements:
        • requirement satisfiedCode-Review
        • requirement satisfiedNo-Unresolved-Comments
        • requirement satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: net
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
        Gerrit-Change-Number: 708435
        Gerrit-PatchSet: 5
        Gerrit-Owner: Nicholas Husin <n...@golang.org>
        Gerrit-Reviewer: Damien Neil <dn...@google.com>
        Gerrit-Reviewer: Nicholas Husin <hu...@google.com>
        Gerrit-Reviewer: Nicholas Husin <n...@golang.org>
        Gerrit-Attention: Nicholas Husin <n...@golang.org>
        Gerrit-Comment-Date: Thu, 02 Oct 2025 01:54:38 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes
        Comment-In-Reply-To: Damien Neil <dn...@google.com>
        Comment-In-Reply-To: Nicholas Husin <n...@golang.org>
        satisfied_requirement
        open
        diffy

        Gopher Robot (Gerrit)

        unread,
        Oct 1, 2025, 9:54:49 PM (6 hours ago) Oct 1
        to Nicholas Husin, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go LUCI, Nicholas Husin, Damien Neil, golang-co...@googlegroups.com

        Gopher Robot submitted the change

        Change information

        Commit message:
        internal/httpsfv: add parsing functionality for types defined in RFC 8941

        This change introduces parsing functions for all item types defined in
        RFC 8941, namely: integers, decimals, strings, tokens, byte sequences,
        and booleans.

        At this point, internal/httpsfv should be usable for parsing any RFC
        8941-compliant HTTP Structured Field Values.

        In a future CL, we will add support for parsing display strings and
        dates, so that this package fully supports RFC 9651.

        For golang/go#75500
        Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
        Auto-Submit: Nicholas Husin <n...@golang.org>
        Reviewed-by: Damien Neil <dn...@google.com>
        Reviewed-by: Nicholas Husin <hu...@google.com>
        Files:
        • M internal/httpsfv/httpsfv.go
        • M internal/httpsfv/httpsfv_test.go
        Change size: L
        Delta: 2 files changed, 389 insertions(+), 31 deletions(-)
        Branch: refs/heads/master
        Submit Requirements:
        • requirement satisfiedCode-Review: +2 by Damien Neil, +1 by Nicholas Husin
        • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
        Open in Gerrit
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: merged
        Gerrit-Project: net
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8ad2caa5f6ea4285d00506faa4b8127c2cc9419
        Gerrit-Change-Number: 708435
        Gerrit-PatchSet: 6
        Gerrit-Owner: Nicholas Husin <n...@golang.org>
        Gerrit-Reviewer: Damien Neil <dn...@google.com>
        Gerrit-Reviewer: Gopher Robot <go...@golang.org>
        open
        diffy
        satisfied_requirement
        Reply all
        Reply to author
        Forward
        0 new messages