premature end of script headers
Martina
- perl
Hallo Leute!
Ich beziehe mich auf folgendes Thema:
http://forum.de.selfhtml.org/?t=77385&m=446621
Jetzt habe ich aber ein Problem....
Ich rufe das Perlscript auf und es funktioniert auch, dass es im Hintergrund alles erledigt....
Nur am Bildschirm bekomme ich einen "Internal Server Error" und in meiner Error_log-File steht "premature end of script headers"....
Was ist faul.....
Gruss,
M.
Hi,
"premature end of script headers"....
Was ist faul.....
Dein Script gibt kein gültiges Set an HTTP-Headern zurück, die im CGI- (und damit HTTP-)Kontext zwingend benötigt werden.
Cheatah
Warum nicht???
Weil es im Hintergrund gestartet wird oder was?
Wie ist das zu lösen....
Gruss und Danke,
M.
Hi,
Warum nicht???
weil Du die Ausgabe derselben vergessen hast.
Weil es im Hintergrund gestartet wird oder was?
Es wird über HTTP gestartet, nicht im Hintergrund.
Wie ist das zu lösen....
Sorge für die Ausgabe eines gültigen Satzes von HTTP-Headern.
Cheatah
Könntest du mir ein Beispielcode schreiben....
Also im Hintergrund läuft das Script aber schon, da die Aktionen, welches es machen soll stattfinden...
Gruss,
M.
Hi,
Könntest du mir ein Beispielcode schreiben....
Beispiel == Lösung, Lösung => hier nicht.
Also im Hintergrund läuft das Script aber schon, da die Aktionen, welches es machen soll stattfinden...
Es wird per HTTP aufgerufen. Das ist *nicht* im Hintergrund.
Cheatah
Was soll jetzt diese Geheimnistuerei
Hi,
Was soll jetzt diese Geheimnistuerei
selber denken macht schlau.
Cheatah
Ich weiß ja noch nicht mal von was du redest...aber gut...behalt es für dich wenn es dich glücklich macht..
Hi,
Ich weiß ja noch nicht mal von was du redest...
genau deswegen antworte ich nicht detaillierter: Damit Du _selbst_ diesen Mangel abstellst.
Cheatah
Behalt es für dich...
Jetzt habe ich aber ein Problem....
Ich rufe das Perlscript auf und es funktioniert auch, dass es im Hintergrund alles erledigt....
ruf das Perlskript in der Konsole auf und du solltest Hinweise daruaf bekommen was du falsch machst.
Nur am Bildschirm bekomme ich einen "Internal Server Error" und in meiner Error_log-File steht "premature end of script headers"....
Evtl. hilft aber auch use CGI::Carp qw/fatalsToBrowser/;
Aber ich würde die Konsole vorziehen, da du dann auch die warnungen angezeigt bekommst.
Struppi.
Es kommt keine Warnung...
Es kommt keine Warnung...
... und kein Fehler?
Dann befolge Cheatahs Ratschlag.
Struppi.
Was mache ich denn....Ich bräuchte einen Beispielcode...
Gruss,
M.
Hier mal der CODE um den es geht...
Wie gesagt es funktioniert, nur am Bildschirm kommt nix bzw. Fehlermeldung...(siehe Posting)!!!
#!/usr/bin/perl
use XML::Simple;
use lib "lib";
use GENDB;
use CONTGEN;
use POSIX qw/setsid/;
my %CGIDATEN = decodeCGIDaten();
my $schluessel = "erstmals";
my $erstmals = $CGIDATEN{$schluessel};
if ($erstmals ne "ja") {
my $pid = fork();
die $! unless defined $pid;
if($pid == 0) { die $! unless setsid(); }
else { exit; }
close STDIN;
close STDOUT;
close STDERR;
}
&GENDB::verbindeDB();
print << "ENDE_HTML";
Content-type: text/html\n\n
<html>
<head>
<title>Datenbankgenerierung</title>
<link href="/css/intern.css" rel="stylesheet" type="text/css">
<script LANGUAGE="JavaScript" TYPE="text/javascript" src="/js/intern.js"></script>
</head>
ENDE_HTML
if ($erstmals eq "ja") {
print "<body onload="javascript:history.back(); FensterOeffnen('benutzerpraesenz','/cgi-bin/admin/GENERIERUNG/DB_GENERIERUNG.pl','','DB_GENERIERUNG')">";
}
else {
print "<body>";
_leereTabellen();
_erzeugeKnotenTabellen();
_genVarianten();
_genBloecke();
_genFrageboegen();
_genZustaende();
_genVerzeichnisse();
_genXMLVarianten();
}
print << "ENDE_HTML";
<span class=zentriert style="color:maroon"><h1>Datenbankgenerierung</h2></span>
<br><br><br>
<span class=zentriert><h3>Es wurde begonnen die Daten neu zu generieren!</h3></span>
<br>
<span class=zentriert><h3>Dies kann unter umständen längere Zeit in Anspruch nehmen!</h3></span>
<br><br>
<div class=rechts>
<input type=button value="Schliessen" onClick="JavaScript:self.close()">
</div>
</body>
</html>
ENDE_HTML
&GENDB::trenneDB();
Gruss,
M.
Hi,
#!/usr/bin/perl
perldoc warnings
perldoc strict
my %CGIDATEN = decodeCGIDaten();
Waaah. perldoc CGI
if($pid == 0) { die $! unless setsid(); }
else { exit; }close STDIN;
close STDOUT;
close STDERR;
}
Du brichst alle Brücken ab, bevor Du ein gültiges HTTP-Result erzeugt hast.
print "<body onload="javascript:[...]
"javascript:" ist kein gültiger JavaScript-Befehl.
<span class=zentriert style="color:maroon"><h1>Datenbankgenerierung</h2></span>
Falsche Schachtelung.
<br><br><br>
Nutze CSS.
<span class=zentriert><h3>Dies kann unter umständen längere Zeit in Anspruch nehmen!</h3></span>
Zu spät. Die Antwort kommt erst, wenn die längere Zeit bereits in Anspruch genommen wurde.
<input type=button value="Schliessen" onClick="JavaScript:self.close()">
"JavaScript:" ist auch kein gültiger JavaScript-Befehl. "Schließen" schreibt man mit "ß".
Cheatah
In der neuen Rechtschreibung mit "ss"...
So jetzt nochwas....
Javascript --> passt...
Alles funktioniert....
Brücken abbrechen.....dies sind die Befehle für den Hintergrundprozess...(siehe auch Christian Kruse)....
Halihallo M.
Javascript --> passt...
Alles funktioniert....
Funktionieren != Korrekt
Brücken abbrechen.....dies sind die Befehle für den Hintergrundprozess...(siehe auch Christian Kruse)....
Nein. Sie werden sowohl für Parent, wie auch Childprozess ausgeführt.
Viele Grüsse
Philipp
Hi,
In der neuen Rechtschreibung mit "ss"...
ich wusste nicht, dass das "ie" in "schließen" kurz gesprochen wird.
Javascript --> passt...
Nein, tut es nicht.
Alles funktioniert....
Das war noch nie ein Argument, sondern eher ein Warnzeichen. Siehe </archiv/> und Philipps Antwort.
Cheatah
PASST
PASST
PASST
PASST
Hi,
PASST
PASST
PASST
PASST
wer schreit, hat Unrecht. Was bezweckst Du mit sowas? Willst Du hier Deinen Dickschädel durchsetzen oder etwas lernen?
Cheatah
Hier geht es wohl um ein anderes Problem, als das mit Javascript, welches nicht das Problem ist.
Aber gut, du willst nicht, sondern willst nur Kleinigkeiten (Bürokratenmist) beanstanden.
Schade ist nur, dass das wirkliche Problem nicht gelöst wurde.
Gruss aus der TU München,
Dr. Jochen Berger
Halihallo Dr. Jochen
Hier geht es wohl um ein anderes Problem, als das mit Javascript, welches nicht das Problem ist.
Aber gut, du willst nicht, sondern willst nur Kleinigkeiten (Bürokratenmist) beanstanden.
Schade ist nur, dass das wirkliche Problem nicht gelöst wurde.
[pref:t=77516&m=447443] Cheatah hat die ursprüngliche Frage korrekt
und schnell beantwortet.
[pref:t=77516&m=447483] :
<cite>
Du brichst alle Brücken ab, bevor Du ein gültiges HTTP-Result
erzeugt hast.
</cite>
Auch die zweite Frage wurde von ihm schnell beantwortet. Es fehlte
lediglich der Hinweis, dass exit den Parent-Prozess gleich abwürgt;
aber das Auslassen jenes Hinweises kann jedem passieren.
Der Einspruch ist abgelehnt.
Viele Grüsse
Philipp
Hallöchen!!!
Reicht denn dann auch ein einfaches fork();
Gruss aus dem sonnigen Nürnberg,
Marc
Halihallo Marc04
Reicht denn dann auch ein einfaches fork();
Jain. Ein fork() splittet den Prozess in zwei, es muss eine
Überprüfung vorgenommen werden, die zwischen Child- und Parentprozess
unterscheidet, ansonsten macht der Child genau das, was der Parent
auch macht. Beim Childprozess soll dann auch noch setsid erfolgen,
um einen _wirklichen_ Hintergrundsprozess daraus zu machen, sprich
den Childprozess aus der Hierarchie der Prozesse zu lösen und zu
einer eigenen Session zu "konvertieren", dies löst die beiden
Prozesse aus ihrer "Parent-Child-Beziehung", sodass beide völlig
autark funktionieren.
Viele Grüsse
Philipp
Ich hab das jetzt auch mal probiert mit folgendem Code...
my $pid = fork();
die $! unless defined $pid;
if($pid == 0) { die $! unless setsid(); }
close STDIN;
close STDOUT;
close STDERR;
Bekomme aber auch einen 500er-Fehler....
Gruss,
Marc
Halihallo Marc04
my $pid = fork();
$pid == 0 beim Child-Prozess
$pid == integer-Wert der ProzessId des Childs im Parent.
die $! unless defined $pid;
OK.
if($pid == 0) { die $! unless setsid(); }
Hier geschieht zwar die genannte Fallunterscheidung zwischen Parent
und Child, jedoch führt der Child nach dem if-Block wieder genau
dieselben Sachen aus, wie der Parent.
Vielleicht kann ich es hierdurch etwas klarer beschreiben:
#!/usr/bin/perl
sub thisDoesTheParent() {
print "Content-Type: text/html\015\012\015\012";
print "Alle Ausgaben des Parents!";
}
sub thisDoesTheChild() {
setsid();
# der _Child_ muss nix ausgeben, der _Parent_ (s. oben) schon!
close(STDOUT);
close(STDERR);
...
# Aufgaben des Childs!
}
if (fork()) {
### wahr, wenn fork() die ProzessId des Childs returniert =>
### wir sind also im ParentProzess.
thisDoesTheParent();
} else {
### keine pid => unwahr => wir sind also im ChildProzess
thisDoesTheChild();
}
exit();
close STDIN;
close STDOUT;
close STDERR;
Wie? - Wie oft denn noch: In deinem Programm werden die
Ausgabehandler des Childs, sowie auch dem Parent geschlossen und
somit bekommt man berechtigterweise einen 500er!
---
Ich habe einige Fehlerbehandlungen jetzt ausgelassen, um die Sache
nicht noch unnötig zu komplizieren. Hoffe, dass dies jetzt klar
geworden ist.
Viele Grüsse
Philipp
Hier mal der CODE um den es geht...
Wie gesagt es funktioniert, nur am Bildschirm kommt nix bzw. Fehlermeldung...(siehe Posting)!!!
fehlt da nicht irgendwo noch ein
print "Content-type: text/html\n\n"; ????
Gruss
Alain
Hier mal der CODE um den es geht...
Wie gesagt es funktioniert, nur am Bildschirm kommt nix bzw. Fehlermeldung...(siehe Posting)!!!
D.h. du gibst keinen gültigen HTTP header aus, folglich zeigt der Browser eine Fehlermeldung an, weil er keine antwort bekommt.
Du solltest dich mit einigen grundlegeneden Dingen über CGI Programmierung auseinandersezten.
#!/usr/bin/perl
keine Ahnung wie Fortgeschritten du bist, aber ich würde dir dringend raten die Warnungen anzuschalten (kein wunder das du keine erhälst) und use strict zu verwenden.
#!/usr/bin/perl -w
use strict;
Einbinden der Module
use XML::Simple;
use lib "lib";
use GENDB;
use CONTGEN;use POSIX qw/setsid/;
Aus dem String einen Hash gemacht:
my %CGIDATEN = decodeCGIDaten();
wie schon Cheatah schreibt: use CGI;
Das ist ein Modul für die CGI Programmierung, das dir viele viele Möglichkeiten anbietet eine saubere Ausgabe an den Browser zuschicken.
if($pid == 0) { die $! unless setsid(); }
else { exit; }
Ich weiss nicht, ob du weißt was exit macht. Ich würd es aber auf jeden Fall noch mal nachlesen.
close STDIN;
close STDOUT;
close STDERR;
Auch das würd ich an dieser Stelle noch nicht tun. Da dein Programm noch nicht fertig ist.
Verbindung zur Datenbank
&GENDB::verbindeDB();
Der Aufruf mit '&' ist seit Perl 5 nicht mehr nötig und macht evtl. Dinge duie du nicht willst.
print << "ENDE_HTML";
Content-type: text/html\n\n
<html>
<head>
<title>Datenbankgenerierung</title>
<link href="/css/intern.css" rel="stylesheet" type="text/css">
<script LANGUAGE="JavaScript" TYPE="text/javascript" src="/js/intern.js"></script>
</head>
ENDE_HTML
Und genau dafür bietet das CGI Modul saubere Funktionen an
print CGI::header(),
CGI::start_html(
-meta => {'content-type' => "text/html; charset=iso-8859-1"},
-title => '....',
-style => {src => '/css/intern.css'}
-script => {src => '/js/intern.js'}
)
;
if ($erstmals eq "ja") {
print "<body onload="javascript:history.back(); FensterOeffnen('benutzerpraesenz','/cgi-bin/admin/GENERIERUNG/DB_GENERIERUNG.pl','','DB_GENERIERUNG')">";
'javascript:' ist hier lediglich ein nutzloses Label, das in älteren Browsern zu Fehlermeldungen führt.
print << "ENDE_HTML";
<span class=zentriert style="color:maroon"><h1>Datenbankgenerierung</h2></span>
das <span> ist absolut überflüssig:
<h1 class=zentriert style="color:maroon">Datenbankgenerierung</h1>
<div class=rechts>
<input type=button value="Schliessen" onClick="JavaScript:self.close()">
</div>
auch hier ist das Label nicht nötig.
Struppi.
Halihallo Martina
Ich beziehe mich auf folgendes Thema:
http://forum.de.selfhtml.org/?t=77385&m=446621
Warum wartest du dort nicht auf eine Antwort? - Du hast dieselbe
Frage dort schon gestellt ([pref:t=77385&m=446781]).
Ich rufe das Perlscript auf und es funktioniert auch, dass es im Hintergrund alles erledigt....
Irrelevant, denn nur das aufgerufene Script ist wichtig. Und _dieses_
gibt keine HTTP-Header aus.
Nur am Bildschirm bekomme ich einen "Internal Server Error" und in meiner Error_log-File steht "premature end of script headers"....
Du fork(st) einen neuen Prozess, der Parent-Prozess (das über
HTTP aufgerufene) gibt keinen Header aus, denn dieser wird über
exit gleich beendet. Zur normalen Ausgabe weiter unten kommt er erst
gar nicht (im Parentprozess). Lass einfach exit() weg.
Viele Grüsse
Philipp
Hallo!
Wenn ich exit weglasse läuft es dann auch noch im Hintergrund so wie jetzt???
Gruss,
M.
Halihallo M.
Wenn ich exit weglasse läuft es dann auch noch im Hintergrund so wie jetzt???
fork & setsid macht den Hintergrundsprozess, nicht exit. Die Antwort
lautet also ja.
Dein Hauptprogramm wurde stets gleich nach fork abgewürgt und kam
gar nicht erst zur Aussgabe. Das ist IMHO nicht im Sinne deiner
Aufgabenstellung. Zudem, s. Cheatah, beendest du für Child wie auch
Parent stets gleich die Ausgabehandler und dies führt zu deinem
Problem mit dem 500-er Internal Server Error.
BTW: Lies doch bitte die Doku bzgl. fork, setsid und exit. Du
ersparst dir einiges an Problemen und uns das Antworten.
Viele Grüsse
Philipp