question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Gateway should handle header 'Expect 100-continue' compliant with rfc2616

See original GitHub issue
  • If a proxy receives a request that includes an Expect request- header field with the “100-continue” expectation, and the proxy either knows that the next-hop server complies with HTTP/1.1 or higher, or does not know the HTTP version of the next-hop server, it MUST forward the request, including the Expect header field.

Steps to reproduce problem

Target server: Spring Boot 2.1.8 (Tomcat)

@SpringBootApplication @RestController 
public class MyDownstreamApp {
   public static void main(String[] args) {
      SpringApplication.run(MyDownstreamApp.class, args);
  }

  @PutMapping("/put")
  String put(@RequestParam String x) {
      System.out.println("x: " +x);
      return "hello";
  }
}

Cloud gateway: Greenwich SR3

@SpringBootApplication
public class MyGatewayApp {

    @Bean
    RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p -> p
                        .path("/put")
                        .uri("http://localhost:8080"))
                .build();
    }

    public static void main(String[] args) {
        SpringApplication.run(MyGatewayApp.class, "--server.port=8082");
    }
}

When target server is called directly: curl localhost:8080/put -X PUT -H 'Expect: 100-continue' -d x=foo1 -v

communication flow is OK

  1. Client sends Expect: 100-continue
  2. Server reponds 100-continue
  3. Client sends complete request
  4. Server responds hello

> Expect: 100-continue > Content-Length: 6 > Content-Type: application/x-www-form-urlencoded > < HTTP/1.1 100 * We are completely uploaded and fine < HTTP/1.1 200 < Content-Type: text/plain;charset=UTF-8 < Content-Length: 5

When target server is called through gateway: curl localhost:8082/put -X PUT -H 'Expect: 100-continue' -d x=foo1 -v

communication flow is not OK. My wireshark investigation

  1. Client sends Expect: 100-continue to gateway
  2. Gateway responds 100-continue
  3. Client sends complete request to gateway
  4. I’m not sure 100% what happens in point 4
  5. Target server responds 100-continue to gateway
  6. Gateway sends complete request to target server
  7. Target server responds hello
  8. Gateway forwards 100-continue to client
  9. Client waits for response hello but it is not forwarded

> Expect: 100-continue > Content-Length: 6 > Content-Type: application/x-www-form-urlencoded > < HTTP/1.1 100 Continue * We are completely uploaded and fine < HTTP/1.1 100 Continue (hang up)

Response 100 Continue is received 2 times - once generated by gateway itself, second forwarded from target server, but true response never reach client.

Worth to notice that workaround is filter our header 'Expect 100-continue` when gateway forwards request to target server

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:5
  • Comments:19 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
spencergibbcommented, Apr 14, 2020

I’m able to send a 100 Continue from gateway (or let the downstream service send it), but it seems the request is terminated and the client never sends the body. I’m not sure where in the stack the problem is.

0reactions
michael-ocommented, Oct 15, 2021

I reckon I haven’t given enough details about what I’m trying to do. We have several micro-services behind a spring-cloud-gateway which is accessed by mobile games. We want the gateway to handle Expect 100-continue headers and respond with 100. We don’t want the gateway to pass the request to downstream services in this case. Before spring-boot 2.4.3, we added RemoveRequestHeader and the gateway worked as required. Since upgrading to spring-boot 2.4.3 it passes the request downstream which we don’t want it to do. I tried to implement a gateway filter responsible to intercept Expect 100-continue requests, set the response to 100 and complete the response. I can’t make it work; I alwys the following exception: Connection prematurely closed BEFORE response; nested exception is reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response org.springframework.web.reactive.function.client.WebClientRequestException: Connection prematurely closed BEFORE response; nested exception is reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:137)

This clearly violates https://datatracker.ietf.org/doc/html/rfc7231#section-5.1.1. If the proxy cannot handle the expect handle it must ask the origin. So I expect the API gateway to forward all request headers to the origin server if it cannot make a decision based on the headers.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Gateway should handle header 'Expect 100-continue ...
Gateway should handle header 'Expect 100-continue' compliant with rfc2616.
Read more >
HTTP/1.1: Header Field Definitions
The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used...
Read more >
RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
A client MUST NOT send an Expect request-header field (section 14.20) with the "100-continue" expectation if it does not intend to send a...
Read more >
RFC 2616 HTTP/1.1 - IETF
A client MUST NOT send an Expect request-header field (section 14.20) with the "100-continue" expectation if it does not intend to send a...
Read more >
Support for 'Expect: 100-Continue' in Google HTTP Load ...
However, the Expect request-header itself is end-to-end; it MUST be ... we need the load balancer to at least respond with the 417...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found