Servlets oder cgi in Server einbinden

Status
Nicht offen für weitere Antworten.

Yogi

Mitglied
Hallo,

ich habe einen Http Server selber geschrieben. Der kann nun Post und Get Requests verarbeiten. Nun ist die Frage, wie kann ich auf eine einfache weiße meinen Server so erweitern, dass er Servlets verarbeiten kann? Kann mir das nicht ganz vorstellen. Und wenn cgi einbinden leichter wäre, wie sollte ich da vorangehen?
 
@Gekkonier Da hast du natürlich Recht.

D.h. du mußt zuerst die Shebang auslesen und dann einen entsprechenden Interpreter laden.
 
stimmt, Shebang.

d.h. erste zeile vom script = #!/pfad/zum/interpretermitdemjenedateinterpretiertwerdensoll

und die Scriptdatei selber ausführbar machen, und ohne Extension (oder *.cgi) verwenden. Dann kann man auch einfach mal z.B. ein anderes Script anderer Sprache, gleicher Funktion dort reinhängen, ohne dass man die Konsitenz zerstört.
Natürlich kann man an dieser Stelle dann z.B. auch ein compiliertes Programm einsetzen, wenns nötig ist.
 
ok, irgendwie alles grad ein bisschen konfus für mich. Mit interpreter, ok, check ich, aber ich steh völlig an, wie ich das in java umsetzen soll, dass er mir das cgi verarbeitet.
weil ich hab ja auf meinen Server ein paar html files liegen, dort gibts dann halt a mal a post request, dass halt ein cgi skript verwendet, aber wie mach ich dass, dass der server weiß, was er mit dem cgi machen muss und vor allem wie er das cgi handeln soll?
 
Erstmal musst du rausfinden wie dein Server konfiguriert ist und wie Dein CGI Pfad gemappt ist.
Könnte z.b. so aussehen:
http://www.meineseite.xy/cgi-bin/blabla.cgi
INTERN im Filesystem könnten die CGI's irgendwo liegen.
Auf einem meiner Server liegen die CGI's z.B. da:
/usr/lib/cgi-bin

und in meiner Apache Konfiguration (die richtige Stelle dafür müsstest du noch suchen 😉)

Code:
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin
<Directory /usr/lib/cgi-bin/>
  AllowOverride None
  Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
  Order allow,deny
  Allow from all
</Directory

Diesbezüglich schau aber noch die Dokus durch! Die obige Konfiguration ist in meinem Heimnetzwerk, weis ned genau ob das die sichere Produktionstaugliche CGI Konfiguration ist.
Wie man jetzt explizit Java-Programm dort ausführen kann weis ich selber ned. Ich führe dort nur Ruby und Perl Skripte aus.
 
@gekkonier Nix Apoache. Yogi will einen eigenen Webserver entwickeln.

@Yogi Du mußt einfach über Runtime den Interpreter aufrufen und das Ergebnis an den Client senden. Du mußt nur etnscheiden wann ein Request ein CGI aufruft und wann eine html-Seite. Am besten machst du das über das cgi-bin. D.h. alle Request die auf das cgi-bin kommen werden an einen Interpreter übergeben und das Ergebnis davon (Outpustream) an den Client gesendet.
 
Yogi hat gesagt.:
ich habe einen Http Server selber geschrieben. Der kann nun Post und Get Requests verarbeiten

Wenn ich das richtig verstehe, soll dein selbstgestrickter Server JSP-Seiten verarbeiten.
Dazu müßtest du dir auch einen richtigen Servlet-Container dazustricken.

Das wird mit Sicherheit alles andere als einfach werden... 🙁
 
Das ist mir entfleucht, dass er einen eigenen Server schreiben will. Tschuldigung.
(Vielleicht hilfts aber den Mechanismus zu verstehen, der erfolgreich implementiert wurde?)
 
Das wird mit Sicherheit alles andere als einfach werden...
Es gibt aber schon genug kleine Httpserver mit Servletcontainer im Opensourcebereich, bei denen man etwas abgucken kann ;-)

Man muß ja auch nicht alles implementieren. Es würde ja schon reichen, wenn man ein paar Strings zurück geben kann.
 
Und nein, ich bekomms einfach nicht hin, ist zum verzweifeln. Wie kann ich den Perl Interpreter starten. Das ich dazu die Runtime und Process Klassen brauche ist mir klar. Nur irgendwie check ichs trotzdem nicht und googel ist dieses mal nicht mein freund, der liefert mir nicht wirklich was vernünftiges. Also, ich brauche mal die cgi-lib.pl. Hoffe dass passt. Und diese muss ich ja dann starten, und da hängts dann völlig bei mir.
 
Du brauchst keine cgi-lib.pl zu laden, das macht der Interpreter für dich.

Also mal angenommen du bekommst einen Request auf die Ressource /cgi-bin/hello.pl. Dann rufst du Runtime.exec ungefähr so auf:

Code:
Process p = Runtime.exec("perl.exe /foo/bar/cgi-bin/hello.pl");

Von dem Process holst du dir dann den Outputstream und gibst den als Response wieder raus. Du mußt jetzt nur noch darauf achten das die Pfade zum Perlinterpreter und zu dem Script stimmen. Das ist alles.
 
Also ich hab das jetzt so gemacht, dass ich eine eigene Klasse fürs CGI gemacht habe, die schaut ganz einfach so aus:

Code:
public class StartCgi {
	OutputStream os;
	public StartCgi(String cgi){
		Process p = null;
		try {
			System.out.println("Perl is starting");
			p = Runtime.getRuntime().exec("cgi\\perl.exe cgi\\" + cgi);
			this.os = p.getOutputStream();
		} catch (IOException e) {
			System.out.println("Perl does not start");
			e.printStackTrace();
		}
	}
	public OutputStream getOutputStream(){
		return this.os;
	}

}

Und dann halt in der Getmethode folgender maßen vorgegangen bin

Code:
if(file.startsWith("cgi", 1)){
			System.out.println("CGI");
			
                        //suche wo Variablen in file hinten angehaengt sind, damit ich
                       //an Klasse StartCGI den richtigen Filenamen uebergebe
			for(i = 0; i < file.length(); i++){
				if(file.substring(i, i+1).equals("?")){
					System.out.println("BREAK " + i);
					break;
				}
			}
                        //Interpreter Starten und os (PrintStream) neu setzen
			StartCgi cgi = new StartCgi(file.substring(5, i));
			os = new PrintStream(cgi.getOutputStream());
			try{
							
				File theFile = new File("F:\\workspace\\NWS\\cgi", file.substring(5, i));
				FileInputStream fis = new FileInputStream(theFile);
				byte[] theData = new byte[(int) theFile.length()];
							
				//need to check the number of bytes read here
				fis.read(theData);
				fis.close();

				if(version.startsWith("HTTP/")){//send a MIME header
					os.print("HTTP/1.0 200 OK\r\n");
					Date now = new Date();
					os.print("Date: " + now + "\r\n");
					os.print("Server: jhttp 1.0\r\n");
					os.print("Content-length: " + theData.length + "\r\n");
					os.print("Content-type: " + ct + "\r\n\r\n");
				}

				os.write(theData);
				os.close();
			}//end try

aber jetzt wird mir einfach eine leere Seite zurückgelierfert, bzw IE schreit, dass Seite nicht angezeigt werden kann. Was muss ich anders machen? Bzw muss ich einen bestimmten Content-type setzen?
 
Code:
p = Runtime.getRuntime().exec("cgi\\perl.exe cgi\\" + cgi);
Was machen denn die Slashes und der String cgi am Anfang da? Warum schreibst du nicht?

Code:
p = Runtime.getRuntime().exec("perl.exe " + cgi);

aber jetzt wird mir einfach eine leere Seite zurückgelierfert
Wie sieht der Response denn aus? Bekommst du das Resultat vom CGI geliefert? Poste mal bitte den Response von einem Hello World Script.

Als Contenttype kannst du zum testen erstmal text/plain verwenden.
 
Ok, also es scheint so, als ob das Skript einfach beim Response hinten angehängt wird.
Bei einem Get Request, ohne dass Werte mitgegeben werden, schreit er not Implemented, bei einem Get Request, wo Werte in der Url mitgegeben werden, zeigt er mir das Skript an
 
Ach und ohne die Slashes bekomm ich ne Exception, dass er nix findet
Wer finde was nicht? Exception?


Du mußt zuerst mal dafür sorgen, daß das Script ausgeführt wird und du das Ergebnis als String speicherst. Dann mußt du es einfach im Body des Http-Responses zurück geben.
 
Also bei mir läuft das ohne Probleme:

Code:
import java.io.*;

public class ExecutePerl
{
    public static void main(String[] args)
    {
        try
        {
            Process p =  Runtime.getRuntime().exec("perl /home/steffen/hello.pl");
            
            StringBuilder buffer = new StringBuilder();
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null )
            {
                buffer.append(line);
            }
            System.out.println("Response: " + buffer.toString());
            
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

hello.pl
Code:
#! /usr/bin/perl
print "hello \n";


Wenn die Shebag korrekt ist kannst du dir expliziten Aufruf von Perl auch sparen. Das Einlesen des Inputstreams sollte man vielleicht etwas abwandeln, damit man auch Responses lesen kann die nicht mit einem Zeilenendezeichen enden.
 
ha, jetzt funkt des auch. Aber nur solange keine Variablen übergeben werden( zB in der Url) da gibt er mir dann null zurück im Response. des cgi-lib.pl sollte ja eigentlich dafür sorgen, dass die Variablen geholt werden
 
ha, jetzt funkt des auch. Aber nur solange keine Variablen übergeben werden( zB in der Url) da gibt er mir dann null zurück im Response. des cgi-lib.pl sollte ja eigentlich dafür sorgen, dass die Variablen geholt werden
Das mußt du alles selber implementieren, ist doch dein Server ;-)

Das Parsen der Requests und das zur Verfügung stellen der CGI-Variablen ist alles Sache des Servers.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben