This is an automated email from the ASF dual-hosted git repository.

pjfanning pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-http.git


The following commit(s) were added to refs/heads/main by this push:
     new 6cb602c7b Quote Link header parameter values containing a colon (RFC 
8288) (#1365)
6cb602c7b is described below

commit 6cb602c7b1eed5536c5afa816c8b086d67879c49
Author: PJ Fanning <[email protected]>
AuthorDate: Fri Oct 23 15:03:57 2026 +0100

    Quote Link header parameter values containing a colon (RFC 8288) (#1365)
    
    * quote Link header parameter values containing a colon (RFC 8288)
    
    Motivation:
    LinkParams rendered values such as rel=http://example.net/foo unquoted, 
because
    only " ,;" were treated as reserved (per RFC 5988). RFC 8288 obsoletes RFC 
5988
    and requires parameter values that are not a token to be quoted; ':' is not 
a
    token character, so URI relation types must be quoted.
    
    Modification:
    Add ':' to the reserved characters in LinkParams, so rel, rev, title, media 
and
    type values containing a colon are rendered quoted. Parsing still accepts 
the
    unquoted form.
    
    Result:
    Link: </>; rel="http://example.net/foo"; is rendered instead of
    Link: </>; rel=http://example.net/foo.
    
    Tests:
    - sbt "http-core/Test/testOnly 
org.apache.pekko.http.impl.model.parser.HttpHeaderSpec": 75 passed
    - Same spec without the LinkValue change: Link test fails (directional)
    - scalafmt --mode diff-ref=upstream/main: no changes
    
    References:
    Refs akka/akka-http#4267 (Apache 2.0 since the Akka HTTP 10.6.0 change 
date, 2026-10-23)
    
    * update Lightbend copyright years on files with ported Akka HTTP 10.6.0 
code
    
    The ported changes are from Akka HTTP 10.6.0, so these files take the
    Lightbend copyright line of the same files in akka-http v10.6.0, as done
    for earlier ports (#961, #1016).
    
    Tests:
    - sbt headerCheck / Test/headerCheck for the touched modules: pass
    
    References:
    None - license header follow-up for this port
---
 .../org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala  | 6 ++++--
 .../org/apache/pekko/http/impl/model/parser/HttpHeaderSpec.scala  | 8 ++++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git 
a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala
 
b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala
index c83a05324..eb7358b39 100644
--- 
a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala
+++ 
b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala
@@ -8,7 +8,7 @@
  */
 
 /*
- * Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
+ * Copyright (C) 2009-2023 Lightbend Inc. <https://www.lightbend.com>
  */
 
 package org.apache.pekko.http.scaladsl.model.headers
@@ -46,7 +46,9 @@ object LinkParam {
 }
 
 object LinkParams {
-  private val reserved = CharPredicate(" ,;")
+  // Note rfc5988 only lists " ,;" but we add : to align with rfc8288 which 
quotes anything not a token as defined
+  // in rfc7230 (but without having to parse token)
+  private val reserved = CharPredicate(" ,;:")
 
   // A few convenience rels
   val next = rel("next")
diff --git 
a/http-core/src/test/scala/org/apache/pekko/http/impl/model/parser/HttpHeaderSpec.scala
 
b/http-core/src/test/scala/org/apache/pekko/http/impl/model/parser/HttpHeaderSpec.scala
index cc0897d24..5f1271d52 100644
--- 
a/http-core/src/test/scala/org/apache/pekko/http/impl/model/parser/HttpHeaderSpec.scala
+++ 
b/http-core/src/test/scala/org/apache/pekko/http/impl/model/parser/HttpHeaderSpec.scala
@@ -8,7 +8,7 @@
  */
 
 /*
- * Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
+ * Copyright (C) 2009-2023 Lightbend Inc. <https://www.lightbend.com>
  */
 
 package org.apache.pekko.http.impl.model.parser
@@ -504,7 +504,7 @@ class HttpHeaderSpec extends AnyFreeSpec with Matchers {
           .renderedTo("""<http://example.com/TheBook/chapter2>; rel=previous; 
title="previous chapter"""")
 
       """Link: </>; rel="http://example.net/foo""""; =!= Link(Uri("/"), 
LinkParams.rel("http://example.net/foo";))
-        .renderedTo("</>; rel=http://example.net/foo";)
+        .renderedTo("""</>; rel="http://example.net/foo"""";)
 
       """Link: <http://example.org/>; rel="start 
http://example.net/relation/other""""; =!= Link(
         Uri("http://example.org/";),
@@ -512,6 +512,10 @@ class HttpHeaderSpec extends AnyFreeSpec with Matchers {
 
       // only one 'rel=' is allowed, 
http://tools.ietf.org/html/rfc5988#section-5.3 requires any subsequent ones to 
be skipped
       "Link: </>; rel=prev; rel=next" =!=> "</>; rel=prev"
+
+      // make sure we still parse unquoted rel uri
+      """Link: <http://example.org/>; rel=http://example.net/relation/other"""; 
=!=> """<http://example.org/>; rel="http://example.net/relation/other"""";
+      """Link: </>; rev=http://example.net/foo"""; =!=> """</>; 
rev="http://example.net/foo"""";
     }
 
     "Origin" in {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to