spring-cloud / spring-cloud/spring-cloud-gateway

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

Open
#1,337 19 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
4.9k
Forks
3.5k
Avg merge
20h 57m
Merged PRs (30d)
8

Description

  • 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

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

Reproduce the behavior with the provided Spring Boot gateway and target-server examples, using the two curl commands and verbose output. Trace the Expect: 100-continue exchange between gateway and target; done means the request is forwarded compliantly without a duplicate interim response and the target's final hello response reaches the client.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
api, backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.