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

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

Open
mjhashimoto opened this issue Jul 9, 2024 · 0 comments
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug

Comments

@mjhashimoto
Copy link

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:#851)

Sample

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

@mjhashimoto mjhashimoto added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug
Projects
None yet
Development

No branches or pull requests

1 participant