Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-settings.php on line 512

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-settings.php on line 527

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-settings.php on line 534

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-settings.php on line 570

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-includes/cache.php on line 103

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-includes/query.php on line 61

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-includes/theme.php on line 1109

Deprecated: Assigning the return value of new by reference is deprecated in /var/kunden/webs/www-0003/pastacode/wp-content/plugins/dofollow.php on line 418

Warning: Cannot modify header information - headers already sent by (output started at /var/kunden/webs/www-0003/pastacode/wp-settings.php:512) in /var/kunden/webs/www-0003/pastacode/wp-content/plugins/gengo/gengo.php on line 1188
Web-Development in C++ | Pastacode Informatik Blog

Web-Development in C++


Deprecated: Function split() is deprecated in /var/kunden/webs/www-0003/pastacode/wp-content/plugins/codeviewer/codeviewer.php on line 75

Deprecated: Function split() is deprecated in /var/kunden/webs/www-0003/pastacode/wp-content/plugins/codeviewer/codeviewer.php on line 75

Deprecated: Function split() is deprecated in /var/kunden/webs/www-0003/pastacode/wp-content/plugins/codeviewer/codeviewer.php on line 75

Deprecated: Function split() is deprecated in /var/kunden/webs/www-0003/pastacode/wp-content/plugins/codeviewer/codeviewer.php on line 75

Php ist inzwischen überall… und hat sich zur Programmiersprache des dynamischen Webs etabliert. Aber was, wenn es zu langsam wird?

Sicher: es gibt den eaccelerator und noch andere Möglichkeiten PHP schneller zu machen. Im großen und ganzen mag ich PHP aber gar nicht so sehr, also begab ich mich auf die Suche nach Alternativen. Warum nicht C++? Es war etwas schwer an die richtigen Informatinen zu kommen und es existieren auch noch alte Informationen die C(++) in Zusammenhang mit dem in die Jahre gekommenen CGI verwenden.

Stand der Dinge: FCGI ist die neue allgemeine Schnittstelle über die man in fast allen möglichen Programmiersprachen Webprojekte programmieren kann. Unterstützt wird das von Apache über mod_fcgi. Für C++ exisitiert inzwischen fastcgipp, eine Library mit einer kleinen Priese Framework, die jedem C++ Entwickler einen einfachen Zugang zur Webentwicklung geben sollte. Die Konfiguration von mod_fcgi soll hier aber nicht weiter erläutert werden.

Nachdem man seinen Webserver eingerichtet hat und fastcgipp kompiliert hat, kann es losgehen. Ein Beispielcode sagt mehr als Tausend Worte… Also hier ein kleines Programm, das ein paar Session Variablen ausgibt und mit q= einen GET-Parameter übergeben bekommt. Das auslesen einer GET-Variable funktioniert in fastcgipp etwas spartanischer als man es von PHP gewöhnt ist, man muss es nämlich per Hand machen. Da Boost sowieso von fastcgipp benötigt wird, kann man aber auch sehr bequem boost.regex (eine C++-Library für reguläre Ausdrücke) für diese Aufgabe verwenden.

  1. #include <fstream>
  2. #include <fastcgi++/request.hpp>
  3. #include <fastcgi++/manager.hpp>
  4. #include <string>
  5. #include <fstream>
  6. #include <wchar.h>
  7. //#include <locale.h>
  8. #include <boost/regex.hpp>
  9. //#include <vector>
  10.  
  11. //eigenes Error log
  12. void error_log(const char* msg)
  13. {
  14. using namespace std;
  15. using namespace boost;
  16. static ofstream error;
  17. if(!error.is_open())
  18. {
  19. error.open("/tmp/errlog", ios_base::out | ios_base::app);
  20. error.imbue(locale(error.getloc(), new posix_time::time_facet()));
  21. }
  22. error << ‘[' << posix_time::second_clock::local_time() << "] " << msg << endl;
  23. }
  24.  
  25.  
  26. //Klasse die von Fastcgipp::Request erbt und bool response() implementiert
  27. class SimpleFcgi: public Fastcgipp::Request<wchar_t>
  28. {
  29. bool response()
  30. {
  31. //Header: muss mit zweimaligen \r\n abgeschlossen werden
  32. out << "Content-Type: text/html; charset=utf-8\r\n\r\n"; //charset ist utf8
  33.  
  34. out << "<html><head><meta http-equiv=’Content-Type’ content=’text/html; charset=utf-8′ />";
  35. out << "<title>Simple fastcgi++</title></head><body>";
  36.  
  37. //Print Session Parameter
  38. out << "<h1>Session Parameters</h1>";
  39. out << "<p><b>Hostname:</b> " << session.host << "<br />";
  40. out << "<b>User Agent:</b> " << session.userAgent << "<br />";
  41. out << "<b>Accepted Content Types:</b> " << session.acceptContentTypes << "<br />";
  42. out << "<b>Accepted Languages:</b> " << session.acceptLanguages << "<br />";
  43. out << "<b>Accepted Characters Sets:</b> " << session.acceptCharsets << "<br />";
  44. out << "<b>Referer:</b> " << session.referer << "<br />";
  45. out << "<b>Content Type:</b> " << session.contentType << "<br />";
  46. out << "<b>Query String:</b> " << session.queryString << "<br />";
  47. out << "<b>Cookies:</b> " << session.cookies << "<br />";
  48. out << "<b>Root:</b> " << session.root << "<br />";
  49. out << "<b>Script Name:</b> " << session.scriptName << "<br />";
  50. out << "<b>Content Length:</b> " << session.contentLength << "<br />";
  51. out << "<b>Keep Alive Time:</b> " << session.keepAlive << "<br />";
  52. out << "<b>Server Address:</b> " << session.serverAddress << "<br />";
  53. out << "<b>Server Port:</b> " << session.serverPort << "<br />";
  54. out << "<b>Client Address:</b> " << session.remoteAddress << "<br />";
  55. out << "<b>Client Port:</b> " << session.remotePort << "<br />";
  56. out << "<b>If Modified Since:</b> " << session.ifModifiedSince << "</p>";
  57.  
  58. //regex um das Argument q aus dem query String zu parsen
  59. std::wstring query_q_matcher= L"(.*)q=([^&]+)(.*)";
  60. boost::wregex query_q_exp(query_q_matcher);
  61.  
  62. std::wstring q(session.queryString);
  63. boost::wsmatch matches;
  64. //wenn der Ausruck matcht
  65. if(boost::regex_match(q, matches, query_q_exp))
  66. {
  67. //gebe ihn aus
  68. std::wstring pattern = std::wstring(matches[2]);
  69. out << "<h1>" << "pattern is: " << pattern;
  70. }
  71.  
  72. //statt dem eigenen log kann auch das Apache-errorlog verwendet werden
  73. err << "Hello apache error log";
  74.  
  75. return true;
  76. }
  77. };
  78.  
  79. int main()
  80. {
  81. try
  82. {
  83. Fastcgipp::Manager<SimpleFcgi> fcgi;
  84. fcgi.handler();
  85. }
  86. catch(std::exception& e)
  87. {
  88. error_log(e.what());
  89. }
  90. }

Dieser Beispielcode sollte mit

g++ -lfastcgipp -lboost_regex -lboost_thread -O2 -o simple.fcgi simplefcgi.cpp
kompiliert werden können.

Wer möchte, kann es auch direkt hier ausprobieren: http://cgi.pastacode.de/simple.fcgi?lala=schwupp&q=dasistq&u=nochwas

Ich hoffe das der Code einigermaßen selbsterklärend ist. Trotzdem eine kleine Erklärung des Beispiels: Für Fastcgipp benötigt jedes Programm eine Klasse, die Fastcgipp::Request<...> implementiert. Die Funktion bool response() wird bei jedem Request aufgerufen. Im unterschied zu CGI oder PHP, ist die Lauftzeit eines Programms nicht durch einen Request bestimmt, das Programm läuft immer. Es können also auch wichtige Inhalte bei Start der Applikation in den Speicher geladen werden, sodass sie bei jedem Request sofort bereitstehen. Da von der Klasse Fastcgipp::Request gerbt wird, steht ein Stream out bereit und intern wird mit wchar_t gearbeitet, was Unicode unterstützung für diesen ermöglicht. Um auf das Apacheerrorlog zuzugreifen, kann err verwendet werden.

Um sich weiter mit der Materie zu beschäftigen, führt natürlich kein Weg an http://fastcgipp.com/doc/ vorbei.

One Comment

  1. Pastacode Relaunch…

    Mein Komilitone Benni hat nun auch wieder angefangen zu bloggen. Und er legt direkt ziemlich los und schreibt von Web-Development in C++, Openfire unter Linux aufsetzen und Firefox Performance.
    Dann wünsche ich Benni doch mal viel Erfolg!
    Güße,
    Zoki…

Leave a Reply