por que o conteúdo parcial não está sendo exibido em nginx (mp4)?

3

Estou executando o nginx v.1.9.3 aqui para servir meu site e também arquivos de vídeo para streaming. Eu estou vendo que os arquivos mp4 são sempre servidos com um código de 200 e que as solicitações de conteúdo parcial são ignoradas. Às vezes, os vídeos podem ser "pesquisados" nos navegadores e, às vezes, não. Eu usei vários formatos de arquivo e os resultados variam de ok-ish a fatalmente ruim.

usei curl -I para visualizar os dados de retorno do nginx e vi que não havia menção do servidor aceitando os intervalos de bytes e quando solicito manualmente partes dos arquivos usando o curl, vejo que em todos os casos o código de retorno é 200 .

Eu testei com e sem o módulo mp4 ativado na construção do arquivo de configuração do nginx e nem fiz uma vantagem significativa sobre o outro.

um arquivo de exemplo pode ser visto aqui (este é o formato mp4 h264, como eu ouvi isso foi melhor para navegadores modernos): link

este é o arquivo de configuração do meu site:

server {
    server_name www.mysite.org;
    listen 443 ssl spdy default_server;
    ssl_certificate_key /mysitekey.key;
    ssl_certificate /mysitekey.crt;
    keepalive_timeout     300;
    spdy_keepalive_timeout 300;

    index index.php index.html index.htm;

    # https only, mode - Remember this setting for 365 days
    add_header Strict-Transport-Security max-age=31536000;

    access_log /mysite.log;
    error_log /mysite.log;
    root /mysite/path;

    client_header_buffer_size 1k;
    fastcgi_index index.php;
    client_max_body_size  2G;
    client_body_buffer_size 1K;
    proxy_read_timeout 600;

    error_page   500  /500.html;
    error_page   502  /502.html; #bad gateway
    error_page   503  /503.html;
    error_page   504  /504.html; # gateway timeout

    location ~ (^\.|/\.) {
        return 403;
    }

    set $cache_uri $request_uri;

    # POST requests and urls with a query string should always go to PHP
    if ($request_method = POST) {
        set $cache_uri 'null cache';
    }
    if ($query_string != "") {
        set $cache_uri 'null cache';
    }

    # Don't cache uris containing the following segments
    if ($request_uri ~* "(/admin/|/xml-rpc_handler.php|/(cron|sign-in|joyn|messages).php|/feed/|index.php|sitemap.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
        set $cache_uri 'null cache';
    }

    location /cache {
        rewrite ^/cache\/(.*)$ /engine/handlers/cache_handler.php?request=$1&$query_string;
    }

    location /export {
        rewrite ^/export\/([A-Za-z]+)\/([0-9]+)\/?$ /engine/handlers/export_handler.php?view=$1&guid=$2;
        rewrite ^/export\/([A-Za-z]+)\/([0-9]+)\/([A-Za-z]+)\/([A-Za-z0-9\_]+)\/$ /engine/handlers/export_handler.php?view=$1&guid=$2&type=$3&idname=$4;
    }

    location = /rewrite.php {
        rewrite ^(.*)$ /install.php;
    }

    location / {
        try_files $uri $uri/ /index.php?__elgg_uri=$uri&$query_string;
    }

    location ~ /\.well-known
    {
        access_log off;
        log_not_found off; 
    }

    location ~ /\. 
    {
        access_log off;
        log_not_found off; 
        deny all;
    }   

    # Prevent clients from accessing hidden files (starting with a dot)
    # This is particularly important if you store .htpasswd files in the site hierarchy
    location ~* (?:^|/)\. {
        deny all;
    }

    # Prevent clients from accessing to backup/config/source files
    location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
        deny all;
    }

    location ~ \.php$ 
    {
    # Fastcgi cache
    set $skip_cache 1;
    if ($cache_uri != "null cache") {
        add_header X-Cache-Debug "$cache_uri $cookie_nocache $arg_nocache$arg_comment $http_pragma $http_authorization";
        set $skip_cache 0;
    }
    fastcgi_cache_bypass $skip_cache;
    fastcgi_cache microcache;
    fastcgi_cache_key $scheme$host$request_uri$request_method;
    fastcgi_cache_valid any 8m;
    fastcgi_cache_bypass $http_pragma;
    fastcgi_cache_use_stale updating error timeout invalid_header http_500;
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_pass unix:/socket/php5-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 600;
    fastcgi_buffers 256 4k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
    fastcgi_param  QUERY_STRING     $query_string;
    fastcgi_param  REQUEST_METHOD   $request_method;
    fastcgi_param  CONTENT_TYPE     $content_type;
    fastcgi_param  CONTENT_LENGTH   $content_length;
}

## cache headers 

# cache.appcache, your document html and data
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
  expires -1;
  add_header Cache-Control "private";
  add_header Pragma "private";
}

# Feed
location ~* \.(?:rss|atom)$ {
  expires 1h;
  add_header Cache-Control "public";
}

location ~ \.flv$ {
    flv;
}   
}

e aqui está o arquivo principal nginx.conf:

user nginx;
worker_processes  4;
worker_priority -5;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

# Maximum open file descriptors per process;
# should be > worker_connections.
worker_rlimit_nofile 40000;

events 
{
    worker_connections  8096;
    use epoll;
    multi_accept on;
}

http 
{   
    # Define the MIME types for files.
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    underscores_in_headers on;

    # do not allow content to be framed
    add_header X-Frame-Options DENY;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
    # caching using 50MB of RAM and 1000MB of disk space
    fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:50m max_size=1000m inactive=600m;

    # Force the latest IE version
    # Use ChromeFrame if it's installed for a better experience for the poor IE folk
    add_header "X-UA-Compatible" "IE=Edge"; 

 # cache file DESCRIPTORS

    open_file_cache max=2000 inactive=20s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 3;
    open_file_cache_errors on;
    keepalive_requests 100000;
    server_tokens off; # hides nginx version number

      # Speed up file transfers by using sendfile() to copy directly
      # between descriptors rather than using read()/write().
  sendfile        on;

  # Tell Nginx not to send out partial frames; this increases throughput
  # since TCP frames are filled up before being sent out. (adds TCP_CORK)
  tcp_nopush      on;

    ## Global SSL options
  ssl_session_cache builtin:1000 shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
  ssl_session_timeout  24h;

  # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /path/dhparam.pem;

    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:HIGH:DH+AES:ECDH+3DES:DH+3DES:!eNULL:!NULL:!aNULL:!EDH:!MD5:!DSS; # previously produced A grade test result

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    #ssl_buffer_size 4k;
    ssl_buffer_size 1400; # 1400 bytes to fit in one MTU
    ssl_session_tickets off;

    # enable SPDY header compression
    spdy_headers_comp 6;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them

    ssl_stapling on; # Requires nginx >= 1.3.7
    ssl_stapling_verify on; # Requires nginx => 1.3.7

    resolver 156.154.70.1 156.154.71.1 valid=300s;
    resolver_timeout 5s;

  # Compression

  # Enable Gzip compressed.
  gzip on;

  # Enable compression both for HTTP/1.0 and HTTP/1.1 (required for CloudFront).
  gzip_http_version  1.0;

  # Compression level (1-9).
  # 5 is a perfect compromise between size and cpu usage, offering about
  # 75% reduction for most ascii files (almost identical to level 9).
  gzip_comp_level    6;

  # Don't compress anything that's already small and unlikely to shrink much
  # if at all (the default is 20 bytes, which is bad as that usually leads to
  # larger files after gzipping).
  gzip_min_length    10000;

  # Compress data even for clients that are connecting to us via proxies,
  # identified by the "Via" header (required for CloudFront).
  gzip_proxied       any;

  # Tell proxies to cache both the gzipped and regular version of a resource
  # whenever the client's Accept-Encoding capabilities header varies;
  # Avoids the issue where a non-gzip capable client (which is extremely rare
  # today) would display gibberish if their proxy gave them the gzipped version.
  gzip_vary          on;

  # Compress all output labeled with one of the following MIME-types.
  gzip_types
    application/atom+xml
    application/javascript
    application/json
    application/rss+xml
    application/vnd.ms-fontobject
    application/x-font-ttf
    application/x-web-app-manifest+json
    application/xhtml+xml
    application/xml
    font/opentype
    image/svg+xml
    image/x-icon
    text/css
    text/plain
    text/javascript
    application/font-woff
    text/x-component;
  # text/html is always compressed by HttpGzipModule

    gzip_static       on;
    gzip_buffers 16 8k;
    gzip_disable "MSIE [1-6]\.";

    ## Start: Timeouts ##
    client_body_timeout   30;
    client_header_timeout 30;
    keepalive_timeout     100;
    send_timeout          100;  
    ## End: Timeouts ##

    ## Reset lingering timed out connections. Deflect DDoS.
    reset_timedout_connection on;
    ### Directive describes the zone, in which the session states are stored i.e. store in slimits. ###
     ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ###
   limit_conn_zone $binary_remote_addr zone=perip:10m;
   limit_req_zone $binary_remote_addr zone=periprate:10m rate=1000r/s;
   limit_conn_zone $server_name zone=perserver:10m;
    #  limit_rate 1280k;
    ### Control maximum number of simultaneous connections for one session i.e. ###
    ### restricts the amount of connections from a single ip address ###
    limit_conn perip 200;
    ### limit connections for the total server
    limit_conn perserver 15000;


    ## Enable clickjacking protection in modern browsers. Available in
    ## IE8 also. See
    ## https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header
    add_header X-Frame-Options SAMEORIGIN;

    ## Include the cache map to decide when or not when to cache.
    include map_cache_piwik.conf;

    ## Include the php-fpm status allowed hosts configuration block.
    ## Uncomment to enable if you're running php-fpm.
    include php_fpm_status_allowed_hosts.conf;

    include /etc/nginx/sites-enabled/*;
}

se alguém souber por que isso está falhando, eu adoraria que você compartilhasse aqui ... obrigado

    
por tunist 02.08.2015 / 17:50

1 resposta

1

a causa do problema foi a falta de manipulação de intervalo na página PHP que estou usando para transmitir os arquivos. Eu esqueci que isso é uma exigência do processo! Eu adicionei a classe de videostream ( link ) para a página e até agora o streaming está funcionando bem nos meus testes:)

    
por 07.08.2015 / 14:27

Tags