spring-projects / spring-projects/spring-session

Session cookie not issued when output buffer size exceeds when including multibyte characters on Jetty server

Open
#3,082 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: bug
Dominant language
Java
Stars
1.9k
Forks
1.2k
Avg merge
4h 27m
Merged PRs (30d)
55

Description

Describe the bug
Session cookie is not issued when the output buffer size exceeds due to including multibyte characters on Spring Boot with Jetty server.

To Reproduce

  1. include Jetty server instead of tomcat

spring boot version: 3.3.1

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.1'
    id 'io.spring.dependency-management' version '1.1.5'
}

Gradle dependency:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation('org.springframework.boot:spring-boot-starter-web') {
        exclude group:'org.springframework.boot', module:'spring-boot-starter-tomcat'
    }
    implementation 'org.springframework.boot:spring-boot-starter-jetty'
    implementation 'org.springframework.session:spring-session-core'
}
  1. In the controller, render a document over 32768 bytes including multibyte characters:
@Controller
public class SessionCookieController {

    public static final String HELLO_IN_JA = "こんにちは"; // 15bytes

    @GetMapping("/cookie")
    public String cookie(HttpSession session, Model model){
        // < 32768 bytes doc
        String html = IntStream.range(0, 2184)
                .mapToObj(i -> HELLO_IN_JA)
                .collect(Collectors.joining());
        model.addAttribute("html", html);
        return "index";
    }

    @GetMapping("/nocookie")
    public String nocookie(HttpSession session, Model model){
        // > 32768 bytes doc
        String html = IntStream.range(0, 2185)
                .mapToObj(i -> HELLO_IN_JA)
                .collect(Collectors.joining());
        model.addAttribute("html", html);
        return "index";
    }
}

index.html
<p th:utext="${html}"></p>

  1. Test with curl:

OK case:

> curl -s -D - localhost:8080/cookie -o /dev/null
HTTP/1.1 200 OK
Date: Tue, 09 Jul 2024 11:19:06 GMT
Content-Language: ja-JP
Content-Type: text/html;charset=utf-8
Set-Cookie: SESSION=ZGZjYWNiMDctZjc1My00YmU1LWEwYmItZGY1MTdkMDg5N2U2; Path=/; HttpOnly; SameSite=Lax
Transfer-Encoding: chunked

NG case:

> curl -s -D - localhost:8080/nocookie -o /dev/null
HTTP/1.1 200 OK
Date: Tue, 09 Jul 2024 11:19:08 GMT
Content-Language: ja-JP
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked

Expected behavior
When the document size is over 32768 bytes (the default output buffer size on Jetty), the response header should include the Set-Cookie header with the session cookie.

When using Tomcat, this issue does not occur. The difference lies in how buffer length is counted: Tomcat uses char array length, while Jetty uses bytes.
Spring Session counts length in org.springframework.session.web.http.OnCommittedResponseWrapper#trackContentLength
(ref:https://github.com/spring-projects/spring-session/issues/851)

Sample

(https://github.com/mjhashimoto/springsessionjettysample/tree/issued20240709)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with org.springframework.session.web.http.OnCommittedResponseWrapper#trackContentLength and compare its length handling with the Jetty behavior described in the issue. Reproduce the /cookie and /nocookie cases using the linked sample; done means a session cookie is included for responses over 32768 bytes containing multibyte characters.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.