Tous ceux qui font du web connaissent HTTP. Mais que se passe-t-il quand on le pousse dans ses retranchements ? Retours d’expérience sur nos développements en interne.
5. Problématique de l'épisodeProblématique de l'épisode
● Gérer des fichiers dans le cloud
● Application web
● Utilisation d'un object storage
https://www.ovh.com/fr/cloud/storage/object-storage.xml
● Gérer des fichiers dans le cloud
● Application web
● Utilisation d'un object storage
https://www.ovh.com/fr/cloud/storage/object-storage.xml
11. Timeout ?Timeout ?
● Connexion HTTP en attente sans traffic
● Passage par des load balancers
● Ressemble à une attaque SYN
● Connexion HTTP en attente sans traffic
● Passage par des load balancers
● Ressemble à une attaque SYN
12. Le callback de curl est un amiLe callback de curl est un ami
● Exécution à chaque paquet reçu
● Temps curl non décompté
● Permet d'éviter stockage local
● Permet d'envoyer du contenu : pas de
timeout
● Exécution à chaque paquet reçu
● Temps curl non décompté
● Permet d'éviter stockage local
● Permet d'envoyer du contenu : pas de
timeout
13. Le callback de curl est un amiLe callback de curl est un ami
curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($a,$b) {
echo $b;
flush();
return strlen($b);
);
curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($a,$b) {
echo $b;
flush();
return strlen($b);
);
15. Enregistrer le fichier sous...Enregistrer le fichier sous...
// Frontend
Iframe + formulaire à valider pour charger le fichier sans recharge la
page
// Backend
header('CacheControl: nocache, nostore, maxage=0, mustrevalidate');
header("ContentType: application/jpeg”);
header('ContentLength: 1337”);
header("ContentTransferEncoding: binary");
header('ContentDisposition: attachment;filename="picture.jpg"');
// Frontend
Iframe + formulaire à valider pour charger le fichier sans recharge la
page
// Backend
header('CacheControl: nocache, nostore, maxage=0, mustrevalidate');
header("ContentType: application/jpeg”);
header('ContentLength: 1337”);
header("ContentTransferEncoding: binary");
header('ContentDisposition: attachment;filename="picture.jpg"');
16. Zip obligatoireZip obligatoire
● Un seul fichier par download
● Le format zip permet de faire un seul
fichier (même sans compression)
● Stockage local avant de zipper ?
● Un seul fichier par download
● Le format zip permet de faire un seul
fichier (même sans compression)
● Stockage local avant de zipper ?
17. Les streams sont vos amisLes streams sont vos amis
● Stream permet la lecture / écriture d'une
ressource
● Stream se comporte comme les fichiers
● Plus d'infos sur les streams
http://php.net/manual/en/intro.stream.php
https://blog.pascal-martin.fr/post/slides-presentation-flux-forum-php-2015.html
● Stream permet la lecture / écriture d'une
ressource
● Stream se comporte comme les fichiers
● Plus d'infos sur les streams
http://php.net/manual/en/intro.stream.php
https://blog.pascal-martin.fr/post/slides-presentation-flux-forum-php-2015.html
18. Les streams sont vos amisLes streams sont vos amis
// Register stream zip
stream_wrapper_register("zip", "ZipClassName");
// Use stream zip with curl return
$fp = fopen("zip://uniqNameByDownload”, "r+");
curl_setopt($curl, CURLOPT_FILE, $fp);
fclose( $fp );
// Register stream zip
stream_wrapper_register("zip", "ZipClassName");
// Use stream zip with curl return
$fp = fopen("zip://uniqNameByDownload”, "r+");
curl_setopt($curl, CURLOPT_FILE, $fp);
fclose( $fp );
20. Imagick ?Imagick ?
● Limité à l'application web
● Prend des ressources CPU
● Comment distribuer le cache ?
● Limité à l'application web
● Prend des ressources CPU
● Comment distribuer le cache ?
21. Réducteur d'image à la voléeRéducteur d'image à la volée
Navigateur
web
Serveur
applicatif
Object
storage
Miniatures
22. Houston : on reçoit des erreurs 0Houston : on reçoit des erreurs 0
23. Des erreurs 0 ?Des erreurs 0 ?
● Pas d'erreur 0 dans les logs
● Sur IE, l'erreur n'appelle même pas le
callback d'erreur …
● Mais des 499
● What ?
● Pas d'erreur 0 dans les logs
● Sur IE, l'erreur n'appelle même pas le
callback d'erreur …
● Mais des 499
● What ?
24. Suppression d'un fichierSuppression d'un fichier
● L'erreur arrive sur les suppressions de
gros fichiers
● L'action est longue coté Object Storage
● Timeout php ?
● L'erreur arrive sur les suppressions de
gros fichiers
● L'action est longue coté Object Storage
● Timeout php ?
25. Code HTTP 0 ?Code HTTP 0 ?
● Soucis réseau : ça a tranché sur la route
● Timeout du load balancer !
● Solution : faire de l'async ?
● Soucis réseau : ça a tranché sur la route
● Timeout du load balancer !
● Solution : faire de l'async ?
26. Suppression programméeSuppression programmée
● Object storage permet de programmer
une suppression
● Pas d'attente ! C'est juste programmé !
● Et si on programmait dans une
seconde ?
● Object storage permet de programmer
une suppression
● Pas d'attente ! C'est juste programmé !
● Et si on programmait dans une
seconde ?
27. Heu… y'a encore des erreurs 0 !Heu… y'a encore des erreurs 0 !
28. Encore des erreurs 0 ?Encore des erreurs 0 ?
● Sur un upload : y'a du traffic -_-
● Seulement sur les gros fichiers
● Sur un upload : y'a du traffic -_-
● Seulement sur les gros fichiers
29. Firebug ...Firebug ...
● Analyseur de code dans Firefox /
Chrome
● Coupe le traffic sur les requêtes > 100
Mo.
● Paf timeout ...
● Analyseur de code dans Firefox /
Chrome
● Coupe le traffic sur les requêtes > 100
Mo.
● Paf timeout ...
30. Et si on parlait d'upload ?Et si on parlait d'upload ?
31. Comment on upload ?Comment on upload ?
<form enctype="multipart/formdata" action="upload.php” method="POST">
<input type="hidden" name="META1" value="file" />
<input name="content" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
● Recharge la page
● Ne permet pas d'afficher la progression
● AJAX ?
<form enctype="multipart/formdata" action="upload.php” method="POST">
<input type="hidden" name="META1" value="file" />
<input name="content" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
● Recharge la page
● Ne permet pas d'afficher la progression
● AJAX ?
32. AJAX ?AJAX ?
● Permet de suivre la progression
● Format binaire
xhr = new XMLHttpRequest();
xhr.addEventListener("load", successCallback, false);
xhr.addEventListener("error", errorCallback, false);
xhr.addEventListener("abort", abortCallback, false);
xhr.upload.addEventListener("progress", progressCallback, false);
xhr.open('POST', url, true);
xhr.send(data);
● Permet de suivre la progression
● Format binaire
xhr = new XMLHttpRequest();
xhr.addEventListener("load", successCallback, false);
xhr.addEventListener("error", errorCallback, false);
xhr.addEventListener("abort", abortCallback, false);
xhr.upload.addEventListener("progress", progressCallback, false);
xhr.open('POST', url, true);
xhr.send(data);
33. Et mon formulaire ?Et mon formulaire ?
● L'object storage attend un formulaire
● On crée le formulaire en javascript
● http://caniuse.com/#search=formdata
http://caniuse.com/#search=file
formData = new FormData();
formData.append('meta1', “file”);
formData.append('content', fp);
…
xhr.send(formData);
● L'object storage attend un formulaire
● On crée le formulaire en javascript
● http://caniuse.com/#search=formdata
http://caniuse.com/#search=file
formData = new FormData();
formData.append('meta1', “file”);
formData.append('content', fp);
…
xhr.send(formData);
34. Contraintes des uploadsContraintes des uploads
● Adsl répandu
● Upload de l'adsl : max 128 Ko/s (1Mbps)
● Les uploads durent des heures
● Adsl répandu
● Upload de l'adsl : max 128 Ko/s (1Mbps)
● Les uploads durent des heures
36. Chef ça a cassé !Chef ça a cassé !
● Same origin policy !
● Aucun appel Ajax sur un autre domaine
● C'était trop beau…
● Same origin policy !
● Aucun appel Ajax sur un autre domaine
● C'était trop beau…
37. CORSCORS
● Permet de définir les serveurs autorisés
● Configuration sur les serveurs
● http://caniuse.com/#search=cors
// Requête de firefox
GET /fileList/ HTTP/1.1
Origin: http://mywebapp.ovh
// Réponse du serveur cluster.objectstorage.ovh
AccessControlAllowOrigin: http://mywebapp.ovh
● Permet de définir les serveurs autorisés
● Configuration sur les serveurs
● http://caniuse.com/#search=cors
// Requête de firefox
GET /fileList/ HTTP/1.1
Origin: http://mywebapp.ovh
// Réponse du serveur cluster.objectstorage.ovh
AccessControlAllowOrigin: http://mywebapp.ovh
38. Au fait, tu dois gérer IE8 !Au fait, tu dois gérer IE8 !
● Dernier IE de Windows XP...
● Gére pas formData (IE10)
● Gére pas CORS (IE10) ...
● Dernier IE de Windows XP...
● Gére pas formData (IE10)
● Gére pas CORS (IE10) ...
39. Au fait, tu dois gérer IE8 !Au fait, tu dois gérer IE8 !
● On crée une iframe sur cluster.objectstorage.ovh
● Contenant un formulaire
● On simule le clic sur le bouton
● On crée une iframe sur cluster.objectstorage.ovh
● Contenant un formulaire
● On simule le clic sur le bouton
40. Les autres blagues de IE < 10Les autres blagues de IE < 10
● Upload de .jpeg ?
● Sélection multiple ?
● Windows phone 8 ?
● Upload de .jpeg ?
● Sélection multiple ?
● Windows phone 8 ?
41. On peut uploader un dossier ?On peut uploader un dossier ?
● Chrome le peut. C'est deprecated
● Firefox bute sur l'ergonomie
● WebAPI ?
● Chrome le peut. C'est deprecated
● Firefox bute sur l'ergonomie
● WebAPI ?
42. Etape 3 :
La réalisation et ses aléas
Etape 3 :
La réalisation et ses aléas
44. Remontées des utilisateursRemontées des utilisateurs
● Mon download a crashé au bout de 27h
● Mon zip est corrompu
● Mon download a crashé au bout de 27h
● Mon zip est corrompu
45. Ce qu'en pense les sysadminsCe qu'en pense les sysadmins
● Non pas de reboot de serveur
● Aucune alerte du monito
● Au fait, pendant que tu es là, tu as vu
mon mail sur la conso de RAM ?
● Non pas de reboot de serveur
● Aucune alerte du monito
● Au fait, pendant que tu es là, tu as vu
mon mail sur la conso de RAM ?
46. Conso de RAM ?Conso de RAM ?
● Pas possible : je stream
● Je reproduis pas en dev : c'est le serveur
qui est mal configuré
● Monito des process PHP : non c'est pas
eux qui mangent la RAM !
● Pas possible : je stream
● Je reproduis pas en dev : c'est le serveur
qui est mal configuré
● Monito des process PHP : non c'est pas
eux qui mangent la RAM !
50. Tout est bien qui finit bienTout est bien qui finit bien
51. En fait, le dev web c'estEn fait, le dev web c'est
● Multi – navigateur
● Ça doit gérer le réseau
● C'est comme les oignons, ça a des
couches
● Multi – navigateur
● Ça doit gérer le réseau
● C'est comme les oignons, ça a des
couches