Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Root-less+FreeBSD+Nginx as proxy #147

Closed
nazriel opened this issue Jan 4, 2013 · 13 comments
Closed

Root-less+FreeBSD+Nginx as proxy #147

nazriel opened this issue Jan 4, 2013 · 13 comments

Comments

@nazriel
Copy link
Contributor

nazriel commented Jan 4, 2013

Greetings.

I am trying to use Vibe.d on shared hosting. I haven't got root access but I am allowed to listen on ie port 2500. I managed to install it with few changes in build-freebsd.sh

The server with vibe.d on it is running FreeBSD 9.1 64bits.

Then, nginx listening on other machine forwards request from http://up.dzfl.pl to http://mdweb.mydevil.net:2500/

While accessing site directly http://mdweb.mydevil.net:2500/ everything works fine, but when trying to access it from http://up.dzfl.pl errors pop-ups.

Browser pop-ups following message:

Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.

Vibe.d spits following message:

[800927F08:80092BE88 ERR] Error after page has been written: object.Exception@/home/nazriel/vibe.d/source/vibe/core/drivers/libevent2_tcp.d(272): Remote hung up while operating on TCPConnection.
----------------
0x548863 <bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+107> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5d7826 <void vibe.core.drivers.libevent2_tcp.Libevent2TcpConnection.checkConnected()+178> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5d7533 <void vibe.core.drivers.libevent2_tcp.Libevent2TcpConnection.write(const(ubyte[]), bool)+107> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x601ec6 <void vibe.core.stream.OutputStream.write(const(char[]), bool)+110> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5eadc8 <void vibe.http.server.HttpServerResponse.writeHeader()+432> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5ea394 <@property vibe.core.stream.OutputStream vibe.http.server.HttpServerResponse.bodyWriter()+624> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x53b060 <void app.handleRequest(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)+72> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x559c8c <void std.functional.DelegateFaker!(void function(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)*).DelegateFaker.doIt(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)+104> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5edc66 <bool vibe.http.server.handleRequest(vibe.core.stream.Stream, immutable(char)[], vibe.http.server.HTTPServerListener, ref vibe.http.server.HttpServerSettings)+5742> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5ec535 <void vibe.http.server.handleHttpConnection(vibe.core.net.TcpConnection, vibe.http.server.HTTPServerListener)+501> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5e961e <void vibe.http.server.listenHttpPlain(vibe.http.server.HttpServerSettings, void delegate(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)).void doListen(vibe.http.server.HttpServerSettings, vibe.http.server.HTTPServerListener, immutable(char)[]).void __lambda33(vibe.core.net.TcpConnection)+54> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5d8034 <extern (C) nothrow void vibe.core.drivers.libevent2_tcp.onConnect(int, short, void*).void ClientTask.execute()+680> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x6086f2 <void vibe.core.core.CoreTask.run()+126> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x64583e <void core.thread.Fiber.run()+42> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x64574e <fiber_entryPoint+98> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x0 <???+0> at ???
[800927F08:80092BE88 WRN] Handling of connection failed: Operating on closed TCPConnection.

Full vibe.d output:

[nazriel@mdweb0]:<~/vibe.d/examples/http_info>$ vibe
Checking dependencies in '/usr/home/nazriel/vibe.d/examples/http_info'
Compiling diet template 'info.dt'...
Warning: using render!() or parseDietFile!() with aliases is unsafe,
         please consider using renderCompat!()/parseDietFileCompat!()
         until DMD is fully stable regarding local alias template arguments.
Compiling diet template 'info.dt'...
Warning: using render!() or parseDietFile!() with aliases is unsafe,
         please consider using renderCompat!()/parseDietFileCompat!()
         until DMD is fully stable regarding local alias template arguments.
[800927F08:00000000 INF] Listening for HTTP requests on 0.0.0.0:2500
[800927F08:00000000 INF] Listening for HTTP requests on :::2500
[800927F08:00000000 INF] Running event loop...
[800927F08:80092BE88 ERR] Error after page has been written: object.Exception@/home/nazriel/vibe.d/source/vibe/core/drivers/libevent2_tcp.d(272): Remote hung up while operating on TCPConnection.
----------------
0x548863 <bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+107> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5d7826 <void vibe.core.drivers.libevent2_tcp.Libevent2TcpConnection.checkConnected()+178> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5d7533 <void vibe.core.drivers.libevent2_tcp.Libevent2TcpConnection.write(const(ubyte[]), bool)+107> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x601ec6 <void vibe.core.stream.OutputStream.write(const(char[]), bool)+110> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5eadc8 <void vibe.http.server.HttpServerResponse.writeHeader()+432> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5ea394 <@property vibe.core.stream.OutputStream vibe.http.server.HttpServerResponse.bodyWriter()+624> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x53b060 <void app.handleRequest(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)+72> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x559c8c <void std.functional.DelegateFaker!(void function(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)*).DelegateFaker.doIt(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)+104> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5edc66 <bool vibe.http.server.handleRequest(vibe.core.stream.Stream, immutable(char)[], vibe.http.server.HTTPServerListener, ref vibe.http.server.HttpServerSettings)+5742> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5ec535 <void vibe.http.server.handleHttpConnection(vibe.core.net.TcpConnection, vibe.http.server.HTTPServerListener)+501> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5e961e <void vibe.http.server.listenHttpPlain(vibe.http.server.HttpServerSettings, void delegate(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)).void doListen(vibe.http.server.HttpServerSettings, vibe.http.server.HTTPServerListener, immutable(char)[]).void __lambda33(vibe.core.net.TcpConnection)+54> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x5d8034 <extern (C) nothrow void vibe.core.drivers.libevent2_tcp.onConnect(int, short, void*).void ClientTask.execute()+680> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x6086f2 <void vibe.core.core.CoreTask.run()+126> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x64583e <void core.thread.Fiber.run()+42> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x64574e <fiber_entryPoint+98> at /tmp/.rdmd-11127/rdmd-app.d-710FE1DA4B6377961FD7A5354EC3AFD3/app
0x0 <???+0> at ???
[800927F08:80092BE88 WRN] Handling of connection failed: Operating on closed TCPConnection.

I can't provide Nginx configs as for now (I will pm admins of server so maybe I can provide them later).

Although simple HttpServer either in Python (python -m SimpleHTTPServer 2500 ) or Java (quick implementation) works fine.

I am using DMD Head from Github and Vibed Head from Github

Best regards
Damian Ziemba

@nazriel
Copy link
Contributor Author

nazriel commented Jan 4, 2013

I can also confirm that problem ALSO occurs on local computer running Arch Linux x64_86

Both when running vibe or sudo vibe

Nginx config for proxy:

server 
{
    listen       80;
    server_name  test.d-programming.com;
    root         /home/naz/www/test.d-programming-language.org/public_html/;

    access_log   /home/naz/www/test.d-programming-language.org/log/access.log main;
    error_log    /home/naz/www/test.d-programming-language.org/log/error.log  warn;
    # Process PHP files with fastcgi
    index   index.php;

location / {
  proxy_pass        http://127.0.0.1:2500;
  proxy_set_header  X-Real-IP  $remote_addr;
}

    location ~ \.php$ 
    {
        if ( !-f $request_filename ) 
        {
            return 404;
        }

        include /etc/nginx/fastcgi.conf;
        fastcgi_pass   unix:/var/run/php-fpm/naz.test.d-programming-com;
        fastcgi_index  index.php;
    }
}

Same errors as in first bug report.

Are there any special headers required in order to make vibed working?

@nazriel
Copy link
Contributor Author

nazriel commented Jan 4, 2013

Ok I figured out what is causing the problem.

Adding proxy_set_header Content-Length $body_bytes_sent; in Nginx config file solves problem.
I will leave issue as open for now because maybe there is a way to allow Vibe.d running without it?

PS
Also other drivers like Libev are not working.

[raz@d4 uploader]$ vibe
/usr/share/vibed/bin/../source/vibe/core/drivers/libev.d(114): Error: function vibe.core.drivers.libev.LibevDriver.listenTcp of type TcpListener(ushort port, void delegate(TcpConnection stream) conn_callback, string bind_address) overrides but is not covariant with vibe.core.driver.EventDriver.listenTcp of type TcpListener(ushort port, void delegate(TcpConnection stream) conn_callback, string bind_address)
Failed: 'dmd' '-g' '-w' '-version=VibeLibevDriver' '-property' '-I/usr/share/vibed/bin/../source' '-L-levent_pthreads' '-L-levent' '-L-lssl' '-L-lcrypto' '-Jviews' '-Isource' '-v' '-o-' '/tmp/vpm.d' '-I/tmp'

I will open another issue a bit later today

@s-ludwig
Copy link
Member

s-ludwig commented Jan 4, 2013

I forgot to investigate the "Content-Length" problem (James Miller already stumbled over it in the past before posting the first working configuration on the D newsgroup). It's good to have a ticket for this - it'll look into it as soon as there is some time.

Regarding the libev driver - it was more or less just a test to see if it performs better than the libevent driver. However, although according to various benchmarks that should be the case, I never could get it up to speed and probably used in in the wrong way... That's why it has been rotting there unmaintained for some time. It shouldn't take too much to get it working, though - I'll look into it.

@s-ludwig
Copy link
Member

s-ludwig commented Jan 4, 2013

Forgot to mention that I've added a configuration to the wiki: https://github.com/rejectedsoftware/vibe.d/wiki/Setting-up-Nginx-as-a-reverse-proxy

s-ludwig added a commit that referenced this issue Jan 4, 2013
…See issue #147.

The HTTP server erroneously assumed that a body is following a request with "Connection: close", even in the absence of "Content-Length" or "Transfer-Encoding". While this can be true for HTTP 1.0 clients, the HTTP 1.1 standard explicitly requires one of these headers to indicate a body.
@nazriel
Copy link
Contributor Author

nazriel commented Jan 5, 2013

Ach that is ok then (regarding backends).

@s-ludwig is it possible to run this setup, nginx + vibe without modyfing (adding content-lenght or proxy_set_body) Nginx config files? I mean here mostly rootless scenarios.

It would be cool if it was possible to run Vibe in environments without root access like you do with PHP, Ruby etc.
It is fine in my case because administrators of shell server I use are very open minded but in others cases it may not be as easy.

Also I wonder if it would be possible to make install script less root-oriented or add set of install files without a need of root access. Or atleast make wiki entry about installing Vibe without root access.

Thank you very much for all this work. Vibe is really great, high quality product.

I am happy user of it on rootless FreeBSD now ;)

@s-ludwig
Copy link
Member

s-ludwig commented Jan 5, 2013

Regarding non-root installation, there is basically nothing to do. Just clone/unzip and call /path/to/vibe.d/bin/vibe directly or add it to the user's PATH. But it's only mentioned on the github project page, so I'll also state that in the general documentation and in the FreeBSD section. Hm... wiki page for installation instructions is probably an even better idea...

bc2e0f3 should have made both configuration options, the content-length header and the proxy_set_body, superfluous now. But I have tested it only briefly with a simple GET request.

@nazriel
Copy link
Contributor Author

nazriel commented Jan 5, 2013

@s-ludwig yea I noticed your commit with fix, but I was not sure that's why I asked.

Still seems to not work properly.

504 Gateway Time-out

nginx/1.2.4
[raz@d4 uploader]$ vibe
Checking dependencies in '/usr/share/vibed/examples/uploader'
Compiling diet template 'upload_form.dt' (compat)...
Compiling diet template 'upload_form.dt' (compat)...
[7F581E55B058:00000000 INF] Listening for HTTP requests on 0.0.0.0:8080
[7F581E55B058:00000000 WRN] Failed to listen on :::8080
[7F581E55B058:00000000 INF] Running event loop...
[7F581E55B058:7F581E5671D8 ERR] Error after page has been written: object.Exception@/usr/share/vibed/source/vibe/core/drivers/libevent2_tcp.d(272): Remote hung up while operating on TCPConnection.
----------------
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(pure @safe bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+0x61) [0x53c6e1]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.core.drivers.libevent2_tcp.Libevent2TcpConnection.checkConnected()+0xb2) [0x5c5596]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.core.drivers.libevent2_tcp.Libevent2TcpConnection.write(const(ubyte[]), bool)+0x6b) [0x5c52af]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.core.stream.OutputStream.write(const(char[]), bool)+0x6e) [0x56a41a]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.http.server.HttpServerResponse.writeHeader()+0x1a0) [0x5ef84c]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(@property vibe.core.stream.OutputStream vibe.http.server.HttpServerResponse.bodyWriter()+0x26d) [0x5eee39]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.http.server.HttpServerResponse.renderCompat!("upload_form.dt", vibe.http.server.HttpServerRequest, "req").renderCompat(, ...)+0x130) [0x5f3308]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(@property void delegate(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse) vibe.http.server.staticTemplate!("upload_form.dt").staticTemplate().void __lambda48(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)+0x71) [0x53c88d]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.http.router.UrlRouter.handleRequest(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)+0x165) [0x5c7b3d]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(bool vibe.http.server.handleRequest(vibe.core.stream.Stream, immutable(char)[], vibe.http.server.HTTPServerListener, ref vibe.http.server.HttpServerSettings)+0x1338) [0x5f2348]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.http.server.handleHttpConnection(vibe.core.net.TcpConnection, vibe.http.server.HTTPServerListener)+0x1f1) [0x5f0f4d]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.http.server.listenHttpPlain(vibe.http.server.HttpServerSettings, void delegate(vibe.http.server.HttpServerRequest, vibe.http.server.HttpServerResponse)).void doListen(vibe.http.server.HttpServerSettings, vibe.http.server.HTTPServerListener, immutable(char)[]).void __lambda47(vibe.core.net.TcpConnection)+0x36) [0x5ee0d2]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(extern (C) nothrow void vibe.core.drivers.libevent2_tcp.onConnect(int, short, void*).void ClientTask.execute()+0x2a5) [0x5c5da5]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void vibe.core.core.CoreTask.run()+0x7e) [0x5d36ae]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(void core.thread.Fiber.run()+0x2a) [0x64affe]
/tmp/.rdmd-1000/rdmd-app.d-A3EB7CF7CACED0BCEED9BAECF01AADFA/app(fiber_entryPoint+0x61) [0x64af11]
[(nil)]
[7F581E55B058:7F581E5671D8 WRN] Handling of connection failed: Operating on closed TCPConnection.
[7F581E55B058:7F581E5671D8 WRN] Handling of connection failed: Remote hung up while operating on TCPConnection.

From Git head.

@s-ludwig
Copy link
Member

s-ludwig commented Jan 5, 2013

Can you run the app using vibe -- -vverbose and see what the last log messages are before it hangs (i.e. not the errors that occur after the connection timeout but the lines before that)?

Fir me it works on nginx 1.1.19 and the upload example using these settings:

location / {
        proxy_pass http://localhost:8080;
        proxy_redirect off;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
}

@nazriel
Copy link
Contributor Author

nazriel commented Jan 5, 2013

Ach indeed it works!

Adding proxy_http_version 1.1; fixed things.

@nazriel
Copy link
Contributor Author

nazriel commented Jan 5, 2013

@s-ludwig I had very unfriendly nginx conf here at localhost hehe

server 
{
    listen       80;
    server_name  test.d-programming.com;


    location / 
    {
      proxy_pass        http://127.0.0.1:8080;
      proxy_set_header  X-Real-IP  $remote_addr;

    }

}

Not sure what configs were running on my shell tho (can't test it anymore because Administrators added Content-length header to config)

I guess I can close the issue now right?

@s-ludwig
Copy link
Member

s-ludwig commented Jan 5, 2013

Lets keep it still open for a while - lets me remember the backend thing, but above all I need to investigate if that HTTP 1.0 exception which still causes the hang now without the 1.1 is really necessary. (1.1 is necessary either way, though, because some parts rely on the ability to send using chunked encoding)

@nazriel
Copy link
Contributor Author

nazriel commented Jan 5, 2013

Alrighty!

Thanks alot.
Vibe.d rox ;)

s-ludwig added a commit that referenced this issue Jan 8, 2013
…request body.

This was causing non-conformant behavior infavor of broken clients. See issue #147.
@s-ludwig
Copy link
Member

s-ludwig commented Jan 8, 2013

Okay, I'll close this for now. HTTP/1.0 exception is removed now and the libev driver compiles again. I'll put a TODO item for making it actually work again, but that'll have to wait a bit more.

@s-ludwig s-ludwig closed this as completed Jan 8, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants