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

Range response status reset when using a @ServerResponseFilter #45791

Open
jorsol opened this issue Jan 22, 2025 · 9 comments · May be fixed by #45798
Open

Range response status reset when using a @ServerResponseFilter #45791

jorsol opened this issue Jan 22, 2025 · 9 comments · May be fixed by #45798
Labels
area/jbang Issues related to when using jbang.dev with Quarkus kind/bug Something isn't working

Comments

@jorsol
Copy link
Contributor

jorsol commented Jan 22, 2025

Describe the bug

When returning a File Quarkus should use the ServerFileBodyHandler that supports Range requests:

static void sendFile(File file, ServerRequestContext context) {
ResteasyReactiveRequestContext ctx = ((ResteasyReactiveRequestContext) context);
Object rangeObj = ctx.getHeader("Range", true);
ByteRange byteRange = rangeObj == null ? null : ByteRange.parse(rangeObj.toString());
long fileLength = file.length();
if ((byteRange != null) && (byteRange.ranges.size() == 1)) {
ByteRange.Range range = byteRange.ranges.get(0);
ByteRange.Range fileRange = (range.getStart() == -1)
? new ByteRange.Range(fileLength - range.getEnd(), fileLength - 1)
: new ByteRange.Range(range.getStart(), Math.min(fileLength - 1, range.getEnd()));
if ((fileRange.getStart() >= 0) && (fileRange.getStart() <= fileRange.getEnd())) {
String contentRange = "bytes " + fileRange.getStart() + "-" + fileRange.getEnd() + "/" + fileLength;
long length = fileRange.getEnd() - fileRange.getStart() + 1;
context.serverResponse()
.setStatusCode(Response.Status.PARTIAL_CONTENT.getStatusCode())
.setResponseHeader("Content-Range", contentRange)
.sendFile(file.getAbsolutePath(), fileRange.getStart(), length);
return;
}
}
context.serverResponse().sendFile(file.getAbsolutePath(), 0, fileLength);
}

It works fine until I access the response from a @ServerResponseFilter where the response status is reset to 200 instead of the 206:

//usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS io.quarkus.platform:quarkus-bom:3.17.7@pom
//DEPS io.quarkus:quarkus-rest
//JAVAC_OPTIONS -parameters
//JAVA_OPTIONS -Djava.util.logging.manager=org.jboss.logmanager.LogManager

import java.io.File;

import org.jboss.resteasy.reactive.server.ServerResponseFilter;

import io.quarkus.runtime.Quarkus;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.container.ContainerResponseContext;

@Path("/hello")
@ApplicationScoped
public class QuarkusApp {

  @GET
  public File sayHello() {
    return new File("/home/quarkus/data");
  }

  public static void main(String[] args) {
    Quarkus.run(args);
  }

  @ServerResponseFilter
  public void responseHeaders(ContainerResponseContext responseContext) {
    System.out.println(responseContext.getEntity());
  }

}

The ServerFileBodyHandler sets the status code to PARTIAL_CONTENT (206) .setStatusCode(Response.Status.PARTIAL_CONTENT.getStatusCode()) , but the filter is messing up this status (without even changing anything) and reset it to OK 200.

Expected behavior

❯ http :8080/hello Range:bytes=100-199
HTTP/1.1 206 Partial Content
Content-Range: bytes 100-199/10000000000
Content-Type: application/octet-stream
content-length: 100

+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+

The 206 Partial Content code should be present.

Actual behavior

❯ http :8080/hello Range:bytes=100-199
HTTP/1.1 200 OK
Content-Range: bytes 100-199/10000000000
Content-Type: application/octet-stream
content-length: 100

+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+

The 200 OK code is used instead.

How to Reproduce?

Run the QuarkusApp jbang script.

Comment the System.out.println(responseContext.getEntity()); line, and it returns 206, uncomment and it returns 200.

Any access to the response object resets the status code to 200.

Output of uname -a or ver

Linux quarkus 6.12.9-200.fc41.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jan 9 16:05:40 UTC 2025 x86_64 GNU/Linux

Output of java -version

java 23.0.1 2024-10-15

Quarkus version or git rev

3.17.7

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.9

Additional information

No response

@jorsol jorsol added the kind/bug Something isn't working label Jan 22, 2025
@quarkus-bot quarkus-bot bot added the area/jbang Issues related to when using jbang.dev with Quarkus label Jan 22, 2025
Copy link

quarkus-bot bot commented Jan 22, 2025

/cc @maxandersen (jbang), @quarkusio/devtools (jbang)

@geoand
Copy link
Contributor

geoand commented Jan 22, 2025

Could you please create a Maven reproduce that I can use to run the application and see the problem in action?

Thanks

@jorsol
Copy link
Contributor Author

jorsol commented Jan 22, 2025

The reproducer is the jbang script:

//usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS io.quarkus.platform:quarkus-bom:3.17.7@pom
//DEPS io.quarkus:quarkus-rest
//JAVAC_OPTIONS -parameters
//JAVA_OPTIONS -Djava.util.logging.manager=org.jboss.logmanager.LogManager

import java.io.File;

import org.jboss.resteasy.reactive.server.ServerResponseFilter;

import io.quarkus.runtime.Quarkus;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.container.ContainerResponseContext;

@Path("/hello")
@ApplicationScoped
public class QuarkusApp {

  @GET
  public File sayHello() {
    return new File("/home/quarkus/data");
  }

  public static void main(String[] args) {
    Quarkus.run(args);
  }

  @ServerResponseFilter
  public void responseHeaders(ContainerResponseContext responseContext) {
    System.out.println(responseContext.getEntity());
  }

}

@geoand
Copy link
Contributor

geoand commented Jan 22, 2025

I know, but I would really like a Maven project along with a sample data file that triggers the issue

@jorsol
Copy link
Contributor Author

jorsol commented Jan 22, 2025

The data file is anything, could be a text file, or a binary file, it doesn't matter.

bug45791.zip

@geoand
Copy link
Contributor

geoand commented Jan 22, 2025

What size is needed? I tried with a small one and couldn't reproduce the problem

@jorsol
Copy link
Contributor Author

jorsol commented Jan 22, 2025

./mvnw verify to the attached maven project and it triggers the problem.

@geoand
Copy link
Contributor

geoand commented Jan 22, 2025

TY

@geoand
Copy link
Contributor

geoand commented Jan 22, 2025

This will require some thought on how to address it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/jbang Issues related to when using jbang.dev with Quarkus kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants