Sending files through Apache with mod_xsendfile

If you ever wanted to serve big or many files through PHP and needed to check permissions or do any other calculation upfront file delivery, you might want to think about an Apache module called mod_xsendfile. With it you’re able to separate permission checks and other script related stuff from the slow part of file delivery in which PHP is not best at.

And getting it up and running is pretty simple.

a2enmod xsendfile
apache2ctl restart

Now, in your virtual host configure your host to pick up the module and maybe define a folder wich the module is allowed to send files from.

#enable the module for your host
XSendFile On

#define a white list folder outside your DocumentRoot
XSendFilePath /some/path/outside/my/docroot

That’s it on the Apache side of things.
Now, simply tell Apache to handle the file transfer itself in your script. This is done by sending the X-Sendfile-Header. No more needs to be done. No file reading, nothing. The whole delivery is being delegated to Apache.

//some code to check permissions, get the file name, rescue the world or whatever
//...
header('X-Sendfile: '.$absolute_path_to_file);
header ('Content-Type: application/octet-stream');
header ('Content-Disposition: attachment; filename='.$some_file_name );
exit();

And that’s it. Now all your validation stuff will be done by PHP while file delivery is done by Apache.

Werbespots auf Newsseiten: Ihr nervt.

Mittlerweile überlege ich mir echt zwei mal, ob ich ein Video auf spiegel.de oder anderen Seiten anklicke und schaue. Die Videos dort sind sehr kurz und sind sie nicht interessant, bin ich nach einigen Sekunden der Langeweile wieder weg, muss mir aber vorher in jedem Fall einen Werbespot anschauen.

Und diese Spots sind lang:

25-30 Sekunden Werbung bei 2:30 Minuten Video. Das sind 20% Werbeanteil! So ist das bei Spiegel und eigentlich anderen allen Newsseiten. Schrecklich frustrierend und die Message des Werbenden landet so sicher auch nicht beim User. Bei Spiegel etc. nervt es nur – zumal hier auch scheinbar nur die Spots zum Einsatz kommen, die auch im TV ihre Anwendung finden: Dort ist der Anteil an Werbung mit Sicherheit prozentual auch nicht geringer. Aber gemessen an der Länge des Programms im Internet – nämlich einem 2:30 Minuten langen Film – finde ich die Spots im Web wirklich lästig. Und lästige Werbung kommt nicht an. Sie frustriert.

Videos auf spiegel.de: Immer mit langer Werbung
Videos auf spiegel.de: Immer mit langer Werbung

Da muss es doch bessere Formate geben. Youtube macht es ja vor – der User kann nach 5 Sekunden die Werbung wegklicken. Ist der Spot also nicht “catchy” genug, ist er nicht lustig, bietet er nicht sofort Mehrwert, ist der User weg. Das ist ein klarer Appell an die Produzenten von Werbung: Macht mitreißende Dinge, die in fünf Sekunden die Aufmerksamkeit der User erlangen.

Wer sagt denn, dass ein Spot 30 Sekunden lang sein muss? Es muss doch möglich und auch im Interesse der Werbetreibenden sein, spezielle kurze Spots (kürzer als 10 Sekunden) für das Web zu drehen. Hier sind doch auch die großen Agenturen vertreten: Warum gibt es nicht eine kurze Variante eines Spots für das Web? Das kann doch so teuer nicht sein – das Budget für das Storyboard ist doch schon da für die Produktion im TV.Hier noch eine Web-Variante mitzudenken, die am Ende viel prägnanter für den User ist und ihn nicht frustriert vor seinem Screen warten lässt, muss doch denkbar sein. Das würde doch viel größere Akzeptanz schaffen.

Kurze Spots ließen sich auch sehr viel eher noch hinter ein Video schalten: Erst bekommt der User den Content, dann die kurze und knackige Werbung. Bei viel geklickten Videos, die bis zum Schluss geschaut werden, wird das sicher funktionieren. Oder sogar als “Interstitial” mitten im Video. Wäre die Werbung von zehn Sekunden Dauer und das Video vielleicht fünf Minuten lang, wäre das doch auch erträglich und die Absprungquote der User mit Sicherheit geringer.

 

Don’t offer me what I already own.

We moved to a new apartment about 8 weeks ago. During that time we had to buy a lot of new stuff for our kitchen. Of course, I started searching on the internet. As always I started looking around on amazon.com: I searched for a dish washer and a new stove. For about a week I was focused on searching products, comparing prices and making decisions. In the end, I really ordered a dish washer at Amazon (it really was a good deal and the service of delivering and setting it up was great). But what really annoys me is what happens since then:

I get bothered with emails. Advertising emails by Amazon offering me dish washers and stoves. 8 weeks after this product information was relevant to me, Amazon still tries to sell that stuff to me. This is not really a useful offer. If Amazon would analyze my order history right, they would easily recognize, that I already bought a dish washer. From the day on I ordered it, my interest  in getting further offers is abruptly gone. Amazon should know as I ordered the product at their store. I presume there are few people on the planet willing to buy dish washers in that high frequency.

Wouldn’t it be easy to guess what’s right?

But it would be so easy to guess what would grab my attention: From the day they delivered my dish washer (the delivery date is stored in my Amazon account), Amazon could have treated me with other stuff. They could anticipate that -since I’m now able to clean my dishes- I could be interested in

  • buying new dishes! They could send me an offer regarding new dishes, cups, wine glasses or whatever
  • cooking! They could send me an offer regarding cookbooks, cooking accessories or other cooking related items
  • decoration! While setting up new kitchen equipment: Why not freshen up my kitchen style?

Instead, Amazon wants to sell even more dish washers and stoves. And that’s the problem with all the advertising on the internet. Advertising companies just follow one basic thought:

What was interesting yesterday, is relevant today. What I bought yesterday, will be bought by me tomorrow. While this is absolutely true for most of the stuff I buy and consume, this is completely false for most of the stuff I buy on the internet – especially regarding Amazon.

If I buy a rucksack, don’t offer me more rucksacks the days after. Please go ahead and offer other outdoor related items.

If I buy a new jacket, don’t offer me other jackets. Offer me other clothes in similar colors or style.

While looking at my 3 year order history at Amazon, I can find so many things that describe my style, taste and interest. Thinking about it, it appears to me that it should not be too difficult to analyze that data right. At least there must be a way of generating better offers than dish washers or stoves.

Anticipating systems

The fact that even Amazon seems to not get it done quite right, shows the fact, that there still is so much research and work to be done to get really useful offers based on personal consumption history and anticipated data. Amazon does not have access to my Facebook account (at least I hope so). Nevertheless the amount of data (a few hundred record sets of orders just by me) already seems to too complex to generate high-performance personalized offers. So, they offer what might be most relevant: The stuff I looked for or bought weeks ago. But Amazon has the right data to do it better: While searching for products in their web store, I get Information about related stuff. This information is still poor sometimes but there obviously is a way to relate products. And that is the information Amazon should aggressively use for their product newsletter.

But in future there is more to be done. The ideal way would look something like this (let’s not look at data protection issues): My Amazon account is linked to my Facebook account and some wearable device collecting data about nutrition, sports or location. These three key information (data of social networks, consumption history and personal tracking data of multiple kind) should lead to really useful digital products as well as really useful personalized offers. Anticipating systems that tell me what I might need in a certain situation. Big data. Big challenges.

Until then, dear Amazon, I’d be glad to have just a simple solution: Please (please, please!) send me offers to related products and not the same products I bought. That would be really helpful.

tintencenter.com kann es nicht.

28. Juli 2013 – Update: Offenbar gibt es schon wieder Fishingmails, scheinbar von Tintencenter.com – Google Analytics nach kamen seit gestern hunderte Besucher über Google auf diesen Post. Was sind Eure Erfahrungen mit Tintencenter.com?

*

Dass es immer wieder Datenlöcher gibt und irgendwelche Kriminellen an meine Daten kommen, ist leider fast schon Alltag geworden. Was sich aber dringend ändern sollte, ist die Art und Weise, mit der Unternehmen mit ihrem Verlust und dem ihrer Kunden umgehen: Meist ist das nur enttäuschend und erst das Ignorieren des Problems sorgt dafür, dass Phishing erst zum Erfolg werden kann.

Am Samstag erhielt ich eine E-Mail von tintencenter.com – da diese durch meinen Spamfilter bei Gmail rutschte, war ich echt irritiert: Da standen meine kompletten Adressdaten drin und Daten über eine angebliche Bestellung, die ich aufgegeben hätte. Als Informatiker bin ich immun solchen Anfragen gegenüber – eigentlich. Aber ich hatte es eilig, meine Daten stimmten und der Link in der Mail sah auf einen flüchtigen Blick hin auch gut aus. Ich bin also auf die Seite und wollte mich einloggen. Erst da merkte ich, dass ich Phishing aufgesessen bin. Naja, das war der Anlass, endlich mal wieder alle Passwörter zu ändern.

Ich habe die Email sofort an tintencenter.com weitergeleitet und darum gebeten, mein Benutzerkonto umgehend zu löschen.

Nach einem Tag bekam ich folgende Antwort:

Sehr geehrter Kunde,
sehr geehrte Kundin.

Sie haben von uns eine Auftragsbestätigung bzw. Versandbestätigung mit der
Nummer 2011145121 erhalten, welche angeblich von uns versendet wurde.

>>> Diese E-Mail ist NICHT von uns versendet worden. <<<

Leider sind wir in jüngster Vergangenheit Opfer eines Angriffes geworden,
bei dem der Angreifer durch eine bis dato unbekannte Sicherheitslücke des Shops
teilweisen Zugriff auf die Kundendaten hatte. Die Sicherheitslücke wurde von
uns schnellstmöglich geschlossen, bedauerlicherweise sind aber einige Daten in
die Hände des Angreifers gefallen. Dabei handelt es sich um die E-Mailadresse
sowie Ihre zu dem Zeitpunkt hinterlegte Liefer- bzw. Rechnungsanschrift.
Dadurch ist es dem Angreifer nun möglich täuschend echte Auftragsbestätigungen
in unseren Namen zu verschicken, welche persönliche Daten von Ihnen enthält.
Das Ziel des Angreifers ist es, dass Sie auf die Links klicken, die in der
E-Mail enthalten sind, um Ihnen Schadsoftware auf Ihren Computer zu installieren.

>>> Daher klicken Sie bitte NICHT auf die in der E-Mail enthaltenen Links! <<<

Natürlich ist es zu keiner Bestellung Ihrerseits gekommen. Wir werden auch
keine Ware versenden oder Ihnen irgendeinen Betrag in Rechnung stellen! Auch
war es dem Angreifer nicht möglich, Kontodaten oder Kreditkartendaten zu bekommen!

Wir werden selbstverständlich den Vorfall zu einer Anzeige bei der Polzei bringen,
allerdings zeigt die Vergangenheit bei dieser Art Vorfällen, dass die Erfolgsaussichen
gering sind, zumal die Angreifer bzw. die Versender dieser E-Mails im Ausland sitzen
oder gehackte Server benutzen um z.B. die E-Mail zu versenden. Natürlich setzen wir
alles daran den Versand dieser E-Mails zu unterbinden
sowie die Abschaltung der Domain zu veranlassen.

Leider kann es vorkommen, dass Sie in Zukunft erneut eine E-Mail mit der gleichen Auftragsnummer
oder Spam-Mails von angeblichen Vergleichsportalen (sogn. Krankenkassenspam) erhalten.
Diese können Sie dann ungesehen löschen.

Wir entschuldigen uns für diesen Vorfall sowie die damit verbundenen Unannehmlichkeiten.

Mit freundlichen Gruss,
Team Tintencenter

Aha, eine Datenpanne, wenigstens entschuldigten sie sich. Aber was macht tintencenter.com aktiv? Die Firma wartet scheinbar, bis die Kunden selbst sich melden, statt offensiv mit dem Problem umzugehen und ihre Kunden anzuschreiben. Erst so gelangen selbst “professionelle” Surfer wie ich auf eine Phishingseite und geben ihre Zugangsdaten ein.

Noch dazu geht tintencenter.com scheinbar nicht einmal jetzt, zwei Tage später, technisch gegen die Betrügerei vor: Sogar jetzt, nachdem es zwei Tage her ist, dass ich bei tintencenter.com meinen Vorfall eingereicht habe, gelange ich von der Phishingseite und dem angeblichen Loginformular auf die originale Website, welche keinen Hinweis beinhaltet, dass ich unter Umständen von einer kriminellen Seite zu tintencenter.com gelangt bin. Dabei wäre dies technisch eine Sache von Minuten. Bei Twitter melden sich mittlerweile weitere enttäuschte Kunden.

Nachdem ich auf die Antwort von tintencenter.com gestern Abend erneut darum bat, mir zu bestätigen, dass mein Account gelöscht sei und mich bei der Gelegenheit über die Kommunikation beschwerte, bekam ich heute eine Antwort, dass mein Account entfernt wurde. Vertrauen ist gut, Kontrolle ist besser. Scheinbar klappt selbst das nicht: Ich komme immernoch rein. tintentcenter.com = fail.

Testing using the Robot Framework.

I recently came across a testing framework called Robot. It allows easy creation of test tables using a simple keyword-driven syntax. The test-cases are stored in simple CSV/TSV files which allow easy creation by even non-technical staff. A really nice feature is a test library for Selenium which may be installed along Robot. This makes testing web GUIs (HTML and according to the docs Flash/Flex) a treat. You may use another library called Ride to maintain, edit and run tests from a nice and simple GUI or you might consider using command line tools to integrate Robot into CI tools.

Robot Framwork and Selenium- test automation

Installing Robot, Ride and Selenium

This is a description and basic tutorial to install Robot on a Ubuntu machine. To install a web-test setup for Robot do the following:

1. Refer to the following sites and download the latest versions:

Robot Framework
http://code.google.com/p/robotframework/

Ride GUI
http://code.google.com/p/robotframework-ride/

Selenium Plugin
http://code.google.com/p/robotframework-seleniumlibrary/

2. Extract and Copy: Once downloaded, extract and copy all folders to a folder called e.g. /opt/dev/robot

3. Install Robot and all libraries: In each folder run

sudo python setup.py install

4. Start GUI – run the following script to start creating tests:

ride.py

Components in Robot

Tests in Robot are organised in

  • Folders containing
  • Test Suites containing
  • Test Cases, User Keywords, Scalars, List Variables

Keywords are commands used to trigger events. Using Selenium this might be accessing a website, clicking a specific button etc.. User keywords are powerful way to create your own re-usable test commands based on a set of defined keywords. You are allowed to parameterise your user keywords. Great stuff!

Scalars may be understood as variables such as URLs or default parameters passed to web forms e.g.

Setting up a test environment

We now want to create a simple test suite which visits Google.com, searches for Robot Framework and checks if results exist. Before we set up all basic test components we need to define a constant value for the Google URL. To do so, right click on Resources and select New Scalar. Enter ${GOOGLEURL} for name and http://www.google.com as Value.

Creating a Test Suite

Setting up a basic test suite which loads up Google:

1. Click on File -> open Folder, create a new one and give it the name “Google”

2. Right Click on the folder and select “Add Suite”. Give it the Name “Google Test”

3. Right Click on the Suite and create three test cases: Initial, Load Google, Finally

Now, your setup should look something like this:

Test Setup in Ride

Loading Resources and Libraries
First we will add the Selenium Library: Click on the Google Test Suite and choose Add Library on the Edit Tab. Here you’ll need to enter the path to the Selenium library. In my case this is

/opt/dev/robot/robotframework-seleniumlibrary-2.7/src/SeleniumLibrary

Then we will add our recently created GOOGLEURL Scalar to the suite. Click Add Resource and enter the path to the constant file. If you do not want to remember and type the whole path, you might want to head back to the constants file, copy the path and paste it in here. Now, we’re ready to create our simple test!

Creating a simple test

Now, we’re going to create our basic testing. Therefore I’m going to use a number of keywords implemented in the Selenium library. A documentation about these keywords may be found here: http://robotframework-seleniumlibrary.googlecode.com/hg/doc/SeleniumLibrary.html?r=2.7 Of course you may create your own keywords.

1. We need to start the Selinum Server: The keyword to do this is – surprise – Start Selenium Server. Add this to your initial test case.

Start Selenium Server

2. Then we’re going to visit Google in Firefox:

Open Browser    ${GOOGLEURL}

3. Let’s wait until the search field is present. The id of the input field is ‘lst-ib’:

Page Should Contain Element    lst-ib

According to the Selenium Library Documentation the identifier may be the id of an element, its XPath locator etc.
4. Now fill the field with “Robot Framework”:

Input Text    lst-ib    Robot Framework

5. Wait for the page to contain “code.google.com/p/robotframework/”

Wait Until Page Contains code.google.com/p/robotframework/

We’re now ready to run the test. To do so, we hit the small brown “run” icon in the tool bar and we’ll see: it works just fine 🙂

Test successfully completed

Enhancements

Robot creates a log and report for each test-run. If a test fails, a screenshot is being created and integrated into the html report. You are, of course, able to trigger the creation of screenshots or source code logging. Also, using the Wait For Condition keywords you are able to run an almost unlimited amount of JavaScript based tests on your website. Have a look at the Selenium docs – there is a huge amount of keywords to be used.

An easy to use testing tool

Robot is a nice and easy to use tool – we’re not using it to integrate into CI. We’re just running stand-alone tests. But it’s really handy when it comes to handle a huge number of test cases: For example we were testing the behaviour of search functionality of one of our websites. With robot I was able to fire hundreds of request against the search and get screenshots in return for further manual investigation. Also we’re using it to autmatically test dependencies of our content trees in huge navigational structures. For this kind of test Robot is perfectly suited.