[lighttpd + fastcgi] krijg geen contact met fcgi server

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05 20:45
Ik ben bezig met een python scripts die hun output via fastcgi aan lighttpd door geven. Tot nu toe heel simpel:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python
import os, time
from flup.server.fcgi import WSGIServer

SocketAddress = "/tmp/fcgi.sock"

def myapp(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['Hello World! It is %s\n' % time.strftime("%X")]

Server = WSGIServer(application = myapp, bindAddress = SocketAddress, umask=011)
Server.run()

Dit is een wsgi script maar waar het om gaat is dat de regel "Hello World! It is <tijd-om-naar-bed-te-gaan>" door de socket naar de webserver wordt gestuurd.
Als ik dit programma met de hand start en vanuit mijn browser dit script aan roep, krijg ik netjes de verwachte output. Maar als ik lighttpd het script laat starten krijg ik geen reactie van de webserver. Maar ook geen foutmelding: de verbinding wordt blijkbaar gelegd, maar er wordt niets teruggestuurd door de server.

Mijn fastcgi configuratie is:
code:
1
2
3
4
5
6
7
fastcgi.server = ( ".py" =>
        ((
                "bin-path" => "/home/www/cgi-bin/hello.py",
                "socket" => "/tmp/fcgi.sock",
                "max-proc" => 1,
        ))
)


Als ik een commentaar voor de bin-path regel zet en het fcgi script met de hand start gaat het dus wel goed. Lighttpd start wel hello.py. Hij start er zelfs vier en er worden 5 sockets gemaakt in /tmp:
code:
1
2
3
4
5
6
7
8
9
10
ebox:/home/www/cgi-bin# ps ax | grep hello
21204 ?        Sl     0:00 /usr/bin/python /home/www/cgi-bin/hello.py
21205 ?        Sl     0:00 /usr/bin/python /home/www/cgi-bin/hello.py
21206 ?        Sl     0:00 /usr/bin/python /home/www/cgi-bin/hello.py
21207 ?        Sl     0:00 /usr/bin/python /home/www/cgi-bin/hello.py
srwxrw-rw- 1 www-data www-data 0 2010-11-10 00:30 /tmp/fcgi.sock
srwxr-xr-x 1 www-data www-data 0 2010-11-10 00:30 /tmp/fcgi.sock-0
srwxr-xr-x 1 www-data www-data 0 2010-11-10 00:30 /tmp/fcgi.sock-1
srwxr-xr-x 1 www-data www-data 0 2010-11-10 00:30 /tmp/fcgi.sock-2
srwxr-xr-x 1 www-data www-data 0 2010-11-10 00:30 /tmp/fcgi.sock-3

Ik heb max-proc 1 gemaakt! Waarom krijgt mijn browser de output van het script niet te zien?

In de error.log van lighttpd komt niets te staan, maar access.log geeft een kleine aanwijzing:
Als hello.py standalone draait :

192.168.0.5 192.168.0.1 - [10/Nov/2010:08:12:11 +0100] "GET /cgi-bin/hello.py HTTP/1.1" 200 28 "http://192.168.0.1/cgi-bin/" "Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10"

En als hello.py door lighttpd wordt gestart:

192.168.0.5 192.168.0.1 - [10/Nov/2010:08:08:55 +0100] "GET /cgi-bin/ HTTP/1.1" 200 2183 "-" "Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10"

Hoe moet ik dit interpreteren?

[ Voor 16% gewijzigd door Sir Isaac op 10-11-2010 08:09 ]


Acties:
  • 0 Henk 'm!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 01-10 15:44
Sir Isaac schreef op woensdag 10 november 2010 @ 00:22:

...

En als hello.py door lighttpd wordt gestart:

192.168.0.5 192.168.0.1 - [10/Nov/2010:08:08:55 +0100] "GET /cgi-bin/ HTTP/1.1" 200 2183 "-" "Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10"

Hoe moet ik dit interpreteren?
Volgens de logging van ligttpd doe je een GET op "/cgi-bin/" in plaats van "/cgi-bin/hello.py", gebruik je wel de juiste URL?

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic


Acties:
  • 0 Henk 'm!

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05 20:45
Dat verschil had ik inderdaad gezien. Ik had de laaste regel in de access.log toegeschreven aan de GET /cgi-bin/hello.py. Maar voor de GET hello.py vraag ik inderdaad de cgi-bin directory op en daar slaat deze regel op. Bij het opvragen van hello.py komt er geen regel bij! Ook met de live-httpd headers extentie van firefox kan ik niet zien wat er gebeurt. Die wacht blijkbaar ook op de server response voordat hij de request weergeeft. Vreemd.

Acties:
  • 0 Henk 'm!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 01-10 15:44
Volgens mij moet je in elk geval nog "check-local" uitzetten in de lighttpd configuratie. Verder is het handig om te weten dat stderr van een fastcgi script niet afgevangen wordt in lighttpd, dat maakt het best lastig om fouten te zoeken, daarom is het verstandig om stderr om te sluizen naar een log bestand.
Wel kun je in elk geval nog fastcgi.debug aanzetten, dan heb je iets meer logging in error.log (of access.log, maar ik meen dat het naar error.log gaat).

Heb je het al via telnet geprobeerd? dus
code:
1
2
telnet 192.168.0.1   80
GET /cgi-bin/hello.py

(Na de "GET /cgi-bin/hello.py" moet je twee keer op <Enter> drukken, maar dit wordt weggehaald door de GoT parser)

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic


Acties:
  • 0 Henk 'm!

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05 20:45
fastcgi.debug = 1 levert weinig extra's op: alleen deze melding:
code:
1
2010-11-10 14:33:48: (mod_fastcgi.c.2979) got proc: pid: 23236 socket: unix:/tmp/fcgi.sock-0 load: 5

Hij geeft blijkbaar wel een request door aan de fcgi server.
Handmatig uitvoeren via telnet levert een "400 Bad Request" response op, maar dat gebeurt ook als ik een willekeurige andere file opvraag. Is het openen van een verbinding op port 80 voldoende om een http sessie te initieren?

Het aantal processen dat door lighttpd wordt gestart is nu wel correct: dat was een typo in de config file.

[ Voor 10% gewijzigd door Sir Isaac op 10-11-2010 15:46 ]


Acties:
  • 0 Henk 'm!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 01-10 15:44
Volgens mij moet je met deze toevoeging stderr kunnen redirecten:
Python:
1
2
3
import sys
sys.stderr = open('/tmp/hello.log', 'a')
...

Kijk eens wat daar mis gaat. Verder kun je de logging module van python gebruiken om wat meer boven water te krijgen. Ik heb destijds ook wat moeite gehad om flup fastcgi werkend te krijgen, ik denk dat ik thuis nog wel een VM heb waar ik de uiteindelijke instellingen nog terug kan vinden.

.edit:

Ik bedenk net dat ik de host regel ben vergeten bij telnet, moet zijn:
code:
1
2
3
telnet 192.168.0.1
GET /cgi-bin/hello.py
host: 192.168.0.1

[ Voor 16% gewijzigd door Elijan9 op 10-11-2010 17:11 ]

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic


Acties:
  • 0 Henk 'm!

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05 20:45
In de stderr van mijn applicatie komt niets te staan. Ik bedenk net dat mij applicatie op de voorgrond blijft hangen in de mainloop totdat hij wordt afgesloten. Kan het niet zo zijn dat lighttpd verwacht dat de fcgi afpplicatie als daemon gaat draaien? Ik zal hem een forken en vervolgens de parent afsluiten.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:26
Ten eerste: de optie om het aantal processen in te stellen heet "max-procs", niet "max-proc", dus vandaar dat je nog steeds vier processen krijgt.

Ten tweede: een FastCGI server moet juist niet daemonizen. De webserver gaat er namelijk vanuit dat als dat proces exit hij 'm opnieuw moet starten. Forken met de file descriptors die je van de webserver gekregen hebt kan alleen maar voor problemen zorgen.

Ten derde: check-local moet je waarschijnlijk op disabled zetten, tenzij je script ook daadwerkelijk te vinden is op de locatie waar 'ie wordt aangeroepen (zelf plaats ik cgi applicaties meestal buiten de webroot).

Ten vierde, en dit is waarschijnlijk het probleem: je moet het socket path niet hardcoden in je script. Zo werkt FastCGI niet. De webserver maakt een pipe of een socket of een fifo of een ander soort file aan, en geeft het CGI proces daar toegang toe door middel van een open file descriptor. Dus: haal regel 5 en de twee extra parameters op regel 11 weg, en probeer het nog eens.

Acties:
  • 0 Henk 'm!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 01-10 15:44
Soultaker schreef op vrijdag 12 november 2010 @ 19:03:
...

Ten tweede: een FastCGI server moet juist niet daemonizen.

..

Ten vierde, en dit is waarschijnlijk het probleem: je moet het socket path niet hardcoden in je script.
Tweede en vierde argument kloppen niet helemaal, je kunt wel degelijk een fastcgi server daemonizen, mits je het socket path hardcoded in je script hebt staan (en check-local uit staat (oftewel op disabled)). Dit moet je zelfs doen als je het fastcgi script onder een andere user id wilt draaien.

Als je het echter op die manier wilt aanpakken (maar ik ging er niet vanuit dat dit hier geprobeerd werd) dan moeten ook een aantal environment variabelen goed gezet worden voor flup, misschien moet je daar eens naar zoeken...

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:26
Laat de TS eerst maar eens uitproberen of het werkt, dan praten we verder. ;) De standaardsituatie is in ieder geval zonder daemonization en zonder expliciet een socket path te hardcoden. Je hebt wel gelijk dat er in principe een heleboel verschillende manieren zijn om FastCGI te configureren.

Zoals je ook ziet in de TS maakt het script /tmp/fcgi.sock aan, nadat Lighttpd al /tmp/fcgi.sock-[0123] heeft gemaakt, dus ik ben er 90% zeker van dat het probleem is dat FastCGI verwacht dat het script niet z'n eigen socket aanmaakt, wat nu wel gebeurt, maar in plaats daarvan via de file descriptor communiceert.

edit:
Trouwens, nu we toch aan het muggenziften zijn:
Elijan9 schreef op woensdag 10 november 2010 @ 15:46:
code:
1
2
3
telnet 192.168.0.1
GET /cgi-bin/hello.py
host: 192.168.0.1
Dit is geen geldige HTTP request. Voor HTTP 1.0 is het specificeren van het versienummer verplicht:
code:
1
2
GET /pad HTTP/1.0
Host: bla

Overigens is de Host-header niet verplicht bij HTTP/1.0 maar meestal wel nodig als de webserver voor virtual hosting geconfigureerd is.

[ Voor 47% gewijzigd door Soultaker op 12-11-2010 22:28 ]


Acties:
  • 0 Henk 'm!

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05 20:45
Ha bedankt, dat zijn een paar mooie reply's.
Die max-procs had ik al gefixed.
Ik heb de locatie van de socket nu uit de code van mijn script gehaald en nu werkt het! Waarom ik geen foutmelding op kreeg snap ik niet. Ik neem aan dat zowel lighttpd als mijn script de socket rw openen. Dat zou toch een foutmelding moeten geven.

Voor me zelf en voor anderen in de toekomst. Er zijn dus twee manieren om een fcgi applicatie te draaien.
1) Je start de fcgi applicatie zelf. Je kunt er dan een daemon van maken en hem herstarten wanneer je wil. De applicatie kan dan ook op een andere server draaien. Voorwaarde is dat de locatie van de socket in zowel de configuratie van de webserver als van de applicatie staat. Dat is in dit geval het enige dat ze van elkaar weten.
2) Je laat de fcgi applicatie door de webserver starten. Het mag dan geen daemon zijn, en de locatie van de socket wordt door de webserver aan de fcgi applicatie doorgegeven (hoe?). Dit is de makkelijkste methode maar is minder flexibel en werkt ook alleen met een lokale applicatie.

In eerste instantie had ik methode 1 werkend, nu methode 2. Bedankt Soultaker en Elijan.
Pagina: 1