Jeder Punkt unten hat zwischen einigen Stunden und zwei Tagen gekostet, und keiner ließ sich aus der Dokumentation vorhersehen.
Das iPhone verschlechtert still, was es hochlädt
Ein in 4K aufgenommenes Video kam als kurze Datei in 480 mal 360 an, und Fotos waren kleiner als die Originale. Nichts in der Anwendung tat das. Die WebKit-Quellen machen es klar: Wird eine Datei aus der Fotomediathek gewählt, kodiert Safari auf iOS Videos immer neu, merkt sich die im Auswahldialog gewählte Größe von jeder anderen Seite und übergibt ein Live Photo als seinen kurzen Clip in niedriger Auflösung. Eine Webseite kann das nicht abschalten. Also sagt die Anwendung die Wahrheit: Nach der Auswahl zeigt sie die tatsächliche Auflösung und Länge, warnt bei Anzeichen für eine Verkleinerung und bietet den Weg über die App Dateien an, die das Original liefert. Die Maße jeder Datei werden auf dem Server gespeichert, die Frage, warum ein Video schlecht ist, entscheidet also ein Eintrag und nicht eine Vermutung.
Hängen bei 96 Prozent: eine Antwort, die ankommt, aber nie gesehen wird
Uploads von iPhones erreichten 96 bis 99 Prozent und blieben stehen. Die Serverlogs zeigten alles empfangen und geschrieben, mit anderthalb Sekunden Antwortzeit. Das Telefon wartete endlos. Zwei Ursachen, beide in der Netzwerkschicht von Apple: Der Browser verlor sich, wenn der Anfragekörper direkt aus einer Datei auf der Platte gelesen wurde, und bei mehreren Uploads zugleich erhielt eine Anfrage ein vollständiges HTTP 200, meldete aber nie, dass sie fertig sei. Stücke werden jetzt zuerst in den Speicher gelesen und als fertiger Puffer gesendet; ist eine vollständige, gültige Antwort sichtbar, gilt das Stück als zugestellt und die Zombie-Anfrage wird verworfen; ein Leerlaufzähler von 30 Sekunden löst eine Wiederholung mit wachsendem Abstand aus. Das Telefon schickt am Ende außerdem ein kurzes Ereignisprotokoll, das bei den Metadaten der Datei liegt, sodass sich das Verhalten eines fremden Telefons später am Server nachlesen lässt.
Ein moderner Build, ein altes Telefon, eine weiße Seite
Auf einem einige Jahre alten Telefon mit veraltetem Browser erschien die Seite ohne Stile, und der Upload funktionierte nicht. Das Framework baut für Browser der letzten zwei Jahre, die Stilbibliothek packt alles in eine moderne CSS-Konstruktion, die eine ältere Engine samt dem ganzen Stylesheet überspringt, und einige neue Einheiten und Syntaxkürzel stoppen das ganze Skript. Zwei Fallen obendrauf: Der CSS-Minifizierer entfernte den älteren von zwei Ersatzwerten als Duplikat, und der offizielle Mechanismus des Frameworks, ein Skript zuerst zu laden, lud es nach den eigenen Paketen. Die Lösung: eine ausdrückliche, mehrere Jahre zurückgesetzte Liste unterstützter Browser, die moderne Konstruktion beim Bauen aufgelöst, Ersatzeinheiten, Polyfills und ein paar Zeilen Skript direkt im Kopf des Dokuments.
Eine große Datei gegen die Standardwerte des Servers
Bei 5 GB je Datei arbeiten die meisten Standardwerte gegen einen. Der Reverse-Proxy puffert die ganze Anfrage, bevor er sie weitergibt, und schreibt Gigabytes auf die eigene Platte, nur um sie weiterzureichen; Größenlimits und Zeitüberschreitungen sind kurz. Der Upload streamt jetzt durch alle Schichten ohne Zwischenpuffer, jedes Stück landet an seinem Platz in einer dünn besetzten Datei, der Abschluss ist atomar, und ein nach Verbindungsabbruch wiederholter Abschluss erzeugt kein Duplikat. Die Standardbibliothek für Formulare in Python dekodierte Dateinamen in einer alten westeuropäischen Kodierung, polnische Zeichen konnten so die ganze Anfrage zum Scheitern bringen; ein kurzer Leser der Kopfzeile mit der richtigen Kodierung hat sie ersetzt.
Einen Browser von vor sechs Jahren testen
Moderne Testwerkzeuge können Browser aus dieser Zeit nicht mehr steuern. Statt anzunehmen, es müsse funktionieren, wurden archivierte Engine-Versionen geladen und direkt über ein Protokoll niedrigerer Ebene gesteuert, jede über den vollen Weg: Seite öffnen, echte Datei hochladen, Prüfsumme mit dem Original vergleichen, Galerie und Unterseiten öffnen.