2016-04-12 1 views
4

Je suis actuellement en train de développer un site web avec phoenix et j'ai une section vidéo qui devrait jouer en arrière-plan.Servir une requête de plage HTTP avec phoenix?

Bien que cela fonctionne correctement sur Chrome & Firefox, il ne fonctionne pas sur Safari.

Je suppose que c'est parce que cowboy ne sert pas correctement la requête HTTP.

Y at-il un moyen d'activer (si désactiver par défaut)?

$ curl -H Range:bytes=16- -I http://localhost:4000/videos/vid_home_1.mp4 
HTTP/1.1 200 OK 
server: Cowboy 
date: Tue, 12 Apr 2016 14:41:20 GMT 
content-length: 633787 
cache-control: public 
etag: 480A03F 
content-type: video/mp4 

Quand il doit être un 206 comme indiqué avec un serveur nginx:

$ curl -H Range:bytes=16- -I http://localhost/videos/vid_home_1.mp4 
HTTP/1.1 206 Partial Content 
Server: nginx/1.8.0 
Date: Tue, 12 Apr 2016 14:46:17 GMT 
Content-Type: video/mp4 
Content-Length: 633771 
Last-Modified: Mon, 11 Apr 2016 12:26:26 GMT 
Connection: keep-alive 
ETag: "570b97f2-9abbb" 
Content-Range: bytes 16-633786/633787 
+0

pourquoi servir du contenu statique par cow-boy? – ardhitama

+0

@ardhitama: bien surtout parce que c'est ce qui utilise phoenix, et je suis encore au début du développement ... et aussi, cowboy sert du contenu statique assez bien pour autant que je sache. Cependant, si je ne peux pas utiliser range-request, je pourrais passer par nginx et reverse proxy à mon serveur phoenix, mais je préférerais résoudre ce problème. – TheSquad

Répondre

0

je trouve un moyen de me faire avec bouchons ... Donc, si quelqu'un veut servir avec Phoenix Range Request/Elixir Voici ce que vous devez faire (Ceci est assez basique et ne ne pas prendre en compte rfc)

defmodule Plug.Range do                      
    @behaviour Plug                        
    @allowed_methods ~w(GET HEAD)                    
    import Plug.Conn                        

    def init(options) do                       
    options                         
    end                           

    def call(conn, _opts) do                      
    if (Enum.empty?(Plug.Conn.get_req_header(conn, "range"))) do            
     conn                          
    else                          
     file_path = "priv/static" <> conn.request_path               
     if File.exists? file_path do                    

     stats = File.stat! file_path                   
     filesize = stats.size                     

     req = Regex.run(~r/bytes=([0-9]+)-([0-9]+)?/, conn |> Plug.Conn.get_req_header("range") |> List.first) 

     {req_start, _} = req |> Enum.at(1) |> Integer.parse             
     {req_end, _} = req |> Enum.at(2, filesize |> to_string) |> Integer.parse        

     file_end = (filesize - 2) |> to_string                

     length = req_end - req_start + 1                  

     conn                         
     |> Plug.Conn.put_resp_header("Content-Type", "video/mp4")            
     |> Plug.Conn.put_resp_header("Accept-Ranges", "bytes")             
     |> Plug.Conn.put_resp_header("Content-Range", "bytes #{req_start}-#{req_end}/#{filesize}")    
     |> Plug.Conn.send_file(206, file_path, req_start, length)            
     |> Plug.Conn.halt                      
     else                          
     conn                         
     end                          
    end                          
    end                           
end   

Comme vous pouvez le voir, en ce moment, il n'envoyer « video/mp4 » type de contenu, mais vous pouvez facilement faire fonctionner quelque chose pour tout ...

Enfin pour le Plug à travailler, vous besoin de le placer juste avant Plug.static dans votre fichier Project Endpoint.

aide quelqu'un espère que ce ...

EDIT: Pour ceux qui sont intéressés, j'ai créé un paquet github/de hex.pm pour cela: Hex link
github link

0

On dirait que Cowboy n'a pas (encore) soutien à l'en-tête Range, vous aurez donc besoin d'utiliser un serveur web différent pour cela.

Source: https://github.com/ninenines/cowboy/issues/306

+0

Vous avez raison, Range n'est pas encore pris en charge, mais j'ai trouvé un moyen de le faire avec Plugs, voir ma réponse ci-dessous ... – TheSquad

+0

Moi personnellement, je préfère avoir une implémentation RFC conforme. Mais si cela fonctionne pour vous, génial! Bravo ;-) –

+0

Ceci est pour le développement seulement ... Actuellement, je n'ai malheureusement pas le temps de créer une implémentation compatible RFC ... Je vais probablement créer un github dans un mois avec le Plug conforme RFC, mais pour maintenant ça marchera pour moi ;-) – TheSquad