Archiv ‘Web’

Freitag, 27. Juni 2014

.ch-Domains zu cyon transferieren

Heute schreckte mich Blogging Tom auf Facebook mit der Meldung auf, dass SWITCH/nic.ch per 1. Januar 2015 keine .ch-Domains mehr verwaltet. Bis spätestens zu diesem Stichdatum müssen .ch-Domains zu privaten schweizerischen Anbietern gezügelt werden.

Ich besitze ein halbes Dutzend .ch-Domains und lasse diese bereits alle auf meinen Shared Server bei der Cyon GmbH in Basel zeigen. Zum Glück hat der dortige Support in seiner Knowledgebase bereits eine bebilderte und „dubelisichere“ Anleitung aufgeschaltet, an Hand derer ich den Transfer innert 5 Minuten hingekriegt habe:

Wie kann ich meine Domain von SWITCH zu cyon transferieren?

ACHTUNG: Die ursprüngliche Google-Suche leitete mich auf folgenden Artikel, welcher diesen Spezialfall leider nicht behandelt:

Wie kann ich meine Domains transferieren?

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 20. Mai 2014

Die Tagesanzeiger-Paywall (eher: das Lehmmäuerchen) umgehen

In den letzten Monaten haben sich die Paywalls der traditionellen Zeitungen im Internet gehäuft: Die New York Times macht, die NZZ auch – und seit kurzem auch der Tagesanzeiger. Aus meiner Sicht war es auch wirklich an der Zeit, dass die Medienhäuser den von ihnen generierten Mehrwert entsprechend schützen und von den Konsumenten vergüten lassen. So wie man das seit Jahrhunderten in der Printpresse auch macht (wobei man anmerken muss, dass bei der Printpresse die Mehrheit der Einnahmen aus der Printwerbung stammen).

Doch wenn man eine Internet-Paywall aufbaut, welche angeblich drei Millionen Schweizer Franken gekostet haben soll, sollte sie dann aber auch der Chinesischen Mauer entsprechen, und nicht einem Lehmmäuerchen oder einem morschen Lattenzaun.

Nachdem man nämlich die maximale Zahl an kostenlosen Tagi-Artikeln gelesen hat, kriegt man die Artikelseiten weiterhin mit dem kompletten Inhalt ausgeliefert. Nach kurzer (oder längerer Ladezeit) wird mit CSS ein halbtransparenter Overlay eingeblendet, welcher den Internetbenutzer auffordert, ein Abonnement abzuschliessen.

Diese „CSS-Wall“ umgeht man unter Google Chrome folgendermassen:

  1. Stylebot herunterladen und installieren
  2. Rechtsklick auf CSS-Icon
  3. Optionen
  4. Stylebot Options
  5. Styles
  6. Edit Global Stylesheet

Dort gibt man ein:

div#overlay_wrap {
	display: none;
}

Abspeichern, Browser neu starten – et voilà!

Sollte diese Massnahme aus irgendeinem Grund nicht klappen, kann man Stylebot immer noch mittels Druck auf Alt+M aktivieren, auf die dunkle Overlay-Fläche klicken (#overlay_wrap) und im Abschnitt „Layout & Visibility“ den Wert „Visibilty“ auf „Hide“ setzen.

Tags: , , , , , ,
Labels: Web

18 Kommentare | neuen Kommentar verfassen

Donnerstag, 20. Februar 2014

YouTube-Videos ab einer bestimmten Zeitmarke abspielen

Im Grunde kann sich der gemeine Zeitgenosse die URLs selber zusammenbasteln. Doch es gibt auch eine Web-Seite, die einem die Schreibarbeit abnimmt:

YouTubeTime.com

Beispiel: Gernot Hassknechts Tirade über die EU (bei 21 Minuten und 30 Sekunden)

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 19. Dezember 2013

Hochzeit-Fotos von ichwuensche.ch automatisiert herunterladen

Heuer war es wieder mal soweit — Bekannte, welche im September 2013 geheiratet und an deren Hochzeit Stephanie und ich teilgenommen haben, haben die Fotos über ichwuensche.ch zugänglich gemacht. Da es mir zu blöd war, mich durch die 12 Web-Seiten voller Hochzeitsbilder zu klicken, habe ich mir ein kleines PHP-Script geschrieben, welches mir die URLs der Fotos generiert. Dafür benötige ich die fortlaufende Nummer des ersten sowie letzten Bildes der Serie; das Script generiert anschliessend automatisiert alle URLs.

<?php
    $base = 'http://www.ichwuensche.ch/images/gallery/';
    $start = 1269245;
    $end = 1269774;
    $suffix = '_l.jpg';
    
    $counter = 0;
    for($i = $start; $i <= $end; $i++) {
        $counter++;
        
        // $middle = 4/4/2/9/6/ if JPEG basename is 1269245
        $middle = strrev($i);
        $middle = substr($middle,0,5);
        $middle = implode('/',str_split($middle)) . '/';
        
        $url = $base . $middle. $i . $suffix;
        echo $url . "\n";
    }
    
    echo "\n" . $counter . "\n";
?>

Anschliessend führt man das Script aus, pipet die Ausgabe in eine Textdatei und lässt dann wget seine Arbeit verrichten:

$ php generate-urls.php > urls.txt
$ wget -i urls.txt
--2013-12-19 16:06:37--  http://www.ichwuensche.ch/images/gallery/4/7/7/9/6/1269774_l.jpg
Verbindungsaufbau zu www.ichwuensche.ch (www.ichwuensche.ch)|85.158.232.45|:80... verbunden.
HTTP-Anforderung gesendet, warte auf Antwort... 200 OK
Länge: 150027 (147K) [image/jpeg]
In »»1269774_l.jpg«« speichern.
...

ACHTUNG: Leider haben die Entwickler der Web-Site nicht viel überlegt: Unter den Total 530 Fotos findet sich auch die Hochzeit eines unbekannten Paares aus dem Thurgau, eine Amerika-Reise eines anderen, ebenfalls unbekannten Paares sowie die wohl fast schon obligatorischen Katzenfotos.

Umgekehrt bedeutet dies, dass ein Script-Kiddie in einer Nacht alle Fotos der Web-Site abräumen könnte. Na dann.

Tags: , , , , , ,
Labels: Web

7 Kommentare | neuen Kommentar verfassen

Mittwoch, 18. Dezember 2013

Mit cURL unter Windows das Verhalten eines Tomcat-Servers debuggen

Obwohl ich primär als IT-Auditor unterwegs bin, haben wir uns vor einigen Tagen mit einer Tomcat-basierenden Audit-Applikation herumgeschlagen. Kurz ging es darum, die Kommunikation im Intranet zwingend mit HTTPS zu verschlüsseln. Da der Server mit verschiedenen Domainnamen (teilweise nicht FQDNs) angesprochen werden kann, mussten wir Tomcat zuerst einmal so konfigurieren, dass er alle HTTP-Anfragen auf eine bestimmte Domain umleitete, falls die Anfrage nicht bereits an den korrekten Host gerichtet war (wir haben uns den UrlRewriteFilter) zu Nutze gemacht — und trauerte dabei leise dem (noch) eleganteren mod_rewrite in .htaccess Dateien unter Apache nach …

Item. Da unsere Web-Browser nicht wirklich hilfreich waren, um die Redirects zu analysieren und auch noch ein Enterprise Proxy-Server dazwischenstand, behalf ich mich mit der Win32-Version von cURL, curl.exe mit den Optionen --verbose, um den gesamten Ablauf der Verbindungsaufnahme auf der Kommandozeile auszugeben, sowie mit --noproxy *, um sicherzugehen, dass wir direkt mit dem Server sprachen und den Enterprise Proxy so umgingen. Das Resultat sah folgendermassen aus:

C:\Temp\cURL\> curl.exe --verbose --noproxy * http://software.domain.tld:8080/r2d2/asdf
* Adding handle: conn: 0x1c3def0
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x1c3def0) send_pipe: 1, recv_pipe: 0
* About to connect() to software.domain.tld port 8080 (#0)
* Trying 10.0.0.111...
* Connected to software.domain.tld (10.0.0.111) port 8080 (#0)
> GET /r2d2/asdf HTTP/1.1
> User-Agent: curl/7.32.0
> Host: software.domain.tld:8080
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Location: https://protected.domain.tld:8443/r2d2/asdf
< Content-Length: 0
< Date: Wed, 11 Dec 2013 10:35:41 GMT
<
* Connection #0 to host software.domain.tld left intact

Alles Bestens: Anfragen auf http://software.domain.tld:8080/r2d2/asdf werden auf https://protected.domain.tld:8443/r2d2/asdf umgeleitet. Und das Auditorenherz schlägt höher.

Tags: , , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 17. November 2013

Checkliste für die Aktualisierung des Profilbildes („Avatar“) auf den wichtigsten Social Media-Plattformen

Gestern habe ich am AvatarDay #5 von Pictura teilgenommen und bin so nicht nur zu einer kostenlosen Gesichtsmaske gekommen, sondern auch zu zwei netten Profilbildern (meine Facebook-Freunde werden es bereits bemerkt haben). Noch einmal ein grosses Danke an die Organisatoren für diesen tollen Anlass!

Nachfolgend eine Checkliste, um auch ja keinen personalisierten Internet-Service zu verpassen, auf welchem das Profilbild aktualisiert werden muss:

Internet-Anwendungen

  • Facebook
  • Twitter
  • Google+
  • Skype
  • Swisscom iO
  • What’s App
  • Viber
  • Last.fm
  • Foursquare
  • Gravatar
  • WordPress (resp. auf der eingesetzten Blogging-Software)

Desktop-Rechner

  • Apple Addressbook (synchronisiert sich Dank iCloud auf alle Macs und iOS-Geräte)
  • System Preferences > Users & Accounts (muss leider auf jedem Mac durchgeführt werden; sprich bei mir drei Mal)

Da ich für geschäftliche Internet-Services ein anderes Photo von mir verwende (mit Kravatte & Anzug), waren nachfolgende Web-Sites nicht relevant:

  • Xing
  • LinkedIn

Tags: , , , , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Montag, 7. Oktober 2013

Apache liefert ungefähr richtige Dateinamen aus

Ungefähr einmal im Jahr konfiguriere ich unter einer Mac OS X-Installation den lokalen Web-Server, um auf dem Gerät Web-Applikationen zu entwickeln. Und bei jedem Mal vergesse ich in der Regel, dass unter Mac OS X das Apache-Modul mod_negotiation installiert ist, welches spätestens bei der Verwendung von mod_rewrite zu komischem Verhalten führt.

Beispiel: Ich rufe im Browser die URL http://localhost/article/132 auf, welche eigentlich mittels mod_rewrite auf index.php umgeleitet werden sollte. Habe ich im DocumentRoot des Web-Servers aber dummerweise ein Script namens article.php rumliegen, wird Apache die Rewrite-Regeln nicht beachten und stattdessen article.php aufrufen.

Unter Mac OS X könnte man nun rabiaterweise einfach das Laden von mod_negotiation verhindern. Leider führt das zu neuen Problemen und Fehlermeldungen, welche ich hier aus Zeitgründen nicht ausführen möchte, weshalb man stattdessen die mod_negotiation-Funktionalität in der VirtualHost-Konfiguration für das DocumentRoot und alle darunterliegenden Verzeichnisse deaktiviert:

...
Options -Multiviews
...

Und gut is …

Tags: , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 18. September 2013

Hostpoint: Immer mal wieder zickt die Datenbank …

Irgendwann ab den frühen 2000ern habe ich alle meine Web-Projekte über das Shared Hosting von Hostpoint AG im Internet bereitgestellt, und dort sind sie in den meisten Fällen noch heute.

Spätestens seit ich diese mit eMeidi.smt laufenden Web-Sites jede Minute mit Pingdom überwache, realisiere ich, wie instabil Hostpoints Hosting ist. Verglichen mit einem an der Uni Bern gehosteten virtualisierten Root-Server (Debian und VMware ESX) und eMeidi.com, welches beim Hoster meines Vertrauens Cyon GmbH in Basel läuft, haben wir es bei Hostpoint mit einem hostingmässigen Drittwelt-Land zu tun.

Dank den vom eMeidi.smt im Dateisystem abgelegten Fehlermeldungen lässt sich rückwirkend jeweils rasch eruieren, wo denn das Problem des Pingdom-Alarms lag. Als Beispiel sei hier der Ausfall vom 13. September 2013 zwischen 8:47 und 9:23 erwähnt:

#2003: Can't connect to MySQL server on 'sekneueg.mysql.db.internal' (13) in /home/sekneueg/public_html/irgendwo/mysql.class.php:240 for URI </> with referer <unknown>

Tjach, dumm gelaufen, ne? In den letzten 30 Tagen betrug die Uptime für diese spezifische Web-Site nur 99.68%, was Ausfällen von insgesamt 2 Stunden und 21 Minuten entspricht. Die längsten Ausfälle fanden am 26. August (57 Minuten), 13. September (36 Minuten) und am 22. August (11 Minuten) statt. Erbärmlich, zumal es sich dabei nicht etwa um Wartungsarbeiten mitten in der Nacht gehandelt hat, sondern um Ausfälle während Bürozeiten.

Der Fall ist klar: Die Profis von heute hosten bei der Cyon GmbH. Da hilft es auch nichts, wenn der Ausfall-anfällige Konkurrenzhoster aus Rapperswil-Jona den bloggenden Tom anheuert – dessen Lohn (sorry, Tom!) würde man lieber in bessere und stabilere Hard- und Software stecken als unnütze Gutfühl-PR.

Tags: , ,
Labels: Web

3 Kommentare | neuen Kommentar verfassen

Freitag, 30. August 2013

Google Chrome unter die Haube schauen (und JSON lesbar ausgeben)

Hierzu haben die Google-Entwickler folgende URI erdacht:

chrome://net-internals/

Über diese Benutzeroberfläche lassen sich Daten auch im JSON-Format exportieren. Damit diese JSON-Daten auch für Menschen (einigermassen) lesbar werden, nimmt man Python zu Hilfe. Im nachfolgenden Beispiel gehen wir davon aus, dass der JSON-Dump in der Datei dump.json abgelegt ist:

python -mjson.tool < dump.json > dump-pretty.json

Tags: , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 22. August 2013

Midori auf Raspberry Pi von jQuery-Effekten entlasten

Mein Raspberry Pi, welcher ein 24″ Dashboard speist, hat sich in den letzten Tagen vermehrt aufgehängt. Dies mag mit einer Aktualisierung der Dashboard-Software zusammenhängen, insbesondere wohl mit Anpassungen am JavaScript-Code.

Ich setze jQuery als JavaScript-Framework ein und steure damit einige visuelle Gimmicks; beispielsweise schwarze Eselsohren an aktualisierten Tiles, welche innert 30 Sekunden nach der Aktualisierung verblassen und dann ganz verschwinden. Auch wird das Doppelpunkt der Zeitanzeige (HH:MM) so animiert, dass es jede zweite Sekunde ausgeblendet wird.

Dies scheint dazu geführt zu haben, dass die schwachbrüstige CPU des Raspberry Pis voll ausgelastet war. Der Browser Midori, welcher als Vollbild läuft, beanspruchte teilweise bis zu 50% CPU-Last und auch das X-Window-System wieso ähnlich hohe Werte auf. Die Load Average des Raspberry Pis war über 1.

Ich entschied mich deshalb, in den JavaScript-Code eine Weiche einzubauen, welche die grafischen Animationen für schwachbrünstige Browser/Systeme auf ein Minimum beschränkte.

Leider hatte die jQuery-eigenen Konfigurationseinstellung Kollateralschäden zur Folge, weshalb ich den Code selber optimieren musste:

jQuery.fx.off = true;

… funktionierte nicht zufriedenstellend.

Nachfolgend einige Konstrukte, die seit gestern Abend in der Produktion laufen:

Browser-Weiche

var browserIsPerformant = true;
if(navigator.userAgent.match(/(Midori)/)) {
	browserIsPerformant = false;
}

Delay statt FadeOuts

An den zwei Orten, wo ich schnelle (250ms – eine Viertelsekunde) und langsame (30000ms – 30 Sekunden) FadeOuts implementiert hatte, baute ich mit der Variable browserIsPerformant eine Weiche ein. jQuery kennt die .delay()-Funktion, mit welcher Aktionen für eine benutzerdefinierte Zeit (Millisekunden) hinausgezögert werden können. Damit konnte ich sicherstellen, dass die Effekte sowohl in der abgespeckten als auch in der Vollversion des Dashboards zur selben Zeit endeten.

Leider kann .delay() nicht auf .toggle(), .show() und .hide() angewendet werden.

Eselsohren

	if(browserIsPerformant) {
		$(obj).children('.updated').fadeToggle(30000);
	}
	else {
		$(obj).children('.updated').delay(30000).fadeOut(1);
	}

Indem ich im else-Abschnitt den Delay auf 30 Sekunden setzte und den fadeOut auf 1 Millisekunde, ergab sich unter Midori neu keine Performance-Einbusse mehr.

Sekundenanzeige (Doppelpunkte)

	if(browserIsPerformant) {
		$('.separator').fadeTo(250,clockSeparatorMap[opacity]);
	}
	else {
		$('.separator').delay(250).fadeTo(1,clockSeparatorMap[opacity]);
	}

Auch hier arbeite ich mit der .delay()-Funktion, setze sie hier aber „nur“ auf 250 Millisekunden. Anschliessen wird der FadeOut innert 1 Millisekunde gemacht.

Nachtrag

Obwohl Midori nach diesen Anpassungen vorerst stabil lief, fror der Browser nach ca. 10 Stunden erneut ein.

Ich entschied mich deshalb, statt Midori auf Chromium zu setzen:

# apt-get install chromium

… und den Google-Browser folgendermassen zu starten (/etc/xdg/lxsession/LXDE/autostart, via Raspberry PI kiosk mode with Chromium.):

@xset s off
@xset -dpms
@xset s noblank

@chromium --kiosk --incognito http://domain.tld/dash

Auch Chromium (Version 22) hat Probleme mit den opulenten jQuery-Animationen, weshalb ich den JavaScript-Code noch ein wenig anpassen musste:

var browserIsPerformant = true;
if(navigator.userAgent.match(/(Midori)/) || navigator.userAgent.match(/(armv6l)/)) {
	browserIsPerformant = false;
}

Chromium trägt aktuell auch die Prozessorplattform im User Agent-String, im Falle von Raspberry Pi ist das ARM.

Tags: , , , ,
Labels: Web

2 Kommentare | neuen Kommentar verfassen