Anzeige:
Seite 3 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 31 bis 45 von 60

Thema: (HTTP) Server mit Qt4

  1. #31
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von TheDodger Beitrag anzeigen
    Ahhh, eine Fehlinterpretation meinerseits ...
    Sowas kann sich echt fix rächen

    Leider scheint auch ein insert() nicht so wie gewünscht zu funktionieren (jedenfalls, so, wie ich es gerade mache) ...
    Cache.h:
    Code:
    class RequestCache {
    
       public:
                           RequestCache()           { m_file = "" ; m_data = ""; }
    
          void              setFile( QString f )    { m_file = f; }
          void              setData( QByteArray d ) { m_data = d; }
    
          QByteArray        data() { return m_data; }
          
       private:   
          QString           m_file;
          QByteArray        m_data;
    };
    
    class RIPCache
     : public QObject,
       public ErrorHandler {
    
       public:
                            RIPCache();
                            ~RIPCache();
    
          void              insert( QString file, QByteArray d );
    
          bool              inCache( QString );
          QByteArray        fromCache( QString f );
          
       private:
          QCache<QString, RequestCache> m_cache;
          RequestCache*     r_cache;
    
    };
    Cache.cpp
    Code:
    RIPCache::RIPCache() {
    
       r_cache = new RequestCache();
       QCache<QString, RequestCache> m_cache(500000);
    }
    
    RIPCache::~RIPCache() {}
    
    
    void RIPCache::insert( QString f, QByteArray d ) {
    
       r_cache->setFile( f );
       r_cache->setData( d );
    
       Debug( QString( "  size bevore '%1'" ).arg( m_cache.size() ).toAscii() );
       
       m_cache.insert( f, r_cache );
    
       Debug( QString( "  size after  '%1'" ).arg( m_cache.size() ).toAscii() );
    }
    Kurzauszüge des aktuellen Codes.
    So bald ich eine 2. Datei in den Cache legen will, bekomme ich einen SegFault und das gesamte Gebilde stürtzt ab. :-(

    Vielleicht sieht jemand von euch auf den ersten Blick meinen Denkfehler?

    Gruß!
    B.
    Bodo
    Systemadmistration UNIX

  2. #32
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    Also bei mir (nach dem Hinzufügen von 68 Zeilen Code ) segfaultet es nicht, aber die Semantik ist sowieso falsch... Alle deine Cache-Einträge zeigen auf das selbe Element, nämlich den private class-member r_cache... Dieser enthält immer den Inhalt des zuletzt gecachten Files.

    Flicken z.B. so:
    Code:
    void RIPCache::insert( QString f, QByteArray d ) {
    
       RequestCache *r = new RequestCache();
    
       r->setFile( f );
       r->setData( d );
    
       Debug( QString( "  size bevore '%1'" ).arg( m_cache.size() ).toAscii() );
       
       m_cache.insert( f, r_cache );
    
       Debug( QString( "  size after  '%1'" ).arg( m_cache.size() ).toAscii() );
    }
    Schöner wäre, wenn die Argumente für die Cache-Items direkt im Konstruktor übergeben werden... (also RequestCache *r = new RequestCache(f, d); ).
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  3. #33
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von jeebee Beitrag anzeigen
    Also bei mir (nach dem Hinzufügen von 68 Zeilen Code ) segfaultet es nicht, aber die Semantik ist sowieso falsch... Alle deine Cache-Einträge zeigen auf das selbe Element, nämlich den private class-member r_cache... Dieser enthält immer den Inhalt des zuletzt gecachten Files.
    Danke!
    Ich merke gerade, das zu viel guten Wein aus Schwiegervaterns Keller nicht unbedingt fördernd wirkt :}
    Schöner wäre, wenn die Argumente für die Cache-Items direkt im Konstruktor übergeben werden... (also RequestCache *r = new RequestCache(f, d); ).
    Ich hab das mal aufgegriffen und umgebaut & schon läuft es wie geschnitten Brot!

    Code:
    siege -v -b -t30s -c5 http://localhost:8080/index.html
    
    Lifting the server siege..      done.
    Transactions:                  37332 hits
    Availability:                 100.00 %
    Elapsed time:                  29.11 secs
    Data transferred:               2.60 MB
    Response time:                  0.00 secs
    Transaction rate:            1282.45 trans/sec
    Throughput:                     0.09 MB/sec
    Concurrency:                    4.88
    Successful transactions:       37332
    Failed transactions:               0
    Longest transaction:            0.12
    Shortest transaction:           0.00
    Flink. Naja, bei einer einzigen statischen Seite, die nix wirklich kann ...
    Bodo
    Systemadmistration UNIX

  4. #34
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Ich hab mal eine aktuelle Version zum download auf den Server kopiert.

    Fühlt euch frei ...
    Bodo
    Systemadmistration UNIX

  5. #35
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Und da hat es mich wieder, das schwarze Loch ...

    Ich hänge gerade beim auseinandernehmen des HTML-Headers fest, da ich gerade versuche einen POST/PUT Request (also das hochladen einer Datei) zusammen zu stümpern ...

    Ich habe jetzt in einem QByteArray alles an HTML-Header, was mit der Browser schickt.
    Nun möchte ich den aber nicht gerade Zeile für Zeile durchwühlen um herauszufinden, wann dort ein 'multipart/form-data; boundary=' drin vorkommt, bzw. die realen Daten ...

    Gibt es dafür denn keinen einfachen, eleganten Weg?
    Bodo
    Systemadmistration UNIX

  6. #36
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von TheDodger Beitrag anzeigen
    Und da hat es mich wieder, das schwarze Loch ...

    Ich hänge gerade beim auseinandernehmen des HTML-Headers fest, da ich gerade versuche einen POST/PUT Request (also das hochladen einer Datei) zusammen zu stümpern ...

    Ich habe jetzt in einem QByteArray alles an HTML-Header, was mit der Browser schickt.
    Nun möchte ich den aber nicht gerade Zeile für Zeile durchwühlen um herauszufinden, wann dort ein 'multipart/form-data; boundary=' drin vorkommt, bzw. die realen Daten ...

    Gibt es dafür denn keinen einfachen, eleganten Weg?
    Nach 2 harten Tagen Denksport hab ichs wohl ... nicht sehr elegant und wahrscheinlich auch eher suboptimal wenn es um performance geht, aber erstmal gehts.
    Bodo
    Systemadmistration UNIX

  7. #37
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von TheDodger Beitrag anzeigen
    Nach 2 harten Tagen Denksport hab ichs wohl ... nicht sehr elegant und wahrscheinlich auch eher suboptimal wenn es um performance geht, aber erstmal gehts.
    Zu früh gefreut.
    Bei (Binär)Dateien oberhalb von 250k scheint der Datenstrom nicht ganz beim Serverprozess angekommen zu sein.
    Jedenfalls kann ich keine Dateien über 250k empfangen

    v20110107 download
    Geändert von TheDodger (07-01-2011 um 13:08 Uhr)
    Bodo
    Systemadmistration UNIX

  8. #38
    Registrierter Benutzer
    Registriert seit
    18.04.2008
    Beiträge
    59
    Zitat Zitat von TheDodger Beitrag anzeigen
    v20110107 download
    Was anderes ist mir aufgefallen, was leicht zu fixen sein kann,
    wenn der GET Request auch direkt zerlegt werden soll?

    Dann würde man bei "get.html?arg1=val1&arg2=val2" kein 404 erhalten.

    PHP-Code:
    // in QString Request::GET_Request() {
    // ...
          
    if( directory.existsWebRoot ) && directory.isReadable() ) {

          
    // readquery
          
    bool hasQuery false;
          
    QString qs;
          for (
    int j 0HTML_Request.size(); ++j) {
             
    // if (hasQuery)  qs += HTML_Request[j];
             
    if (HTML_Request[j] == '?') {
                 
    hasQuery true;
             }
          }

          if (
    hasQuery) {
            
    QStringList qsl HTML_Request.split("?");
            
    // ...filename = ...
             // ...
             // QStringList params = qsl.split("&");
          
    } else 
             
    //  filename = HTML_Request; 
    Und im Destruktor der "writeExampleConfiguration" Call überschreibt die Config.
    Bei mir ist 8080 schon belegt, daher fande ich die "User" config praktisch.

    PHP-Code:
    RIPCoreApplication::~RIPCoreApplication() {
       
    /* writeExampleConfiguration(); */
       
    markUp();

    Geändert von zenobic (10-01-2011 um 00:33 Uhr)

  9. #39
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von zenobic Beitrag anzeigen
    Was anderes ist mir aufgefallen, was leicht zu fixen sein kann,
    wenn der GET Request auch direkt zerlegt werden soll?

    Dann würde man bei "get.html?arg1=val1&arg2=val2" kein 404 erhalten.
    Danke!
    Baue ich mit ein.
    Zitat Zitat von zenobic Beitrag anzeigen
    Und im Destruktor der "writeExampleConfiguration" Call überschreibt die Config.
    Bei mir ist 8080 schon belegt, daher fande ich die "User" config praktisch.
    Ich hatte das Thema QSettings bislang nicht so auf dem Schirm, da ich mich ja um das POST-Problem gekümmert hatte.
    Meine alten configure-Klasse ist ja auch eher so ein alter Zopf, den ich mal unter Qt2 gebastelt hatte ... das Ding wird nun komplett entfernt.
    Bodo
    Systemadmistration UNIX

  10. #40
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Nachtrag meinerseits ...

    Das hier:
    PHP-Code:
          for (int j 0HTML_Request.size(); ++j) {
             
    // if (hasQuery)  qs += HTML_Request[j];
             
    if (HTML_Request[j] == '?') {
                 
    hasQuery true;
             }
          } 
    Lässt sich effektiver so lösen:
    PHP-Code:
             hasQuery = ( HTML_Request.indexOf'?' ) != -) ? true false
    Bodo
    Systemadmistration UNIX

  11. #41
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von TheDodger Beitrag anzeigen
    Zu früh gefreut.
    Bei (Binär)Dateien oberhalb von 250k scheint der Datenstrom nicht ganz beim Serverprozess angekommen zu sein.
    Jedenfalls kann ich keine Dateien über 250k empfangen

    v20110107 download
    Ich hab gerade noch gesehen, dass die die Daten, die via POST kommen, stark vom 'enctype' im <form></form> Block abhängen.
    Somit reicht ja nicht mal ein simpler Parser, sondern damit wird das echt komplex ... :-(
    Bodo
    Systemadmistration UNIX

  12. #42
    Registrierter Benutzer
    Registriert seit
    18.04.2008
    Beiträge
    59
    Mein Vorschlag mit dem GET Request war auch nicht ganz richtig,
    mir fiel auf, dass im allgemeinen "Request handle", also vorher schon geparsed werden muss,
    da dies genauso bei POST Requests der Fall sein kann.
    Und man müsste noch nach Slash zerlegen und auf "is directory" prüfen,
    da es auch sein kann dass der Query String (und resultierende enviroment variable: QUERY_STRING wenn cgi implementiert wird) Slashs enthält
    ( z.B: http://1.2.3.4/shop.cgi/categories/all ).

    Zitat Zitat von TheDodger Beitrag anzeigen
    Ich hab gerade noch gesehen, dass die die Daten, die via POST kommen, stark vom 'enctype' im <form></form> Block abhängen.
    Somit reicht ja nicht mal ein simpler Parser, sondern damit wird das echt komplex ... :-(
    Ich dachte man kann es so realisieren,
    dass alles was POST ist, auch ein potentieller Upload sein kann, also den POST Header parsen auf wenn vorhanden:
    * "content-type" : auch "boundary=" enthalten ist, muss zerlegt werden.
    * "content-disposition" : filename oder name und noch
    * "content-transfer-encoding".


    Gibt es denn einen Grund PUT zu implementieren?

    Viele Webserver unterstützen nur POST, GET und HEAD, vorallem aus Sicherheitsgründen.

  13. #43
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von zenobic Beitrag anzeigen
    Mein Vorschlag mit dem GET Request war auch nicht ganz richtig,
    mir fiel auf, dass im allgemeinen "Request handle", also vorher schon geparsed werden muss,
    da dies genauso bei POST Requests der Fall sein kann.
    Und man müsste noch nach Slash zerlegen und auf "is directory" prüfen,
    da es auch sein kann dass der Query String (und resultierende enviroment variable: QUERY_STRING wenn cgi implementiert wird) Slashs enthält
    ( z.B: http://1.2.3.4/shop.cgi/categories/all ).
    Das parsen des query-Strings habe ich aktuell noch nicht 100%ig implementiert bzw. durchdacht.
    Aber ich denke, das dürfte nicht wirklich sooo kompliziert werden.
    Ich hab mich mehr beim POST festgefressen.

    Zitat Zitat von zenobic Beitrag anzeigen
    Ich dachte man kann es so realisieren,
    dass alles was POST ist, auch ein potentieller Upload sein kann, also den POST Header parsen auf wenn vorhanden:
    * "content-type" : auch "boundary=" enthalten ist, muss zerlegt werden.
    * "content-disposition" : filename oder name und noch
    * "content-transfer-encoding".


    Gibt es denn einen Grund PUT zu implementieren?

    Viele Webserver unterstützen nur POST, GET und HEAD, vorallem aus Sicherheitsgründen.
    Ich will ja gar nicht PUT implementieren!
    Das POST raubt mir schon genug Nerven ...

    Hier mal ein paar Beispiele
    #1 mit
    Code:
    <form action="post.html" name="form" enctype="multipart/form-data" method="post">
    http://pastebin.de/13713
    #2 mit
    Code:
    <form action="post.html" name="form"  method="post">
    http://pastebin.de/13714

    Also 2 völlig verschiedene Wege um die POST-Variablen auszuwerten ...
    Bei #1 fällt dann auch auf, dass 'Content-Disposition: form-data; ...' mehrmals vorkommt.
    Ich bin ja so vorgegangen, dass ich vom letzten Eintrag anfange zu parsen. Scheinbar funktioniert das aber nicht wie gewünscht ...
    Bodo
    Systemadmistration UNIX

  14. #44
    Registrierter Benutzer
    Registriert seit
    18.04.2008
    Beiträge
    59
    Zitat Zitat von TheDodger Beitrag anzeigen
    Also 2 völlig verschiedene Wege um die POST-Variablen auszuwerten ...
    Bei #1 fällt dann auch auf, dass 'Content-Disposition: form-data; ...' mehrmals vorkommt.
    Ich bin ja so vorgegangen, dass ich vom letzten Eintrag anfange zu parsen. Scheinbar funktioniert das aber nicht wie gewünscht ...
    Ja, man braucht wahrscheinlich mindestens 2 Schritte um postdata zu parsen.

    Aber dass sind, soweit ich weiss, auch die einzigen 2 Fälle die auch andere Webserver abfangen.

    Ich glaube so könnte der Ablauf funktionieren:

    Allgemein Header splitten auf ':' zum Auslesen.

    Wenn POST dann (content-length speichern etc.) im
    HEADER['content-type'] auf "boundary" oder "multipart" testen.

    Wenn es kein Multipart ist und boundary enthält, kann man die Parameter (wie #1)
    zerlegen.
    Ansonsten boundary speichern ( #2 ), dann muss man parsen, z.B. mit spiltten nach boundary, diese beginnen mit
    Code:
    "\r\n--" + boundary
    und in einer Schleife analysieren, wenn dann ein filename enthalten ist, muss dies temporär gespeichert werden, z.B. nach /tmp mit einem "tmp name".

    #1 Nach new 2 NewLines "\r\n\r\n" und als QUERY_STRING speichern,
    (ggf. nach & und = zerlegen)

    #2 mit boundary, dann boundaries zerlegen.
    Aus der 'content-disposition' Line name und ggf. filename extrahieren,
    ggf. alles nach Semikolon auf '=' splitten.
    Wenn zwischen den Boundaries 'content-type' vorkommt, dann die eingelesen Chars (data)
    als Datei speichern, ansonsten als Postdata in z.B. POST[name] = data .


    Ich denke das kann auch richtig Spass machen
    Geändert von zenobic (10-01-2011 um 19:41 Uhr)

  15. #45
    Registrierter Benutzer Avatar von TheDodger
    Registriert seit
    17.05.2001
    Ort
    Hamburg
    Beiträge
    615
    Zitat Zitat von zenobic Beitrag anzeigen
    Wenn POST dann (content-length speichern etc.) im
    HEADER['content-type'] auf "boundary" oder "multipart" testen.

    Wenn es kein Multipart ist und boundary enthält, kann man die Parameter (wie #1) zerlegen.
    Ansonsten boundary speichern ( #2 ), dann muss man parsen, z.B. mit spiltten nach boundary, diese beginnen mit
    Code:
    "\r\n--" + boundary
    und in einer Schleife analysieren, wenn dann ein filename enthalten ist, muss dies temporär gespeichert werden, z.B. nach /tmp mit einem "tmp name".

    #1 Nach new 2 NewLines "\r\n\r\n" und als QUERY_STRING speichern, (ggf. nach & und = zerlegen)

    #2 mit boundary, dann boundaries zerlegen.
    Aus der 'content-disposition' Line name und ggf. filename extrahieren, ggf. alles nach Semikolon auf '=' splitten.
    Wenn zwischen den Boundaries 'content-type' vorkommt, dann die eingelesen Chars (data) als Datei speichern, ansonsten als Postdata in z.B. POST[name] = data .

    Ich denke das kann auch richtig Spass machen
    Eigentlich mache ich es ja genau so, wie du es beschrieben hast ... (Mein Code ist in der 'MultipartData.cpp' ) ... jedenfalls denke ich das.
    Aber ich zweifle gerade daran ...
    Geändert von TheDodger (11-01-2011 um 21:15 Uhr)
    Bodo
    Systemadmistration UNIX

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •