Martina: premature end of script headers

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.

  1. 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

    --
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Warum nicht???
      Weil es im Hintergrund gestartet wird oder was?
      Wie ist das zu lösen....

      Gruss und Danke,
      M.

      1. 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

        --
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. 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.

          1. 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

            --
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Was soll jetzt diese Geheimnistuerei

              1. Hi,

                Was soll jetzt diese Geheimnistuerei

                selber denken macht schlau.

                Cheatah

                --
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. Ich weiß ja noch nicht mal von was du redest...aber gut...behalt es für dich wenn es dich glücklich macht..

                  1. Hi,

                    Ich weiß ja noch nicht mal von was du redest...

                    genau deswegen antworte ich nicht detaillierter: Damit Du _selbst_ diesen Mangel abstellst.

                    Cheatah

                    --
                    X-Will-Answer-Email: No
                    X-Please-Search-Archive-First: Absolutely Yes
                    1. Behalt es für dich...

  2. 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.

    1. Es kommt keine Warnung...

      1. Es kommt keine Warnung...

        ... und kein Fehler?

        Dann befolge Cheatahs Ratschlag.

        Struppi.

        1. Was mache ich denn....Ich bräuchte einen Beispielcode...

          Gruss,
          M.

  3. Hier mal der CODE um den es geht...
    Wie gesagt es funktioniert, nur am Bildschirm kommt nix bzw. Fehlermeldung...(siehe Posting)!!!

    #!/usr/bin/perl

    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();

    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;
    }

    Verbindung zur Datenbank

    &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

    Verbindung zur Datenbank trennen

    &GENDB::trenneDB();

    Gruss,
    M.

    1. 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

      --
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
      1. 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)....

        1. 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

          --
          Any given program, when running, is obsolete.
        2. 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

          --
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. PASST
            PASST
            PASST
            PASST

            1. 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

              --
              X-Will-Answer-Email: No
              X-Please-Search-Archive-First: Absolutely Yes
              1. 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

                1. 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

                  --
                  Any given program, when running, is obsolete.
                  1. Hallöchen!!!

                    Reicht denn dann auch ein einfaches fork();

                    Gruss aus dem sonnigen Nürnberg,
                    Marc

                    1. 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

                      --
                      Any given program, when running, is obsolete.
                      1. 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

                        1. 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

                          --
                          Any given program, when running, is obsolete.
    2. 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

    3. 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.

  4. 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

    1. Hallo!

      Wenn ich exit weglasse läuft es dann auch noch im Hintergrund so wie jetzt???

      Gruss,
      M.

      1. 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

        --
        Any given program, when running, is obsolete.