I got a problem while testing an nginx server patched with Quiche implementation of HTTP/3 with curl: when I try to send multiple consecutive request for a small html page (~1kb), nginx responds correctly
root#cUrlClient:~# ./curl/src/curl https://192.168.19.128?[1-5] -Ik --http3
[1/5]: https://192.168.19.128?1 --> <stdout>
--_curl_--https://192.168.19.128?1
HTTP/3 200
server: nginx/1.16.1
date: Mon, 25 Nov 2019 13:44:21 GMT
content-type: text/html
content-length: 924
last-modified: Mon, 25 Nov 2019 12:07:59 GMT
etag: "5ddbc41f-39c"
alt-svc: h3-23=":443"; ma=86400
accept-ranges: bytes
[2/5]: https://192.168.19.128?2 --> <stdout>
--_curl_--https://192.168.19.128?2
HTTP/3 200
server: nginx/1.16.1
date: Mon, 25 Nov 2019 13:44:21 GMT
content-type: text/html
content-length: 924
last-modified: Mon, 25 Nov 2019 12:07:59 GMT
etag: "5ddbc41f-39c"
alt-svc: h3-23=":443"; ma=86400
accept-ranges: bytes
[3/5]: https://192.168.19.128?3 --> <stdout>
--_curl_--https://192.168.19.128?3
HTTP/3 200
server: nginx/1.16.1
date: Mon, 25 Nov 2019 13:44:21 GMT
content-type: text/html
content-length: 924
last-modified: Mon, 25 Nov 2019 12:07:59 GMT
etag: "5ddbc41f-39c"
alt-svc: h3-23=":443"; ma=86400
accept-ranges: bytes
[4/5]: https://192.168.19.128?4 --> <stdout>
--_curl_--https://192.168.19.128?4
HTTP/3 200
server: nginx/1.16.1
date: Mon, 25 Nov 2019 13:44:21 GMT
content-type: text/html
content-length: 924
last-modified: Mon, 25 Nov 2019 12:07:59 GMT
etag: "5ddbc41f-39c"
alt-svc: h3-23=":443"; ma=86400
accept-ranges: bytes
[5/5]: https://192.168.19.128?5 --> <stdout>
--_curl_--https://192.168.19.128?5
HTTP/3 200
server: nginx/1.16.1
date: Mon, 25 Nov 2019 13:44:21 GMT
content-type: text/html
content-length: 924
last-modified: Mon, 25 Nov 2019 12:07:59 GMT
etag: "5ddbc41f-39c"
alt-svc: h3-23=":443"; ma=86400
accept-ranges: bytes
If I try to make a single request to a medium/big html file, nginx respond correctly again, but when I try to make multiple consecutive request to a medium/big html page (>=30kb), nginx stop responding after an arbitrary number of requests (2-5 requests normally). Here's an example made of 10 requests to the https://cloudflare-quic.com html page (which I downloaded on my server):
root#cUrlClient:~# ./curl/src/curl -Ik https://192.168.19.128/cloudflare.html?[1-10] --http3 -v
[1/10]: https://192.168.19.128/cloudflare.html?1 --> <stdout>
--_curl_--https://192.168.19.128/cloudflare.html?1
* Trying 192.168.19.128:443...
* Sent QUIC client Initial, ALPN: h3-23
* h3 [:method: HEAD]
* h3 [:path: /cloudflare.html?1]
* h3 [:scheme: https]
* h3 [:authority: 192.168.19.128]
* h3 [user-agent: curl/7.67.0-DEV]
* h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x5614ee569460)
> HEAD /cloudflare.html?1 HTTP/3
> Host: 192.168.19.128
> user-agent: curl/7.67.0-DEV
> accept: */*
>
< HTTP/3 200
HTTP/3 200
< server: nginx/1.16.1
server: nginx/1.16.1
< date: Mon, 25 Nov 2019 13:53:43 GMT
date: Mon, 25 Nov 2019 13:53:43 GMT
< content-type: text/html
content-type: text/html
< content-length: 106072
content-length: 106072
< vary: Accept-Encoding
vary: Accept-Encoding
< etag: "5ddbdc21-19e58"
etag: "5ddbdc21-19e58"
< alt-svc: h3-23=":443"; ma=86400
alt-svc: h3-23=":443"; ma=86400
< accept-ranges: bytes
accept-ranges: bytes
<
* Excess found: excess = 27523 url = /cloudflare.html (zero-length body)
* Connection #0 to host 192.168.19.128 left intact
[2/10]: https://192.168.19.128/cloudflare.html?2 --> <stdout>
--_curl_--https://192.168.19.128/cloudflare.html?2
* Found bundle for host 192.168.19.128: 0x5614ee56db00 [can multiplex]
* Re-using existing connection! (#0) with host 192.168.19.128
* Connected to 192.168.19.128 (192.168.19.128) port 443 (#0)
* h3 [:method: HEAD]
* h3 [:path: /cloudflare.html?2]
* h3 [:scheme: https]
* h3 [:authority: 192.168.19.128]
* h3 [user-agent: curl/7.67.0-DEV]
* h3 [accept: */*]
* Using HTTP/3 Stream ID: 4 (easy handle 0x5614ee56b2b0)
> HEAD /cloudflare.html?2 HTTP/3
> Host: 192.168.19.128
> user-agent: curl/7.67.0-DEV
> accept: */*
>
* Got h3 for stream 0, expects 4
* Got h3 for stream 0, expects 4
* Got h3 for stream 0, expects 4
* Got h3 for stream 0, expects 4
[...]
It stucks on this screen repeating "Got h3 for stream 0, expects 4". Also I noticed that, when testing on smaller pages, that the smallest the file the bigger is the number of requests fullfilled before stop responding and start printing the error "Got h3 for stream x, expecting y", whith the relation that y=x+4.
Also the access.log and the error.log are clean, meaning that it could maybe be some king of parameter missing in the server configuration, but I'm not sure about it.
Does anyone have an idea of what the problem could be?
My config
nginx version:
nginx version: nginx/1.16.1
built by gcc 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2)
built with OpenSSL 1.1.0 (compatible; BoringSSL) (running with BoringSSL)
TLS SNI support enabled
configure arguments:
--prefix=/root/nginx-1.16.1
--with-http_ssl_module
--with-http_v2_module
--with-http_v3_module
--with-openssl=../quiche/deps/boringssl
--with-quiche=../quiche
nginx.conf:
user root;
# you must set worker processes based on your CPU cores, nginx does not benefit from setting more than that
worker_processes auto; #some last versions calculate it automatically
# number of file descriptors used for nginx
# the limit for the maximum FDs on the server is usually set by the OS.
# if you don't set FD's then OS settings will be used which is by default 2000
worker_rlimit_nofile 100000;
# only log critical errors
error_log logs/error.log crit;
error_log logs/error.log debug;
error_log logs/error.log notice;
error_log logs/error.log info;
# provides the configuration file context in which the directives that affect connection processing are specified.
events {
# determines how much clients will be served per worker
# max clients = worker_connections * worker_processes
# max clients is also limited by the number of socket connections available on the system (~64k)
worker_connections 4000;
# optimized to serve many clients with each thread, essential for linux -- for testing environment
use epoll;
# accept as many connections as possible, may flood worker connections if set too low -- for testing environment
multi_accept on;
}
http {
# cache informations about FDs, frequently accessed files
# can boost performance, but you need to test those values
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# to boost I/O on HDD we can disable access logs
access_log on;
# copies data between one FD and other from within the kernel
# faster than read() + write()
sendfile on;
# send headers in one piece, it is better than sending them one by one
tcp_nopush on;
# don't buffer data sent, good for small data bursts in real time
tcp_nodelay on;
# reduce the data that needs to be sent over network -- for testing environment
gzip on;
# gzip_static on;
gzip_min_length 10240;
gzip_comp_level 1;
gzip_vary on;
gzip_disable msie6;
gzip_proxied expired no-cache no-store private auth;
gzip_types
# text/html is always compressed by HttpGzipModule
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
application/atom+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
# allow the server to close connection on non responding client, this will free up memory
reset_timedout_connection on;
# request timed out -- default 60
client_body_timeout 10;
# if client stop responding, free up memory -- default 60
send_timeout 2;
# server will close connection after this time -- default 75
keepalive_timeout 30;
# number of requests client can make over keep-alive -- for testing environment
keepalive_requests 100000;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
########################################################
########################################################
server {
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
gzip on;
# Enable QUIC and HTTP/3.
listen 443 quic reuseport;
# Enable HTTP/2 (optional).
listen 443 ssl http2;
ssl_certificate certificate.pem;
ssl_certificate_key key.pem;
# Enable all TLS versions (TLSv1.3 is required for QUIC).
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
# Add Alt-Svc header to negotiate HTTP/3.
add_header alt-svc 'h3-23=":443"; ma=86400';
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
###Limits the maximum number of concurrent HTTP/3 streams in a connection.
http3_max_concurrent_streams 256;
###Limits the maximum number of requests that can be served on a single HTTP/3 connection,
###after which the next client request will lead to connection closing and the need of establishing a new connection.
http3_max_requests 20000;
###Limits the maximum size of the entire request header list after QPACK decompression.
http3_max_header_size 100000k;
###Sets the per-connection incoming flow control limit.
http3_initial_max_data 2000000m;
###Sets the per-stream incoming flow control limit.
http3_initial_max_stream_data 1000000m;
###Sets the timeout of inactivity after which the connection is closed.
http3_idle_timeout 1500000m;
}
########################################################
########################################################
}
Curl version
curl 7.67.0-DEV (x86_64-pc-linux-gnu) libcurl/7.67.0-DEV BoringSSL zlib/1.2.11 nghttp2/1.39.2 quiche/0.1.0
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL UnixSockets
EDIT
We discussed about this issue on the Cloudflare quiche repo and we find that it's known curl problem: GitHub Issue
Related
I am running nginx version: nginx/1.20.2 onCentOS Linux release 7.9.2009 (Core) as reverse proxy. I have added the below line in main context of /etc/nginx/nginx.conf config file
cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
load_module modules/ngx_http_cache_purge_module.so;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
nginx -t -c /etc/nginx/nginx.conf
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
location / {
add_header Access-Control-Allow-Origin *;
proxy_pass http://127.0.0.1:8080;
proxy_cache_purge PURGE from 127.0.0.1 36.115.171.121 14.18.155.4;
#proxy_cache_bypass $bypass;
# configure proxy-cache-purge
#proxy_cache_purge PURGE from 0.0.0.0;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_hide_header X-Powered-By;
proxy_hide_header X-Generator;
proxy_hide_header X-Drupal-Cache;
proxy_hide_header X-Drupal-Dynamic-Cache;
proxy_hide_header Server;
proxy_store_access group:rw;
#page caching configuration
proxy_ignore_headers Vary;
proxy_ignore_headers Set-Cookie;
proxy_cache testnginx;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
The nginx cache has the contents which are as follows.
# pwd
/var/www/nginx/cache
#
# ls -l
total 0
drwxrwxrwx. 14 nginx deployuser 114 May 8 05:58 content
drwxrwxrwx. 15 nginx deployuser 123 May 8 07:31 files
#
/var/www/nginx/cache/files
# ls -l
total 0
drwx------ 4 nginx nginx 26 May 8 05:58 0
drwx------ 4 nginx nginx 26 May 8 06:04 1
drwx------ 5 nginx nginx 36 May 8 05:58 2
drwx------ 3 nginx nginx 16 May 6 12:12 3
drwx------ 4 nginx nginx 26 May 8 05:58 4
drwx------ 3 nginx nginx 16 May 8 06:04 6
drwx------ 3 nginx nginx 16 May 8 06:04 7
drwx------ 3 nginx nginx 16 May 5 10:44 9
drwx------ 3 nginx nginx 16 May 5 10:44 a
drwx------ 3 nginx nginx 16 May 8 06:04 b
drwx------ 3 nginx nginx 16 May 8 07:31 d
drwx------ 4 nginx nginx 26 May 8 06:04 e
drwx------ 3 nginx nginx 16 May 5 11:29 f
# cd ../content/
# ls -l
total 0
drwx------ 3 nginx nginx 16 May 6 05:28 1
drwx------ 5 nginx nginx 36 May 8 11:39 2
drwx------ 3 nginx nginx 16 May 6 12:12 3
drwx------ 3 nginx nginx 16 May 8 05:58 4
drwx------ 6 nginx nginx 46 May 5 08:03 5
drwx------ 6 nginx nginx 46 May 8 07:31 7
drwx------ 4 nginx nginx 26 May 5 08:03 8
drwx------ 3 nginx nginx 16 May 4 17:21 9
drwx------ 4 nginx nginx 26 May 8 06:04 a
drwx------ 5 nginx nginx 36 May 8 06:30 c
drwx------ 3 nginx nginx 16 May 5 06:21 d
drwx------ 4 nginx nginx 26 May 5 08:03 f
#
When i run using PURGE Method the http response is 404 not found whereas when i run using GET Method the http response is 200 OK
400 Not Found
#curl -vvv -X PURGE -I https://testnginxproxycachepurge.testintcraft.com/apis
* About to connect() to testnginxproxycachepurge.testintcraft.com port 443 (#0)
* Trying 34.105.141.181...
* Connected to testnginxproxycachepurge.testintcraft.com (34.105.141.181) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=testnginxproxycachepurge.testintcraft.com
* start date: Apr 26 11:06:35 2022 GMT
* expire date: Jul 25 11:06:34 2022 GMT
* common name: testnginxproxycachepurge.testintcraft.com
* issuer: CN=R3,O=Let's Encrypt,C=US
> PURGE /apis HTTP/1.1
> User-Agent: curl/7.29.0
> Host: testnginxproxycachepurge.testintcraft.com
> Accept: */*
>
< HTTP/1.1 404 Not Found
HTTP/1.1 404 Not Found
< Server: nginx/1.20.2
Server: nginx/1.20.2
< Date: Sun, 08 May 2022 08:01:55 GMT
Date: Sun, 08 May 2022 08:01:55 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 153
Content-Length: 153
< Connection: keep-alive
Connection: keep-alive
<
* Excess found in a non pipelined read: excess = 153 url = /apis (zero-length body)
* Connection #0 to host testnginxproxycachepurge.testintcraft.com left intact
200 OK
#curl -vvv -X GET -I https://testnginxproxycachepurge.testintcraft.com/apis
* About to connect() to testnginxproxycachepurge.testintcraft.com port 443 (#0)
* Trying 34.105.141.181...
* Connected to testnginxproxycachepurge.testintcraft.com (34.105.141.181) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=testnginxproxycachepurge.testintcraft.com
* start date: Apr 26 11:06:35 2022 GMT
* expire date: Jul 25 11:06:34 2022 GMT
* common name: testnginxproxycachepurge.testintcraft.com
* issuer: CN=R3,O=Let's Encrypt,C=US
> GET /apis HTTP/1.1
> User-Agent: curl/7.29.0
> Host: testnginxproxycachepurge.testintcraft.com
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.20.2
Server: nginx/1.20.2
< Date: Sun, 08 May 2022 08:01:43 GMT
Date: Sun, 08 May 2022 08:01:43 GMT
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive
< Cache-Control: max-age=21600, public
Cache-Control: max-age=21600, public
< Link: <https://testnginxproxycachepurge.testintcraft.com/apis>; rel="canonical"
Link: <https://testnginxproxycachepurge.testintcraft.com/apis>; rel="canonical"
< X-UA-Compatible: IE=edge
X-UA-Compatible: IE=edge
< Content-language: en
Content-language: en
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< Permissions-Policy: interest-cohort=()
Permissions-Policy: interest-cohort=()
< Expires: Sun, 19 Nov 1978 05:00:00 GMT
Expires: Sun, 19 Nov 1978 05:00:00 GMT
< Vary: Cookie
Vary: Cookie
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< Strict-Transport-Security: max-age=31536000; includeSubDomains
Strict-Transport-Security: max-age=31536000; includeSubDomains
< Set-Cookie: ADRUM_BT=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Set-Cookie: ADRUM_BT=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
< Set-Cookie: ADRUM_BT=R%3A53%7Cg%3A5277dd0a-8de6-440a-a8f7-52fb782db251139%7Cn%3Aicebergtest_e1c60ae6-5d00-47d5-8c0a-690d8465795f; expires=Sun, 08-May-2022 05:58:56 GMT; Max-Age=30; path=/
Set-Cookie: ADRUM_BT=R%3A53%7Cg%3A5277dd0a-8de6-440a-a8f7-52fb782db251139%7Cn%3Aicebergtest_e1c60ae6-5d00-47d5-8c0a-690d8465795f; expires=Sun, 08-May-2022 05:58:56 GMT; Max-Age=30; path=/
< Last-Modified: Tue, 26 Apr 2022 14:39:40 GMT
Last-Modified: Tue, 26 Apr 2022 14:39:40 GMT
< ETag: "1650983980"
ETag: "1650983980"
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< X-Cache-Status: HIT
X-Cache-Status: HIT
<
* Excess found in a non pipelined read: excess = 15395 url = /apis (zero-length body)
* Connection #0 to host testnginxproxycachepurge.testintcraft.com left intact
#
Please guide me.
I'm trying to make a https proxy on nginx engine. And when I test it on different sites - I always get two HTTP codes - 302 - redirect to https scheme and 400 after connect
proxy config
server {
error_log /var/log/nginx/nginx.err;
access_log /var/log/nginx/nginx.acc;
resolver 127.0.0.53;
listen 80; #default_server;
listen 443 ssl default_server;
server_name proxy;
ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem;
proxy_ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem;
proxy_ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem;
proxy_ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem;
large_client_header_buffers 1 128k;
proxy_ssl_verify on;
proxy_ssl_session_reuse off;
ssl_verify_client off;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Access-Control-Allow-Origin *;
proxy_buffering on;
proxy_buffers 8 16k;
proxy_buffer_size 16k;
proxy_pass http://$host$request_uri;
proxy_read_timeout 1800;
}
}
curl -x localhost:80 goo.gl -I -L output (goo.gl - for example, but I have this issue for every site)
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 10 Sep 2021 12:32:42 GMT
Content-Type: application/binary
Content-Length: 0
Connection: keep-alive
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Location: https://goo.gl/
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
HTTP/1.1 400 Bad Request
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 10 Sep 2021 12:32:42 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
same curl output with -v
* Trying ::1:80...
* TCP_NODELAY set
* connect to ::1 port 80 failed: Connection refused
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> HEAD http://goo.gl/ HTTP/1.1
> Host: goo.gl
> User-Agent: curl/7.68.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.18.0 (Ubuntu)
Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 10 Sep 2021 12:34:02 GMT
Date: Fri, 10 Sep 2021 12:34:02 GMT
< Content-Type: application/binary
Content-Type: application/binary
< Content-Length: 0
Content-Length: 0
< Connection: keep-alive
Connection: keep-alive
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
Pragma: no-cache
< Expires: Mon, 01 Jan 1990 00:00:00 GMT
Expires: Mon, 01 Jan 1990 00:00:00 GMT
< Location: https://goo.gl/
Location: https://goo.gl/
< X-XSS-Protection: 0
X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'https://goo.gl/'
* Hostname localhost was found in DNS cache
* Trying ::1:80...
* TCP_NODELAY set
* connect to ::1 port 80 failed: Connection refused
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#1)
* allocate connect buffer!
* Establish HTTP proxy tunnel to goo.gl:443
> CONNECT goo.gl:443 HTTP/1.1
> Host: goo.gl:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< Server: nginx/1.18.0 (Ubuntu)
Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 10 Sep 2021 12:34:02 GMT
Date: Fri, 10 Sep 2021 12:34:02 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 166
Content-Length: 166
< Connection: close
Connection: close
<
* Received HTTP code 400 from proxy after CONNECT
* CONNECT phase completed!
* Closing connection 1
curl: (56) Received HTTP code 400 from proxy after CONNECT
If I do curl without a proxy, then it will contain messages with successful TLS handshakes
I am currently running a Grafana server with an NGINX server in front of it to server up from my grafana.olddomain.uk:
location / {
proxy_pass http://127.0.0.1:3000;
}
I would like to proxy from my new domain (https://my.newdomain/grafana) to the old domain but have been hitting problems with the config:
location /grafana {
max_ranges 0;
rewrite ^/grafana/(.*)$ /$1 break;
proxy_pass https://grafana.olddomain.uk/;
proxy_ssl_server_name on;
proxy_ssl_trusted_certificate /etc/nginx/conf.d/trusted_ca_cert.pem;
proxy_set_header Host $host;
}
This is throwing an error cleared being served by Grafana:
If you're seeing this Grafana has failed to load its application files
1. This could be caused by your reverse proxy settings.
2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath
3. If you have a local dev build make sure you build frontend using: yarn start, yarn start:hot, or yarn build
4. Sometimes restarting grafana-server can help
So that seems pretty clear, I am using a sub folder now and need to change grafana.ini but that will break grafana.olddomain.uk.
What do I need in my newdomain location to get this working?
EDIT: curl response (following redirects) from https://my.newdomain.uk/grafana
> GET /grafana HTTP/1.1
> Host: my.newdomain.uk
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Fri, 16 Apr 2021 17:39:13 GMT
< Content-Type: text/html
< Content-Length: 162
< Location: https://my.newdomain.uk/grafana/
< Connection: keep-alive
<
> GET /grafana/ HTTP/1.1
> Host: my.newdomain.uk
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Fri, 16 Apr 2021 17:39:13 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: no-cache
< Expires: -1
< Pragma: no-cache
< X-Frame-Options: deny
<
So after a lot of attempts at getting a sub path working I had to give up and set this up on root. This required splitting all the configurations up into separate sites.
location / {
max_ranges 0;
proxy_pass https://grafana.olddomain.uk/;
proxy_ssl_server_name on;
proxy_ssl_trusted_certificate /etc/nginx/conf.d/trusted_ca_cert.pem;
proxy_set_header Host $host;
}
I'm trying to configure Location directive on my nginx web-server (Ubuntu).
I can have access to:
http://127.0.0.1/app1/
BUT when I'm trying to get access whitout slash in the end like:
http://127.0.0.1/app1
I get an error 301 HTTP1.1/Moved permanently
I have following nginx config:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Looks like everything is OK.
And following default.conf:
server {
listen 80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /app1/ {
root /var/www/html/;
index index.html;
try_files $uri $uri/ /app1/index.html;
}
}
Curl output
http://127.0.0.1/app1/
root#ubuntu-test:/etc/nginx/sites-available# curl 127.0.0.1/app1/ -Iv
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /app1/ HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 20 Feb 2020 09:14:12 GMT
Date: Thu, 20 Feb 2020 09:14:12 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 5
Content-Length: 5
< Last-Modified: Tue, 18 Feb 2020 10:49:53 GMT
Last-Modified: Tue, 18 Feb 2020 10:49:53 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: "5e4bc151-5"
ETag: "5e4bc151-5"
< Accept-Ranges: bytes
Accept-Ranges: bytes
<
* Connection #0 to host 127.0.0.1 left intact
http://127.0.0.1/app1
root#ubuntu-test:/etc/nginx/sites-available# curl 127.0.0.1/app1 -Iv
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /app1 HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 20 Feb 2020 09:19:31 GMT
Date: Thu, 20 Feb 2020 09:19:31 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 194
Content-Length: 194
< Location: http://127.0.0.1/app1/
Location: http://127.0.0.1/app1/
< Connection: keep-alive
Connection: keep-alive
Why does it happen?
Nginx selects the location / block to process the URI /app1 as no other locations are a better match. See how Nginx processes a request.
The $uri/ term of the try_files statement informs Nginx to append a / to any URI that matches a directory. The directory /var/www/html/app1 matches this requirement, so a 301 redirection is generated to append a / to the URI. See this document for details.
In addition, the default behaviour for a URI which ends with a / and points to a directory is to search that directory for a file that matches the index directive. See this document for details.
It is possible to deviate from this default behaviour, but you will need to make a number of changes to your configuration. The location /app1/ needs to lose the trailing / if you want it to match /app1. Your try_files directives need to lose the $uri/ term, if you want to avoid the 301 redirect. You will also lose default index processing, so the index directive will be useless.
I am trying to add a header "X-Body" and set it to the response body of the request in nginx conf.
pid logs/nginx.pid.test;
error_log logs/error.log.test debug;
worker_rlimit_core 500M;
worker_processes 1;
master_process off;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/json;
sendfile on;
keepalive_timeout 65;
variables_hash_max_size 2048;
server {
listen 65311;
server_name test;
access_log logs/test;
location / {
echo "Nginx response";
proxy_pass_request_headers on;
default_type application/json;
echo_read_request_body;
add_header X-Body $request_body;
return 200;
}
}
}
Expecting header X-Body for the following curl request. But couldn't find.
curl -vk "localhost:65311" -d '{"key":"value"}' -H "Content-Type: application/json"
* Rebuilt URL to: localhost:65311/
* Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 65311 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 65311 (#0)
> POST / HTTP/1.1
> Host: localhost:65311
> User-Agent: curl/7.52.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 15
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
< Server: Test
< Date: Wed, 09 Oct 2019 19:28:14 GMT
< Content-Type: application/json
< Content-Length: 0
< Connection: keep-alive
<
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
Also, the nginx is built with echo module. How can I add the posted JSON as response header?
nginx does not add empty headers. $request_body is empty, which is why you don't see it. As per the docs, $request_body is only added in certain conditions, specifically when proxied.
Here's a config that works:
http {
log_format postdata escape=json '"$request_body"';
server {
listen 65311;
server_name test;
location /success {
return 200;
}
location / {
proxy_redirect off;
proxy_pass_request_body on;
proxy_pass $scheme://127.0.0.1:$server_port/success;
add_header X-Body $request_body;
access_log logs/test.log postdata;
}
}
}