Skip to content

[API] Use weak comparison for If-None-Match validation #324

@RedZapdos123

Description

@RedZapdos123

Description:

Rage::Request#fresh? currently compares If-None-Match values against the response ETag using exact string equality.

Rage emits weak ETags like W/"...", but when the request sends the matching strong form like "...", the request is treated as stale and the action still renders the body.

For If-None-Match, weak comparison should be used for normal GET and HEAD validation.

Minimal reproducible example (MRE):

require "digest"
require "rage/all"

class TestController < RageController::API
  def stale_etag_test
    return unless stale?(etag: "123")

    render plain: "body"
  end
end

handler = TestController.__register_action(:stale_etag_test)
env = {
  "HTTP_IF_NONE_MATCH" => "\"#{Digest::SHA1.hexdigest("123")}\""
}

TestController.new(env, {}).public_send(handler)
# => [200, {"content-type"=>"text/plain; charset=utf-8", "etag"=>"W/\"40bd001563085fc35165329ea1ff5c5ecbdbbeef\"", "last-modified"=>nil}, ["body"]]

The issue reproduction:

Image

Current behavior:

When the request sends a strong If-None-Match value that matches the response ETag value apart from the weak W/ prefix, Rage renders the resource:

[200, {"content-type"=>"text/plain; charset=utf-8", "etag"=>"W/\"40bd001563085fc35165329ea1ff5c5ecbdbbeef\"", "last-modified"=>nil}, ["body"]]

Expected behavior:

For GET and HEAD validation, If-None-Match should use weak comparison.

With the same request, the matching strong form should be treated as not modified against the weak response ETag, and Rage should return:

[304, {"etag"=>"W/\"40bd001563085fc35165329ea1ff5c5ecbdbbeef\"", ...}, []]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions