pursultani / haproxy-error-page

A Lua script for handling HTTP error pages in HAProxy
Other
5 stars 3 forks source link

Lua function 'error-page': runtime error #2

Open guimouraumbler opened 5 years ago

guimouraumbler commented 5 years ago

Hello my friend!

I'm trying to run this project, but i always got the error (when it's match the error code):

proxy_1 | 00000005:http.clireq[0008:ffffffff]: GET /test HTTP/1.1 proxy_1 | 00000005:http.clihdr[0008:ffffffff]: Host: localhost:8080 proxy_1 | 00000005:http.clihdr[0008:ffffffff]: User-Agent: curl/7.61.1 proxy_1 | 00000005:http.clihdr[0008:ffffffff]: Accept: / proxy_1 | [debug] 008/110813 (11) : lua.error-page: rewrite error page: 404 proxy_1 | [ALERT] 008/110813 (11) : Lua function 'error-page': runtime error: 0 from [C] method 'set', /usr/local/etc/haproxy/scripts/error-page.lua:101 C function line 96. proxy_1 | 00000005:web.srvrep[0008:adfd]: HTTP/1.1 404 Not Found proxy_1 | 00000005:web.srvhdr[0008:adfd]: Server: nginx/1.15.8 proxy_1 | 00000005:web.srvhdr[0008:adfd]: Date: Wed, 09 Jan 2019 11:08:13 GMT proxy_1 | 00000005:web.srvhdr[0008:adfd]: Content-Type: text/html proxy_1 | 00000005:web.srvhdr[0008:adfd]: Content-Length: 153 proxy_1 | 00000005:web.srvhdr[0008:adfd]: Connection: close

Can you help me? Thanks.

guimouraumbler commented 5 years ago

The error also happens following the steps for the docker test.

guimouraumbler commented 5 years ago

I've found an "error". The script "works" on haproxy version 1.6. We use here versions 1.8, 1.9 (because we need to use http v2 and this is only available on these versions).

In version 1.6, I still have some trouble, when I access the page, sometimes come to an error and on logs appears:

runtime error: /etc/haproxy-persistent/error-page.lua:103: 'close' needs 1 arguments.

What can I do about this? And is there any possibility to use this script on version 1.9?

OBS: The error I commented that occurs in docker, occurs because the image downloads the latest version of haproxy (haproxy: alphine)

Thanks.

danielvieiravega commented 5 years ago

Hi! I'm having a similar issue. I'm using the labs.play-with-docker.com to test your script. I start the environment using docker-compose up, then I run the curl -v localhost:8080 and it works properly returning a 200 status code. BUT when a I run curl -v localhost:8080/blabla it returns the expected 404 status code, but the following error is displayed on the screen:

$ curl -v localhost:8080/dfa proxy_1 | [debug] 017/160329 (10) : lua.error-page: rewrite error page: 404 proxy_1 | [ALERT] 017/160329 (10) : Lua function 'error-page': runtime error: 0 from [C] method 'set', /usr/local/etc/haproxy/scripts/error-page.lua:101 C function line 96. image

Can you help to solve this problem?

Thanks.

pursultani commented 5 years ago

@guimouraumbler @danielvieiravega looking at the log output my first suspicion is the API changes in newer versions of HAProxy.

marceldegraaf commented 5 years ago

It took me a good part of today to figure this out, but I've found out why this breaks in HAProxy 1.9+. Hidden in the HAProxy changelog I found this line:

MAJOR: lua: Forbid calls to Channel functions for LUA scripts in HTTP proxies

This is the commit that change relates to. The smoking gun is in the commit message:

Functions from then (sic) Channel class are now forbidden for LUA scripts called from HTTP proxies [...] following functions are concerned: Channel.get, Channel.dup, Channel.getline, Channel.set, Channel.append, Channel.send, Channel.forward

This means that for frontends using mode http the Lua script will never be able to call the res.set and res.send functions.

@pursultani do you know if there is a way to make this script work on HAProxy 1.9+ in mode tcp?

pursultani commented 5 years ago

Nice catch @marceldegraaf! It seems to me that unfortunately there's no way around it. mode tcp won't work since it requires not only the status operator for the ACL but also the HTTP status from TXN fetch class to lookup the right error page.

One disgraceful way to do it in to pass every response through the script (in TCP mode) parse it, and act accordingly. But since it's defeats the purpose of being HA it seems to be pointless.