openresty / openresty/lua-nginx-module

HTTP/2 requests to Lua scripts fail when using 'lua_check_client_abort on'

Open
#724 6 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
11.8k
Forks
2.1k
Avg merge
6h 1m
Merged PRs (30d)
6

Description

This only seems to affect *_by_lua_* scripts that output content directly; rewrite_by_lua_* and access_by_lua_*passages that don't ngx.print() or ngx.say() anything seem to work as normal.

I'm running openresty 1.9.7.4 on debian 7.9 in a Vagrant Virtualbox VM.

Steps to reproduce:

  • Build/make/install openresty 1.9.7.4 from release

  • Generate self-signed SSL cert for relevant IP:

    • openssl genrsa -out /etc/ssl/192.168.56.110.key 2048
    • openssl req -new -x509 -key /etc/ssl/192.168.56.110.key -out /etc/ssl/192.168.56.110.cert -days 3650 -subj /CN=192.168.56.110
  • Add server{} block to /etc/nginx/nginx.conf:

    server {
    
            listen 443 http2 ssl;
            ssl_certificate         /etc/ssl/192.168.56.110.cert;
            ssl_certificate_key     /etc/ssl/192.168.56.110.key;
            ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
    
            location /test-lua {
                   lua_check_client_abort on;
    
                    content_by_lua_block {
                            ngx.header['content-type'] = 'text/plain'
                            ngx.say("hi world")
                    }
            }
    }
    
  • Request /test-lua:

    $ /usr/local/bin/curl -k -v --http2 https://192.168.56.110/test-lua
    *   Trying 192.168.56.110...
    * Connected to 192.168.56.110 (192.168.56.110) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
    * successfully set certificate verify locations:
    *   CAfile: /usr/local/etc/openssl/cert.pem
    CApath: none
    * TLSv1.2 (OUT), TLS header, Certificate Status (22):
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * NPN, negotiated HTTP2 (h2)
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Unknown (67):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
    * ALPN, server did not agree to a protocol
    * Server certificate:
    *        subject: CN=192.168.56.110
    *        start date: Mar 25 14:24:23 2016 GMT
    *        expire date: Mar 23 14:24:23 2026 GMT
    *        issuer: CN=192.168.56.110
    *        SSL certificate verify result: self signed certificate (18), continuing anyway.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * TCP_NODELAY set
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7fdcb300c400)
    > GET /test-lua HTTP/1.1
    > Host: 192.168.56.110
    > User-Agent: curl/7.47.1
    > Accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS updated)!
    * HTTP/2 stream 1 was not closed cleanly: error_code = 2
    * Closing connection 0
    * TLSv1.2 (OUT), TLS alert, Client hello (1):
    curl: (16) HTTP/2 stream 1 was not closed cleanly: error_code = 2
    
  • Error appears in error.log:

    2016/03/25 15:14:06 [alert] 11105#0: *1 epoll_ctl(1, 3) failed (17: File exists), client: 192.168.56.1, server: , request: "GET /test-lua HTTP/2.0", host: "192.168.56.110"

  • Switch off lua_check_client_abort in /etc/nginx/nginx.conf, restart nginx:

    lua_check_client_abort off;

  • Retry request to /test-lua:

    $ /usr/local/bin/curl -k -v --http2 https://192.168.56.110/test-lua
    *   Trying 192.168.56.110...
    * Connected to 192.168.56.110 (192.168.56.110) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
    * successfully set certificate verify locations:
    *   CAfile: /usr/local/etc/openssl/cert.pem
    CApath: none
    * TLSv1.2 (OUT), TLS header, Certificate Status (22):
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * NPN, negotiated HTTP2 (h2)
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Unknown (67):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
    * ALPN, server did not agree to a protocol
    * Server certificate:
    *        subject: CN=192.168.56.110
    *        start date: Mar 25 14:24:23 2016 GMT
    *        expire date: Mar 23 14:24:23 2026 GMT
    *        issuer: CN=192.168.56.110
    *        SSL certificate verify result: self signed certificate (18), continuing anyway.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * TCP_NODELAY set
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7f99ec00c400)
    > GET /test-lua HTTP/1.1
    > Host: 192.168.56.110
    > User-Agent: curl/7.47.1
    > Accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS updated)!
    < HTTP/2.0 200
    < server:openresty/1.9.7.4
    < date:Fri, 25 Mar 2016 15:09:09 GMT
    < content-type:text/plain
    <
    hi world
    * Connection #0 to host 192.168.56.110 left intact
    

Contributor guide

No contributing guide indexed for this repository

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

Start by reproducing the request using the shown nginx server block, content_by_lua_block, and lua_check_client_abort setting, then compare behavior with the setting disabled. Trace the handling of client-abort checks during HTTP/2 responses; done means the Lua script returns a successful HTTP/2 response with the setting enabled and the failure has a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, lua, nginx
Domain
api, backend
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.