Opened 13 years ago
Closed 13 years ago
#325 closed defect (fixed)
websocket doesn't work when using unix socket for proxy_pass
| Reported by: | Avétis Kazarian | Owned by: | Maxim Dounin |
|---|---|---|---|
| Priority: | minor | Milestone: | 1.3 |
| Component: | nginx-core | Version: | 1.3.x |
| Keywords: | Cc: | ||
| uname -a: | Darwin mahaprabhu.local 12.3.0 Darwin Kernel Version 12.3.0: Sun Jan 6 22:37:10 PST 2013; root:xnu-2050.22.13~1/RELEASE_X86_64 x86_64 i386 MacBookPro10,1 Darwin | ||
| nginx -V: |
nginx version: nginx/1.3.14
TLS SNI support enabled configure arguments: --prefix=/usr/local/Cellar/nginx/1.3.14 --with-http_ssl_module --with-pcre --with-ipv6 --with-cc-opt=-I/usr/local/include --with-ld-opt=-L/usr/local/lib --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp |
||
Description
I don't know if it's something to be excepted or if it's really a bug.
My conf (in a server {}):
location ~ /socket {
proxy_pass http://unix:/tmp/app.socket;
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "upgrade";
}
error.log:
2013/03/26 15:25:11 [alert] 21581#0: *3457 setsockopt(TCP_NODELAY) failed (102: Operation not supported on socket) while proxying upgraded connection, client: 127.0.0.1, server: localhost, request: "GET /socket/230/5o96b2yn/websocket HTTP/1.1", upstream: "http://unix:/tmp/app.socket:/socket/230/5o96b2yn/websocket", host: "localhost"
It works perfectly fine if I replace proxy_pass http://unix:/tmp/app.socket; with proxy_pass http://127.0.0.1:9000; (and make accordingly the change on my socket server to listen on port 9000).
Change History (3)
comment:1 by , 13 years ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:3 by , 13 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Fix committed, thanks for your report.
Note:
See TracTickets
for help on using tickets.

The following patch should fix this:
# HG changeset patch # User Maxim Dounin <mdounin@mdounin.ru> # Date 1364312044 -14400 # Node ID 51a7e8aaeb1d9792971c6d0d2d7062829ea15356 # Parent 8202d09ccee90004ce748a34f972c7a3e15ab49c Upstream: fixed tcp_nodelay use (ticket #325). diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2413,32 +2413,39 @@ ngx_http_upstream_upgrade(ngx_http_reque r->read_event_handler = ngx_http_upstream_upgraded_read_downstream; r->write_event_handler = ngx_http_upstream_upgraded_write_downstream; - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - + if (clcf->tcp_nodelay) { tcp_nodelay = 1; - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, 0); - return; + if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; } - c->tcp_nodelay = NGX_TCP_NODELAY_SET; - - if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(u->peer.connection, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, 0); - return; + if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0, + "tcp_nodelay"); + + if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(u->peer.connection, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET; } - - u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET; } if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {(Just in case if it's not clear, an obvious workaround would be switch off tcp_nodelay directive.)