Monthly Archives: Dezember 2009
REST, WCF (Windows) und PHP (Linux/Apache2) mit JSON Kodierung – Teil 1
Dezember 22, 2009 in Development, Tutorial von SeveQ
Ich habe einige Zeit gesucht, bis ich die richtigen Antworten hatte. Aber auf welche Frage? Nun, wie lasse ich eine in C#/.NET3.5 entwickelte Anwendung mit einem Webserver kommunizieren, ohne die ganze Kommunikationsschicht selber bauen zu müssen? Die kurze Antwort darauf lautet: WCF, REST und JSON. Die lange Antwort möchte ich hier nun auch in Form eines Tutorials geben.
Im ersten Teil dieses Tutorials werde ich die Erstellung eines REST Services unter PHP erklären. Der zweite Teil folgt später und wird die Erstellung eines Clients in C# beinhalten.
Kurzer Exkurs zu REST (vereinfacht)
Was ist denn REST überhaupt? REST ist die Abkürzung für Representational State Transfer. Es ist eine Spezifikation für die Kommunikation mit Diensten in sogenannten Hypermedia-Informationssystemen wie das World Wide Web. Die Kommunikation findet dabei über HTTP statt. Aufrufe von Funktionen REST implementierter Dienste werden dabei in der aufgerufenen URL kodiert. Beispielsweise sieht die URL für den Aufruf einer Funktion namens “foo” möglicherweise folgendermaßen aus: http://www.meinserver.de/rest/foo
Aufrufparameter, sofern erforderlich, werden dabei im Inhalt des HTTP Requests übermittelt. Aus diesem Grund sollten serverseitig Funktionen, die Argumente erfordern, so implementiert sein, dass sie über die HTTP Methode “POST” (statt standardmäßig “GET”) erreicht werden. Näheres dazu weiter unten. Man kann Aufrufparameter auch über die HTTP Methode “GET” übermitteln, sie landen dann in der URL in der Form
<url>?parameter1=wert1¶meter2=wert2
und so weiter. Ist im Endeffekt Geschmackssache, wirkt sich aber auf die Implementierung sowohl der Funktion serverseitig als auch des Interfaces clientseitig aus. Ich beschreibe in diesem Blogpost nur die Vorgehensweise bei der Implementierung mit HTTP Methode POST für Funktionen mit Parametern (ohne Parameter ist eigentlich immer GET).
Wer ist dieser JSON?
JSON (JavaScript Object Notation) ist eine Syntax, mit der Daten, Objekte, Variablen in Textform über beispielsweise das Web übermittelt werden können. Näheres dazu findet man bei Wikipedia. Das Format selber ist für dieses Tutorial nicht wichtig, da WCF und PHP so gut wie alles selber machen und hier auch mal sehr kompatibel erscheinen.
Den Apache vorbereiten
Damit wir überhaupt mit REST arbeiten können, müssen wir dem Apache noch sagen, dass er alle Anfragen, die auf nicht existierende Dokumente führen, auf eine PHP Datei umlenken soll. Standardmäßig wird das die index.php sein. Um ihm dies zu sagen, benötigen wir im Document Root der Webanwendung eine Datei namens “.htaccess”. Diese muss folgendes beinhalten:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-lRewriteRule .* index.php [L]
Außerdem muss das Modul mod_rewrite aktiviert sein. Näheres dazu kann man aber auch ergooglen. Was macht nun diese Datei? Sie sagt dem Apache, dass alles (“.*”), was nicht (“!”)
- eine existierende Date (“-f”)
- ein existierendes Verzeichnis (“-d”)
- ein existierender Symlink (“-l”)
ist, auf die index.php umgelenkt werden soll. Außerdem aktiviert es in der ersten Zeile die Rewrite Engine natürlich.
Der REST Server
Als REST Server verwende ich eine PHP Anwendung auf einem Apache/Linux System. Ein REST Server ist relativ schnell implementiert. Wir brauchen eine Weichen-Funktion, die bei jedem Aufruf des PHP Dokuments (ich verwende hier ausschließlich die index.php; andere Namen sind natürlich möglich, dann muss aber der Eintrag in der .htaccess Datei entsprechend angepasst werden) ausgeführt wird:
<?php function RESTServer() { $callback = NULL; if(preg_match('/rest\/([^\/]+)/', $_SERVER['REQUEST_URI'], $m)) { if(isset($GLOBALS['RESTmap'][$_SERVER['REQUEST_METHOD']][$m[1]])) { $callback = $GLOBALS['RESTmap'][$_SERVER['REQUEST_METHOD']][$m[1]]; } } else { return FALSE; } if(is_callable($callback)) { $data = NULL; if($_SERVER['REQUEST_METHOD'] == 'GET') { $data = $_GET; } else if ($tmp = file_get_contents('php://input')) { $data = json_decode($tmp); } header("{$_SERVER['SERVER_PROTOCOL']} 200 OK"); header('Content-Type: application/json'); print json_encode(call_user_func($callback, $data)); } else { header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found"); } return TRUE; } ?>
Diese Funktion wird bei jedem Aufruf des Dokuments ausgeführt. Sie holt sich die aufrufende URL (wie oben erwähnt: aufgrund der Umleitung in der .htaccess Datei landet jeder Aufruf, der nicht direkt ein existierendes Dokument anspricht, auf der index.php) und extrahiert daraus, sofern in URL und auch in der Function-Map (siehe weiter unten) vorhanden, die aufgerufene REST Funktion. Stimmt die URL nicht mit der Konvention “<url>/rest/function” überein, so kehrt die Weichen-Funktion mit einem FALSE zurück. Hat die URL jedoch das entsprechende Format, so schaut die Funktion in die Function-Map, ob sie zur HTTP Methode und zum Funktionsnamen einen Eintrag findet. Konnte in der Function-Map kein entsprechender Eintrag gefunden werden, so sendet die Weichen-Funktion ein HTTP 404 (nicht vorhanden) an den Client, der entsprechend reagiert.
Die Function-Map
Was aber ist nun diese ominöse Function-Map? Im Grunde ist es nichts anderes als ein mehrdimensionales Array, das folgendermaßen aussieht:
<?php /******************************************************************************** REST function mappings for access via HTTP GET method *********************************************************************************/ $GLOBALS['RESTmap'] = array(); $GLOBALS['RESTmap']['GET'] = array( ); $GLOBALS['RESTmap']['POST'] = array( ); $GLOBALS['RESTmap']['PUT'] = array( ); $GLOBALS['RESTmap']['DELETE'] = array( ); ?>
Wir legen also eine globale Variable mit dem Namen RESTmap als Array an. Sie erhält vier Einträge, jeweils einen für die entsprechende HTTP Aufrufmethode GET, POST, PUT und DELETE. PUT und DELETE lasse ich außen vor, beziehe mich in diesem Text nur auf GET und POST.
Jeder Eintrag des Arrays ist wiederum selbst ein assoziatives Array (d.h. mit Namen als Index, statt Nummern). Um nun eine PHP-Funktion beispielsweise mit dem Namen “get_Foo” über REST erreichbar zu machen, muss man sie folgendermaßen in diese Map eintragen:
<?php $GLOBALS['RESTmap']['GET'] = array( 'foo' => 'get_Foo', ); ?>
Ein Aufruf der URL “http://blahblubb/rest/foo” führt also nun dazu, dass eine PHP-Funktion namens get_Foo aufgerufen wird. Ihr Rückgabewert wird in JSON kodiert an den Aufrufer zurückgegeben. Man muss also dafür sorgen, dass die Daten, die man gerne clientseitig verarbeiten würde, in Form eines Objektes oder eines Arrays oder einer Variablen per return zurückgegeben werden. Die Kodierung übernimmt unsere oben beschriebene Weichen-Funktion. Eine beispielhafte Implementierung der foo-Funktion:
<?php function foo() { return "Hallo Welt!"; } ?>
PHP kodiert den Rückgabewert dann am Ende der Weichen-Funktion in einen JSON Term und sendet ihn an den Client zurück (ein Browser würde ihn also anzeigen oder eventuell, aufgrund des Content-Types, auch als Download anbieten; jedenfalls reagiert mein FireFox mit einem Downloadfenster auf solch eine Antwort).
Soweit zum serverseitigen Teil der Verbindung.
Die Implementierung des Clients folgt in Teil 2
Faulheit vs. Effizienz
Dezember 20, 2009 in Waste, Wir von SeveQ
Ich werde von einigen Menschen in meiner Umgebung häufig als faul bezeichnet. Ich behaupte hingegen eher, das meiste, was auf den ersten Blick nach Faulheit aussieht, ist eher Effizienz. Daher möchte ich gern mal den Unterschied zwischen Faulheit und Effizienz darlegen, wie ich ihn sehe:
Faulheit
Jemand ist faul, wenn er eigentlich erforderliche Tätigkeiten auslässt, weil er weiß, dass andere sie sowieso irgendwann an seiner statt erledigen werden müssen.
Beispiel:
*hust*
Effizienz
Jemand ist effizient, wenn er Tätigkeiten auslässt, die zum Erreichen eines Ziels nicht zwingend erforderlich sind, oder Tätigkeiten (auch nur Teilschritte auf dem Weg zu einem Ziel) speziell dafür gedachten Geräten, Maschinen (oder unter Umständen auch dafür bezahltem Personal) überlässt.
Beispiel: warum soll ich mich stundenlang in die Küche stellen, Teller, Tassen, Gabeln, Messer einzeln von Hand abwaschen, wenn ein Geschirrspüler diese Aufgabe genau so gut ohne mein Beisein und sogar energieeffizienter (siehe Link) erledigt?
In der Zwischenzeit kann ich gut andere Dinge erledigen. Faulenzen zum Beispiel. Oder Toilettenpapierrollen wechseln.
Namespacing bei E-Mail Adressen
Dezember 17, 2009 in Anleitungen, Development, Sicherheit, Web von SeveQ
Fefe brachte mich darauf, dass man bei sendmail Namensräume für E-Mail Adressen verwenden kann. Das sieht dann so aus:
Eine Mail an diese Adresse würde bei einem solchen Server an blahblubb@meinsendmailserver.de weitergegeben. Das hat den Vorteil, dass man damit quasi “markieren” kann, wofür man eine solche Mail-Adresse verwendet hat. Man kann damit leicht ermitteln, wer die verwendete E-Mail-Adresse weitergegeben hat, wenn man darauf auf einmal Spam empfängt (man sieht’s dann ja im “To:”-Header). Voraussetzung dafür ist natürlich, dass
1. der Betreiber der Webseite, bei der man sich damit registriert hat, den Namensraum bei der Weitergabe drin behält, respektive der Bot, der die Adressen ab sammelt, diesen nicht automatisch entfernt und
2. das Registrierungsformular der jeweiligen Webseite solche Mail-Adressen akzeptiert
Letzteres ist leider oft nicht der Fall, wie ich leidlich feststellen musste. Darum mein Aufruf an alle Webseitenbetreiber und Entwickler von Content Management Systemen und anderen Frameworks, wo man sich registrieren kann: lasst in euren Registrierungsformularen Namensräume zu, um zur Eindämmung von Spam beizutragen!
“NCP Filter” legt Netzwerk lahm [NCP Secure Entry]
Dezember 16, 2009 in Computer, Studium, Wir von SeveQ
Ich hab seit ein paar Tagen auf meinem Windows 7 64bit System den NCP VPN Client “NCP Secure Entry” installiert, damit ich auch auf diesem Gerät in ein Cisco VPN reinkomme. Erstmal nur die Testversion, um zu schauen, ob sich die Software lohnt. Anfänglich funktionierte diese Software auch gut, abgesehen davon, dass sie mir immer das Standard-Gateway verbog, wenn ich ins VPN eingewählt war.
Tja, und nun streikte seit gestern Abend mein Netzwerk vollständig. Angeblich, laut Fehlermeldung, konnte der IP-Stack nicht automatisch mit dem Interface verbunden werden. Ich habe alles mögliche ausprobiert, von automatischer Windows Reparatur, Treiberneuinstallation über Installation eines AVM WLAN USB Sticks als alternative Netzwerkschnittstelle, bis hin zu
C:\> netsh int ip reset reset.log
Aber nichts half. Auch ipconfig zeigte mir nichts. Im Wortsinn “nichts”. Es kam keine Ausgabe. Gar nichts!
Dann kam ich auf die Idee, doch mal in der Schnittstellenkonfiguration alles abzuschalten, was nicht unbedingt benötigt wird. QoS, Dateifreigabe und unter anderem eben auch den Eintrag “NCP Filter”. Und siehe da, auf einmal funktioniert alles wieder.
Fazit also bezüglich NCP VPN Client “NCP Secure Entry”: ich persönlich lasse lieber die Finger davon.
Löschtrolle bei YouTube?
Dezember 16, 2009 in Computer, Web von SeveQ
In letzter Zeit stolpere ich immer wieder über gute Berichte zu Computerspielen, zu neuer Hardware oder anderem. Nichts ungewöhnliches, würde ich behaupten, wären da nicht die von YouTube eingebetteten Videos. Jaja, okay, auch nix neues… aber in immer mehr Fällen kann ich diese eingebetteten Videos nicht anschauen. Immer wieder heißt es, das Video wäre aufgrund einer Rechteverletzung entfernt worden, der Benutzer habe es ohne Angabe von Gründen entfernt oder es wäre wegen eines Verstoßes gegen die Nutzungsbedingungen entfernt worden. Das ist ärgerlich, das nervt. Kann man da nichts gegen unternehmen?
Ich würde ja vorschlagen, für Videos, die möglicherweise bei YouTube demnächst entfernt werden, auch andere Video-Hoster in Betracht zu ziehen oder die Videos für HTML5 codiert auf dem eigenen Server zu lagern. Letzteres setzt natürlich entsprechende Bandbreite voraus.
Auf jeden Fall hab ich das Gefühl, dass sich diese Problematik häuft. Haben die Wikipedia-Löschtrolle inzwischen auch YouTube okkupier?
Fanboy, aber nicht uneingeschränkt…
Dezember 8, 2009 in Die Welt, Öffentlichkeit, Politik, Web von SeveQ
Also ich finde ja gut, was Microsoft momentan so an Software auf den Markt wirft. Das hat alles irgendwie doch Hand und Fuß. Windows 7 ist klasse geworden, das .NET Framework sucht meines Erachtens seinesgleichen vergeblich, Silverlight ist in meinen Augen das bessere Flash und an der Office Suite führt für vernünftiges Arbeiten mit Dokumenten, Daten und Briefen auch kaum ein Weg so wirklich dran vorbei. Open Office, okay, hab ich mir lange nicht angesehen. Aber am Markt etabliert hat sich nun mal die Software aus Redmond. Da beißt die Maus keinen Faden ab.
Aber!
Ich als MS-Produkte-Fanboy distanziere mich entschieden von der Darstellung, das Internet sei ein einziger Hort von Kriminellen, die sich nicht an Recht und Gesetz hielten.
Natürlich gibt es im Web kriminelle Subjekte, wie auch im richtigen Leben. Das liegt einfach in der Natur der Sache: das Internet wird fast ausschließlich von Menschen genutzt und es gehört zur Natur des Menschen, dass seine Handlungsbandbreite auch immer kriminelle Handlungen beinhalten wird. Das wird immer und überall so sein, wo viele Menschen agieren. Daran kann man nichts (!) ändern. Gesetze helfen vielleicht, Auswüchse einzudämmen, aber verhindern werden sie sie niemals. Leider beinhaltet die Natur des Menschen auch, dass es beratungsresistente und erkenntnisimmune Individuen gibt, die ihre eigene Art nicht verstehen und nicht akzeptieren wollen, dass der Kampf gegen Kriminalität ein Kampf gegen Windmühlen ist.
Regeln sind gut, daran zweifle ich nicht. Zu viele Regeln bewirken aber genau das Gegenteil von dem, was sie eigentlich bewirken sollen und schaden letztendlich nur noch der gesellschaftlichen Entwicklung. Das Patent- und das Urheberrecht zum Beispiel verlangsamen massiv den technologischen und wissenschaftlichen Fortschritt, weil jede Erfindung, jede Entdeckung erst einmal auf ihre rechtliche Unantastbarkeit überprüft werden müsste. Da dies unmöglich ist, laufen immer wieder Wissenschaftler und Erfinder in die Abmahnfalle von Patenttrollen. Auf der anderen Seite begünstigen derartige Regeln sogar kriminelle Machenschaften anderer Art: dem Ausschlachten von teils sogar versehentlichen und unbewussten Rechteverletzungen Dritter in Form von Abmahnungen in utopischer Höhe. Dieser Abmahnwahnsinn ist nur durch ein überaltertes Urheberrecht überhaupt erst möglich. Und eigenartigerweise trifft es (fast) immer nur den kleinen Mann. Das Urheberrecht in der heutigen Form schützt keine Existenzen, es vernichtet sie.
Vielleicht ist das alles aber auch gewollt. Dass das Internet Teilen der Regierungen vieler Länder ein Dorn im Auge ist, ist nur zu verständlich, denn das Internet kostet sie Macht, die es auf der anderen Seite den Menschen am unteren Ende der Macht-Leiter wieder gibt. Es fördert den demokratischen Gedanken, es fördert Basisdemokratie und untergräbt die Autorität der etablierten Mächte und Eliten. Kein Wunder, dass man das irgendwie unterbinden und regulieren muss und will, wenn man es irgendwie kann. Auch das ist leider ein Teil unserer Natur: Machtgier. Vielleicht ist das Abmahnwesen ein gutes System, um unliebsame (staatskritische) Subjekte auf einfache Weise beiseite zu räumen. Ein Staatsfeind wird nicht mehr körperlich liquidiert, sondern existenziell (Abmahnung) und gesellschaftlich (Pädophilie). Ist viel einfacher und viel effektiver.
Leider gibt es nun auch solche, die aus Profitgier andere in ihrer Machtgier unterstützen. Peinliche Aktion, liebe “Microsoft-Deutschländer”. Peinliche Aktion, wirklich!


