ExpressGateway / express-gateway

A microservices API Gateway built on top of Express.js
https://www.express-gateway.io
Apache License 2.0
2.97k stars 347 forks source link

[Bug] Upload of big files in binary results in "[EG:policy] warn: socket hang up" #980

Closed tagkiller closed 3 years ago

tagkiller commented 4 years ago

Hi',

After a lot research and testing I come here to seek some help. I have some random "socket hang up" when I try to upload big files (13mb) from a website, going through express-gateway.

Here is my gateway config

   http:
      port: 8888
    admin:
      port: 9876
      host: 0.0.0.0
    apiEndpoints:
      mgmt:
        host: "{{ api_gateway_mgmt_vip }}"
        paths: [ "/esns" , "/esns/*" , "/upload" , "/device/*/esn" ]
    serviceEndpoints:
      provService:
        url: "http://{{ provisioning_vip_location }}"
    policies:
      - proxy
      - rewrite
      - log
      - cors
      - request-transformer
      - oauth2-introspect
      - rate-limit
      - influx
      - headers
    pipelines:
      esnprovisioningservicemgmt:
        apiEndpoints:
          - mgmt
        policies:
          - cors:
            - action:
                origin: '*'
                methods: '*'
          - request-transformer:
            - action:
                headers:
                  add:
                    RequestID: "requestID"
          - oauth2-introspect:
            - action:
                endpoint: "http://{{ securityservice_vip_location }}/introspect"
                authorization_value: "Bearer {{ lookup('file', 'credentials/jwt_token/' + tele_env + '/service-intern') }}"
                ttl: 60
          - request-transformer:
            - action:
                headers:
                  add:
                    x-auth-principal: "req.user.sub"
                    x-auth-scope: "req.user.scope"
          - rewrite:
            - condition:
                name: regexpmatch
                match: ^/(.*)$
              action:
                rewrite: /$1
          - proxy:
            -
              condition:
                name: pathExact
                path: /upload
              action:
                serviceEndpoint: provService
                changeOrigin: true
                stripPath: false
                proxyTimeout: 10000
            -
              condition:
                name: expression
                expression: "req.url !== '/upload'"
              action:
                serviceEndpoint: provService
                changeOrigin: true
                stripPath: false
                proxyTimeout: 1000

There is no firewall in between my machine and the server running express-gateway. My request is the following (with Postman or the website) : https://{{ api_gateway_mgmt_vip }}:8888/upload

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,nl;q=0.6
Authorization: Bearer my_token
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 13375000
Content-Type:text/csv;charset=utf-8
DNT: 1
Host: {{ api_gateway_mgmt_vip }}

The file is put as a binary in the body.

If you guys manage to reproduce the issue please let me know.

Thanks in advance

tagkiller commented 4 years ago

I think I found the issue, will make a PR. The headersSent flag in the response is checked and end the connection with a 502 if it contains nothing, but when a request expect 100-Continue (basically a Keep-Alive) the headersSent in the response is not set as the connection is not finished yet.

Found the related issue in node-http-proxy.