---
title: Cache e CDN para a distribuição OTT
url: https://doc2.pstreamer.tv/pt/manual/extras/ott_caching.html
lang: pt-BR
product: Perfect Streamer
version: 2.0.2.362
---

# Cache e CDN para a distribuição OTT

Apêndice para a operação de instalações de grande porte: como funciona o cache das respostas OTT do Perfect Streamer e como colocar um reverse proxy de cache ou uma CDN à frente do nó. Os modos de distribuição, os formatos de URL e a autorização são descritos na seção principal [OTT e DVR](../streamer/ott_dvr.md#streamer-ott-dvr).

O servidor forma respostas de três categorias, que diferem no tempo de vida do conteúdo e na aptidão para o cache por nós intermediários (reverse proxy, CDN, cache do cliente).

## 1. Modelo de cache

### 1.1. Recursos e cabeçalhos HTTP

| Recurso | URL | Content-Type | Cache-Control |
| --- | --- | --- | --- |
| Segmento TS (HLS) | `/h<sess>/<keyHex>.ts` | `video/mp2t` | `public, max-age=60, immutable` |
| Segmento VTT (legendas) | `/h<sess>/sub/<pid>/<keyHex>.vtt` | `text/vtt; charset=utf-8` | `public, max-age=60, immutable` |
| Segmento fMP4 (DASH / LL-HLS) | `/h<sess>/init.mp4`, `/h<sess>/<key\|N>.m4s` | `video/mp4` | `public, max-age=60, immutable` |
| DASH MPD | `/h<sess>/index.mpd` | `application/dash+xml; charset=utf-8` | `public, max-age=1` |
| HLS master | `/hls/<stream>/<login>/<pass>/index.m3u8` | `application/vnd.apple.mpegurl` | `public, max-age=1` |
| HLS media | `/h<sess>/index.m3u8`, `/h<sess>/sub/<pid>/index.m3u8` | `application/vnd.apple.mpegurl` | `public, max-age=1` |
| 302 Redirect | `/dash/<stream>/<login>/<pass>/index.mpd` | — | `no-cache, no-store` |
| Raw TS | `/http/<stream>/<login>/<pass>` | `video/mp2t` | não definido; não é armazenado em cache |

### 1.2. Características dos segmentos

O identificador hexadecimal do segmento no URL (`<keyHex>` nos caminhos `/h<sess>/<keyHex>.ts`) é formado como o CRC64 do horário inicial do segmento e do ID do fluxo, sendo globalmente único. O URL do segmento endereça um conteúdo imutável — em requisições repetidas do mesmo URL é retornado um fluxo de bytes idêntico (enquanto o segmento permanecer dentro da janela deslizante).

A diretiva `immutable` suprime a revalidação condicional pelo cliente (`If-None-Match`, `If-Modified-Since`). O valor `max-age=60` garante a compatibilidade com um `timeShiftBufferDepth=40s` típico.

Os segmentos fMP4 CMAF (`.m4s`) e o `init.mp4` comum para DASH / Low-Latency HLS são endereçados de forma análoga e armazenados em cache segundo o mesmo modelo (`immutable`, `max-age=60`). Os segmentos parciais (parts) do LL-HLS são requisições byte-range dentro do mesmo `.m4s` e, por isso, não formam uma entrada separada no cache.

### 1.3. Características dos manifestos

`max-age=1` limita a um segundo o limite superior de desatualização do conteúdo no cache. Em uso conjunto com `proxy_cache_lock on` (nginx), os picos de requisições ao manifesto são coalescidos em uma requisição ao origin por segundo.

### 1.4. Variabilidade do conteúdo

Com `absPath=0` (valor padrão, sem o parâmetro de URL `a`) os manifestos HLS media e o DASH MPD não contêm o identificador da sessão no corpo. O conteúdo do manifesto é idêntico entre sessões pertencentes à mesma combinação (stream, param). Isso permite ao cache do reverse proxy reutilizar a entrada entre sessões quando a chave de cache é normalizada.

Com `absPath=1` (parâmetro de URL `a=1`) o corpo do manifesto contém URLs absolutos que incluem o esquema, o host e o identificador da sessão. O conteúdo torna-se específico da sessão e a reutilização do cache entre sessões deixa de ser possível.

## 2. Comportamento dos clientes

| Cliente | URL de atualização do manifesto | Efeito sobre a quantidade de sessões |
| --- | --- | --- |
| Players HLS pela media playlist | `/h<sess>/index.m3u8` | Uma sessão por sessão de reprodução |
| Players DASH pelo URL raiz | `/dash/<stream>/.../index.mpd` (ciclo de repetição) | Tratado pelo session reuse (ver 3.2) |
| Players de navegador (MSE) | `/h<sess>/...` através de `<Location>` / session URL | Uma sessão por sessão de reprodução |

## 3. Mecanismos especiais

### 3.1. HTTP 302 Redirect para DASH

Uma requisição da forma `/dash/<stream>/<login>/<pass>/index.mpd` retorna a resposta `302 Found` com o cabeçalho `Location: /h<sess>/index.mpd`. O corpo da resposta é vazio. A autorização e a alocação da sessão são executadas na etapa de processamento do redirecionamento.

Os clientes que suportam o cache do redirecionamento acessam o session URL diretamente nas requisições subsequentes. Os clientes que não o suportam repetem a requisição de redirecionamento. O custo do reprocessamento do redirecionamento limita-se à verificação de autenticação e às operações de session reuse.

### 3.2. Session reuse para DASH

Ao processar a requisição `/dash/.../index.mpd` do mesmo login para o mesmo fluxo (com o mesmo indicador adaptive), o servidor encontra uma sessão DASH já existente e retorna novamente o seu identificador. Nenhuma sessão nova é criada e nenhum slot do limite de conexões simultâneas é consumido. São reutilizadas apenas as sessões no mesmo modo de reprodução: uma sessão ao vivo e uma sessão VOD de arquivo (parâmetros `t`/`d`/`epg`) não são unificadas.

Aplica-se somente ao DASH. Para o HLS não é necessário um mecanismo de reuse separado: os clientes HLS atualizam a media playlist pelo session URL e não criam uma sessão nova a cada atualização.

### 3.3. Reutilização de segmentos entre sessões

O caminho `/h<sess>/<keyHex>.ts` não depende de `<sess>` na resolução de `<keyHex>` para o conteúdo: `<keyHex>` identifica de forma globalmente inequívoca o segmento TS dentro do fluxo. O Nginx com uma cache key normalizada (que remove o prefixo `/h<sess>/`) atende todas as requisições do mesmo `<keyHex>` a partir de uma única entrada de cache, independentemente de quais clientes as emitiram.

A deduplicação é aplicável somente aos nomes content-addressed — segmentos com identificador hexadecimal de 16 caracteres (`.ts`, `.m4s` com `<keyHex>`, `.vtt`). Os segmentos numerados do live-DASH (`<número>.m4s`), o `init.mp4` e os manifestos são únicos apenas dentro da própria sessão — a sua cache key deve preservar o prefixo `/h<sess>/`, caso contrário o cache entregará o conteúdo de um fluxo aos espectadores de outro. Para o DASH, a deduplicação dos manifestos entre clientes do mesmo login é assegurada pelo session reuse (ver 3.2).

## 4. Parâmetros da requisição

| Parâmetro | Valor padrão | Efeito |
| --- | --- | --- |
| `a` | `0` | `1` — URLs absolutos nos manifestos; `0` — relativos |
| `s` | `40` | `timeShiftBufferDepth` em segundos |
| `m` | `40` | Comprimento mínimo da janela para a emissão do manifesto |
| `v` | `6` para os modos OTT, `3` para Peering / HLS | `#EXT-X-VERSION` no HLS (ignorado pelo DASH); um valor explícito no URL substitui o valor padrão |
| `h3` | ausente (off) | opt-in para HTTP/3 (QUIC): faz o servidor emitir `Alt-Svc` na resposta; sticky no session URL. Ver [HTTP/3 (QUIC)](../streamer/ott_dvr.md#streamer-ott-http3) |

A alteração de um parâmetro pela query string atualiza os valores armazenados na sessão na sua próxima reabertura. Os parâmetros de reprodução do arquivo `t`, `d` e `epg` são descritos em [Reprodução do arquivo (VOD)](../streamer/ott_dvr.md#streamer-dvr-vod).

## 5. Características de carga

A carga sobre o origin escala com a quantidade de fluxos distintos assistidos simultaneamente. O aumento do número de clientes que assistem ao mesmo fluxo não aumenta a quantidade de requisições ao origin quando existe um cache de reverse proxy e uma cache key normalizada.

| Cenário | Frequência de requisições ao origin (ref.) |
| --- | --- |
| 1 cliente no fluxo X | MPD: 0.4 req/s, segment: 0.2 req/s |
| N clientes em um único fluxo X (cache ativado) | MPD: 1 req/s, segment: 0.2 req/s |
| N clientes DASH em modo de repetição em um único fluxo | MPD: 1 req/s (com `proxy_cache_lock`) |
| N clientes em N fluxos distintos | MPD: 0.4·N req/s, segment: 0.2·N req/s |

Os segmentos são deduplicados globalmente pelos nomes content-addressed; a deduplicação dos manifestos entre clientes é assegurada pelo session reuse (DASH) e pelo cache dentro da sessão.

## 6. Nginx como reverse proxy de cache

### 6.1. Configuração básica

```nginx
proxy_cache_path /var/cache/nginx/pss_segments
    levels=1:2 keys_zone=pss_segments:100m
    max_size=20g inactive=30m use_temp_path=off;

proxy_cache_path /var/cache/nginx/pss_manifests
    levels=1:2 keys_zone=pss_manifests:10m
    max_size=256m inactive=5m use_temp_path=off;

upstream pss_backend {
    server 127.0.0.1:43972;
    keepalive 64;
}

map $uri $pss_cache_key {
    "~^/h[0-9a-f]{16}(?<tail>(/[0-9]+)?/[0-9a-f]{16}\.(ts|m4s)|/sub/[0-9]+/[0-9a-f]{16}\.vtt)$"  "stream:$tail";
    default  $uri;
}

server {
    listen 80;
    server_name stream.example.com;

    location ~* "^/h[0-9a-f]{16}(/[0-9]+|/sub/[0-9]+)?/([0-9a-f]+\.(ts|m4s|vtt)|init\.mp4)$" {
        proxy_cache               pss_segments;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 60s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_use_stale     updating error timeout;
        proxy_cache_revalidate    on;
        proxy_ignore_headers      Vary;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_buffering           on;
    }

    location ~* "(^/h[0-9a-f]{16}(/[0-9]+|/sub/[0-9]+)?/index\.(m3u8|mpd)$|^/(hls|dash|llhls)/.*\.(m3u8|mpd)$)" {
        proxy_cache               pss_manifests;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 1s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_lock_timeout  2s;
        proxy_cache_use_stale     updating;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
    }

    location / {
        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_set_header          X-Forwarded-Proto $scheme;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_buffering           off;
        proxy_read_timeout        3600s;
    }
}
```

A porta do origin no exemplo é a porta padrão do servidor HTTP de streaming (43972; HTTPS — 43982). São normalizados apenas os nomes content-addressed dos segmentos (ver 3.3); os manifestos, o `init.mp4` e os segmentos numerados são armazenados em cache pelo URI completo da sua sessão. A diretiva `proxy_ignore_headers Vary` no location dos segmentos é justificada: o servidor acompanha as respostas OTT com o cabeçalho `Vary: Origin` e, sem ela, o cache seria dividido em variantes conforme o valor de Origin do cliente (ver 7).

### 6.2. Finalidade das diretivas

| Diretiva | Finalidade |
| --- | --- |
| `proxy_cache_lock on` | Serializa a execução das requisições upstream em cache miss simultâneos pela mesma chave |
| `proxy_cache_use_stale updating` | Retorna a cópia desatualizada às requisições paralelas durante o período de atualização do cache |
| `proxy_cache_revalidate on` | Utiliza `If-Modified-Since` em cache miss quando há uma cópia armazenada |
| `proxy_cache_valid 404 403 0s` | Proíbe o cache dos erros de autorização e dos 404 |
| `keepalive 64` no upstream | Mantém um pool de conexões persistentes com o origin |
| `proxy_buffering on` | Para os segmentos; ativa a bufferização da resposta no nginx |
| `proxy_buffering off` | Para a seção `/`; desativa a bufferização (raw streaming) |

### 6.3. Cálculo do `max_size` do cache de segmentos

Valor aproximado: `bitrate × timeShiftBufferDepth × distinct_streams × 2`

Exemplo: 10 fluxos × 8 Mbps × 40 s × 2 ≈ 800 MB. Recomenda-se prever uma margem de 10x para levar em conta a variabilidade do bitrate.

### 6.4. Terminação TLS

O servidor Perfect Streamer aceita conexões nas portas HTTP e HTTPS. Com a terminação TLS no nginx, o upstream utiliza a porta HTTP. O encaminhamento dos cabeçalhos `X-Forwarded-Proto` e `X-Forwarded-Host` é obrigatório para a formação correta dos URLs absolutos com `absPath=1`.

```nginx
server {
    listen 443 ssl http2;
    server_name stream.example.com;

    ssl_certificate           /etc/letsencrypt/live/stream.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/stream.example.com/privkey.pem;
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       1d;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location ... {
        proxy_pass                http://pss_backend;
        proxy_set_header          X-Forwarded-Proto https;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_set_header          Host              $host;
        # + caching directives from 6.1
    }
}

server {
    listen 80;
    server_name stream.example.com;
    return 301 https://$host$request_uri;
}
```

Com HTTPS entre o nginx e o origin aplicam-se as diretivas `proxy_ssl_verify` e `proxy_ssl_trusted_certificate`. Para conexões de loopback a criptografia é redundante.

### 6.5. Vários hosts

Ao atender vários `server_name` a partir de um único processo nginx, `$host` é adicionado à cache key para isolar o conteúdo:

```nginx
map $uri $pss_cache_key {
    "~^/h[0-9a-f]{16}(?<tail>(/[0-9]+)?/[0-9a-f]{16}\.(ts|m4s)|/sub/[0-9]+/[0-9a-f]{16}\.vtt)$"  "$host:stream:$tail";
    default  "$host:$uri";
}
```

O tamanho de `keys_zone` é calculado como 8000 chaves/MB. Para instalações multi-host com milhares de fluxos recomenda-se `keys_zone=...:300m` ou superior.

## 7. Cache no lado do cliente

`Cache-Control: immutable` é processado pelos navegadores modernos. O cache do cliente retorna o segmento sem requisição condicional em um acesso repetido (inclusive em um seek para trás dentro do buffer do player).

Os Service Workers podem aplicar a estratégia `cache-first` com base no conteúdo de Cache-Control. Os players DASH utilizam MSE através de `SourceBuffer`; um segmento colocado no buffer permanece disponível sem uma nova requisição HTTP até sair do limite de deslizamento.

Para requisições entre domínios o servidor entrega `Access-Control-Allow-Origin: *` junto com o cabeçalho `Vary: Origin, Access-Control-Request-Headers`. Um proxy de cache que respeita Vary divide as entradas em variantes conforme o valor de Origin do cliente (os players de navegador enviam Origin, os de console não), o que reduz a HIT rate. Como o ACAO é o universal «*», é seguro adicionar `proxy_ignore_headers Vary` no location dos segmentos (ver 6.1).

## 8. Distribuição através de CDN

O Perfect Streamer é compatível com CDN no modo pull-from-origin.

**Origin shield.** Recomenda-se a colocação de um ou vários nós shield entre o CDN edge e o origin para reduzir a frequência de requisições ao origin quando os clientes estão distribuídos globalmente.

**Purge.** Os segmentos content-addressed não requerem purge. Quando os metadados do fluxo mudam (codec, resolução), os manifestos são atualizados dentro de `max-age=1` sem purge explícito.

**Cache warming.** Quando se espera um aumento de carga sobre um fluxo específico, é admissível o aquecimento da CDN a partir de vários pontos geográficos antes do início da transmissão.

**Distribuição geográfica.** Os segmentos (`max-age=60`) são bem adequados ao cache geograficamente distribuído. Os manifestos (`max-age=1`) admitem um atraso de entrega de até um segundo — aceitável para a transmissão live sem baixa latência.

## 9. Monitoramento

### 9.1. `X-Cache-Status`

Adição de `add_header X-Cache-Status $upstream_cache_status;` a cada location com cache. Valores:

| Valor | Descrição |
| --- | --- |
| `HIT` | Resposta a partir do cache |
| `MISS` | Ausente no cache, obtido do origin e armazenado |
| `EXPIRED` | Expirado, atualizado |
| `UPDATING` | Cópia stale entregue a uma requisição paralela durante a atualização |
| `STALE` | `use_stale` retornou uma cópia expirada (origin indisponível) |
| `REVALIDATED` | O origin retornou 304 Not Modified |
| `BYPASS` | `proxy_cache_bypass` foi acionado |

### 9.2. Formato do access log

```nginx
log_format pss_cache '$remote_addr $status $request_method "$request" '
                     '$body_bytes_sent rt=$request_time ut=$upstream_response_time '
                     'cache=$upstream_cache_status key=$pss_cache_key';

server {
    access_log /var/log/nginx/pss.log pss_cache;
}
```

### 9.3. Métricas

O módulo `nginx-vts` exporta métricas per-zone no formato Prometheus:

```
GET /status/format/prometheus
```

Limiares recomendados para alertas:

| Métrica | Limiar | Causa possível |
| --- | --- | --- |
| Segment HIT rate | < 90% em 5 minutos | Normalização da cache key comprometida; `max_size` pequeno |
| Manifest MISS rate | > 50% em 1 minuto | `proxy_cache_lock` não serializa as requisições |
| Upstream response time p95 | > 500 ms em 1 minuto | Sobrecarga do origin |
| Cache zone fill | > 90% em 10 minutos | Aproximação do `max_size`, LRU-eviction prevista |

A qualidade da entrega no lado do nó é visível nas métricas de sessão na tela «Clientes» ([Clientes](../webui/monitor.md#webui-clients)).

## 10. Diagnóstico

| Sintoma | Causa provável | Solução |
| --- | --- | --- |
| Segment HIT rate baixo | `Vary: Origin` divide o cache em variantes; violação da normalização no `map` | Adicionar `proxy_ignore_headers Vary` ao location dos segmentos; verificar o regex na diretiva `map` |
| 404 nos segmentos após a saída da janela | 404 armazenado em cache para um segmento que saiu da sliding window | Adicionar `proxy_cache_valid 404 0s` ao location segments |
| Atraso de playback start de 2–5 s | `proxy_cache_lock_timeout` excede a target latency | Reduzir para 1–2 s; ativar `proxy_cache_use_stale updating` |
| Manifest não é atualizado | `proxy_ignore_headers Cache-Control` está definido e vigora um `proxy_cache_valid` com TTL elevado | Indicar explicitamente `proxy_cache_valid 200 1s` ou deixar de ignorar os cabeçalhos |
| Crescimento de TIME_WAIT no upstream | Ausência de `keepalive` no bloco upstream | Adicionar `keepalive 64`, `proxy_http_version 1.1`, `proxy_set_header Connection ""` |
| 403 em `/dash/.../<segment>.m4s` a partir de clientes de console | O cliente resolve os URLs relativos a partir do URL anterior ao redirecionamento | O servidor emite `<BaseURL>` com caminho absoluto; compatível no build atual |
| Travamentos e rebuffering frequente em clientes remotos | Throughput TCP efetivo baixo devido a slow start e idle restart com RTT elevado (300 ms e acima) | Ajuste da pilha de rede do Linux no origin: ver 10.1 |

### 10.1. Ajuste TCP do origin para clientes de alto RTT

O problema manifesta-se em clientes com RTT elevado até o origin (por exemplo, 300 ms e acima) quando o bitrate do fluxo está próximo da capacidade do canal. Os sintomas no player são rebuffering frequente e interrupções; no servidor, o cliente aparenta estar normal e não há erros.

Causa:

- **TCP slow start.** Cada nova conexão TCP começa com uma congestion window de cerca de 14 KB e aumenta-a ao longo de vários RTT. Com RTT de 300 ms, atingir a janela completa leva 2–3 segundos. Nesse tempo, um segmento HLS/DASH com duração de 5 s (4–6 MB) é baixado sensivelmente mais devagar do que em tempo real.
- **TCP idle restart.** Entre as requisições de segmentos, o cliente no modelo pull do HLS faz uma pausa de 4–5 s. Por padrão, após tal pausa o kernel do Linux redefine a congestion window da conexão de volta ao initial cwnd (comportamento de `net.ipv4.tcp_slow_start_after_idle=1`). Como resultado, no GET seguinte a conexão keep-alive inicia a transmissão a partir do slow start novamente — mesmo em uma sessão já aquecida.

Adicionalmente, a situação é agravada pelo fato de que o congestion control CUBIC padrão lida mal com RTT longos e com perdas de pacotes em trechos intermediários da rede.

A solução consiste em dois parâmetros sysctl no origin:

```bash
# Keep congestion window across idle pauses inside keep-alive sessions.
sysctl -w net.ipv4.tcp_slow_start_after_idle=0

# Use BBR instead of CUBIC: better behaviour on long-RTT paths
# with mild packet loss; paces sending instead of bursting.
modprobe tcp_bbr
sysctl -w net.ipv4.tcp_congestion_control=bbr
```

Para aplicação permanente:

```bash
cat > /etc/sysctl.d/99-pss-net.conf <<EOF
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_congestion_control    = bbr
EOF
sysctl --system
```

O efeito principal vem do primeiro parâmetro (`tcp_slow_start_after_idle=0`) — ele elimina diretamente o slow start repetido entre as requisições de segmentos dentro de uma mesma conexão keep-alive. O segundo (BBR) confere robustez adicional e aplica-se a todas as novas conexões. O ajuste não requer a reinicialização do Perfect Streamer. Aos clientes HTTP/3 (QUIC) esses parâmetros não se aplicam: o QUIC funciona sobre UDP com o seu próprio controle de congestionamento.

## 11. Segurança

### 11.1. Session URL

Um URL do formato `/h<sess>/...` desempenha a função de token de sessão — não requer autenticação repetida. O tempo de vida é limitado por um timeout de inatividade de 60 segundos; na ausência de atividade a sessão é removida automaticamente.

Requisitos:

- HTTPS para todos os caminhos OTT (`/hls/`, `/dash/`, `/h<sess>/`) em produção;
- O Session ID no cabeçalho `Location` da resposta 302 não é armazenado em cache (`no-cache, no-store`).

### 11.2. Rate limiting

```nginx
limit_req_zone $binary_remote_addr zone=dash_top:10m  rate=5r/s;
limit_req_zone $binary_remote_addr zone=hls_top:10m   rate=5r/s;
limit_req_zone $binary_remote_addr zone=llhls_top:10m rate=5r/s;

server {
    location /dash/ {
        limit_req zone=dash_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
    location /hls/ {
        limit_req zone=hls_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
    location /llhls/ {
        limit_req zone=llhls_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
}
```

O Session URL (`/h<sess>/`) não requer rate limiting — o processamento é barato e as respostas são armazenadas em cache.

### 11.3. Cache das respostas com erro

```nginx
proxy_cache_valid 200 60s;
proxy_cache_valid 301 302 0s;
proxy_cache_valid 404 403 0s;
proxy_cache_valid any 1s;
```

Proíbe o cache dos redirecionamentos (sess único em Location) e das respostas com erros de autorização ou de recurso inexistente.

### 11.4. Restrição do acesso de rede ao origin

A porta do servidor HTTP de streaming (43972 por padrão; 43982 para HTTPS) deve estar fechada ao tráfego externo. Configurações admissíveis:

1. Bind do Perfect Streamer em `127.0.0.1` (com nginx local)
2. Regra de firewall:

```
iptables -A INPUT -p tcp -m multiport --dports 43972,43982 ! -s 10.0.0.0/8 -j DROP
```

## 12. Integração com middleware

### 12.1. Modelo prefix-login

O Perfect Streamer suporta a delegação da identificação do usuário a um sistema de middleware através do mecanismo prefix-login — uma alternativa integrada à integração completa com o faturamento externo (as contas verificadas por um sistema externo são configuradas na tela «Usuários / Logins», aba «Remoto (faturação)», [Usuários / Logins](../webui/configure.md#webui-users)).

No login local é ativado o indicador de prefixo, após o que o servidor aceita URLs com um login da forma `<prefix><id_do_assinante>`:

```
/dash/test1/sub42/xxx/index.mpd
/hls/test1/sub43/xxx/index.m3u8
```

Aqui `sub` é o prefixo de login configurado e `42`/`43` são os identificadores dos assinantes do middleware; a senha é comum.

### 12.2. Estatísticas por assinante

Na lista de clientes, cada sessão carrega tanto o login de configuração quanto o login de URL real do assinante (match-login), pelo qual o middleware associa as sessões aos seus próprios assinantes. Os dados são visíveis na tela «Clientes» ([Clientes](../webui/monitor.md#webui-clients)).

### 12.3. Limitações do prefix-login

- **Senha comum.** Todos os assinantes do pool de prefixo utilizam um único valor de senha. O comprometimento da senha concede acesso a qualquer `<prefix><cadeia>`.
- **Granularidade de acesso.** A lista de fluxos permitidos aplica-se a todo o pool de prefixo. O acesso ao nível de um assinante individual é assegurado pela integração com o faturamento externo.
- **Rotação da senha.** A alteração da senha desconecta todos os assinantes ativos. Para uma substituição gradual é necessário o uso temporário de dois prefix-logins.
