Inphinit Proxy

É uma biblioteca proxy destinada ao uso com html2canvas e similares do lado do cliente que exigem a superação das restrições CORS.

Embora desenvolvida como parte do framework Inphinit, esta biblioteca é totalmente independente e compatível com qualquer framework — ou mesmo com PHP puro.

Requisitos do sistema

  • Extensão cURL PHP para usar o CurlDriver
  • allow_url_fopen deve ser definido com o valor 1 no php.ini para pode usar o StreamDriver
  • (Opcional) Composer

Instalação

Você pode instalar via Composer:

composer require inphinit/proxy

Se você não estiver usando um framework, pode baixar a versão de https://github.com/inphinit/inphinit-php-proxy/archive/refs/tags/2.0.0-rc.2.zip, extraí-la, movê-la para o seu servidor web e, opcionalmente, renomear a pasta, por exemplo.

mv "inphinit-php-proxy-2.0.0-rc.2" proxy

Como usar

Em seguida, inclua isso em seu script ou controlador:

use Inphinit\Proxy\Proxy; use Inphinit\Proxy\Drivers\CurlDriver; use Inphinit\Proxy\Drivers\StreamDriver; $proxy = new Proxy(); // Set drivers used for download $proxy->setDrivers([ CurlDriver::class, StreamDriver::class ]); try { // Execute download $proxy->download($_GET['url']); // Display raw output $proxy->response(); } catch (Exception $ee) { $code = $ee->getCode(); $message = $ee->getMessage(); echo 'Error: (', $code, ') ', $message; }

Sem o autoload e o composer-autoload, é necessário incluir as classes manualmente:

use Inphinit\Proxy\Proxy; use Inphinit\Proxy\Drivers\CurlDriver; use Inphinit\Proxy\Drivers\StreamDriver; require_once '/path/proxy/src/CurlDriver.php'; require_once '/path/proxy/src/StreamDriver.php'; require_once '/path/proxy/src/Proxy.php'; $proxy = new Proxy(); ...

Para retornar a resposta do download diretamente para o navegador, use o método Proxy::response():

use Inphinit\Proxy\Proxy; use Inphinit\Proxy\Drivers\CurlDriver; use Inphinit\Proxy\Drivers\StreamDriver; $proxy = new Proxy(); $proxy->setDrivers([ CurlDriver::class, StreamDriver::class ]); $proxy->download($url); $proxy->response();

Se você deseja usar o formato JSONP, substitua o método Proxy::response() por Proxy::jsonp(). Neste exemplo, o callback retornará e receberá o conteúdo no formato DATA URI:

use Inphinit\Proxy\Proxy; use Inphinit\Proxy\Drivers\CurlDriver; use Inphinit\Proxy\Drivers\StreamDriver; if (empty($_GET['callback'])) { http_response_code(400); die('Missing callback'); } $proxy = new Proxy(); $proxy->setDrivers([ CurlDriver::class, StreamDriver::class ]); try { $proxy->download($url); $proxy->jsonp($_GET['callback']); } catch (Exception $ee) { }

Se você precisar manipular conteúdo, pode usar os métodos Proxy::getContents(), Proxy::getContentType() e Proxy::getHttpStatus():

use Inphinit\Proxy\Proxy; use Inphinit\Proxy\Drivers\CurlDriver; use Inphinit\Proxy\Drivers\StreamDriver; $proxy = new Proxy(); $proxy->setDrivers([ CurlDriver::class, StreamDriver::class ]); try { $proxy->download($url); // Success $contents = $proxy->getContents(); $contentType = $proxy->getContentType(); $httpStatus = $proxy->getHttpStatus(); ... } catch (Exception $ee) { $code = $ee->getCode(); $message = $ee->getMessage(); echo 'Error: (', $code, ') ', $message; }

Nos exemplos apresentados até agora, CurlDriver tem prioridade enquanto StreamDriver é usado como altertiva, mas você pode alterar isso. Em um exemplo hipotético, por exemplo, se você quiser usar apenas StreamDriver faça:

$proxy->setDrivers([ StreamDriver::class ]);

Você também pode limitar os URLs que o proxy pode acessar:

$proxy->setAllowedUrls([ 'https://domain1.com/', // Allows requests on any path to https://domain1.com 'https://domain2.com/images/', // Allows requests from the path /images/ on https://domain2.com 'https://*.mainsite.io/', // Allows requests on subdomains of mainsite.io 'https://foo.io:8000/', // Allows requests to foo.io with port 8000 '*://other.io/', // Allows HTTPS and HTTP requests to other.io ]); $proxy->download($url);

As opções genéricas permitem personalizar o comportamento do driver por meio de seus mecanismos de configuração nativos (opções cURL ou contextos de fluxo). Como cada driver pode exigir diferentes tipos de configurações, a abordagem mais flexível é permitir que essas opções armazenem qualquer valor. Isso é particularmente útil ao desenvolver um novo driver.

Para configurar o driver cURL, use 'curl' como primeiro parâmetro, por exemplo $proxy->setOptions('curl', [ ... ]), um exemplo para alterar a versão SSL:

$proxy->setOptions('curl', [ CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_3 ]);

Exemplo de como desativar a verificação SSL (para testes locais, não utilize em ambiente de produção):

$proxy->setOptions('curl', [ CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => false ]);

Para mais opções de constantes a serem usadas com $proxy->setOptions('curl', [ ... ]), consulte: https://www.php.net/manual/en/curl.constants.php

Para configurar o StreamDriver, use 'stream' como primeiro parâmetro em setOptions(), um exemplo para definir a versão do protocolo HTTP:

$proxy->setOptions('stream', [ 'http' => [ 'protocol_version' => 1.0, ] ]);

Exemplo de configuração SSL:

$proxy->setOptions('stream', [ 'ssl' => [ 'verify_peer' => true, 'cafile' => '/foo/bar/baz/cacert.pem', 'verify_depth' => 5, 'CN_match' => 'secure.example.com' ] ]);

Tipo de conteúdo permitido

Ao executar o método download(), será realizada uma validação do tipo de conteúdo (Content-Type). Por padrão, os seguintes tipos de conteúdo são permitidos:

Content-Type Proxy::jsonp()
image/apng base64
image/png base64
image/avif base64
image/webp base64
image/gif base64
image/jpeg base64
image/svg+xml codificado em URL
image/svg-xml codificado em URL

Você pode definir tipos de conteúdo adicionais permitidos, por exemplo:

$proxy->addAllowedType('image/x-icon', true); $proxy->addAllowedType('image/vnd.microsoft.icon', true);

O segundo parâmetro do método especifica se Proxy::jsonp() deve ser usada a codificação URL ou a codificação Base64 no esquema URI de dados.

Para remover um Content-Type permitido, use o Proxy::removeAllowedType() método, por exemplo:

$proxy->removeAllowedType('image/apng');

API

Método Descrição
setMaxDownloadSize(int $value): void Defina o tamanho máximo permitido para download.
getMaxDownloadSize(): int Obtenha o tamanho máximo de download permitido
setMaxRedirs(int $value): void Defina o número máximo de redirecionamentos HTTP.
getMaxRedirs(): int Obtenha o número máximo de redirecionamentos HTTP.
setReferer(string $value): void Defina o Referer: cabeçalho da solicitação.
getReferer(): string Obtenha o Referer: cabeçalho da solicitação
setTimeout(int $value): void Defina o tempo limite de conexão em segundos.
getTimeout(): int Obtenha o tempo limite de conexão em segundos.
setUserAgent(string $value): void Defina o User-Agent: cabeçalho da solicitação.
getUserAgent(): string Obtenha o User-Agent: cabeçalho da solicitação
setDrivers(array $drivers): void Defina a lista de nomes de classes de driver usadas para baixar recursos.
setControlAllowOrigin(string $origin): void Defina o Access-Control-Allow-Origin: cabeçalho
setControlAllowHeaders(array $headers): void Defina a lista de cabeçalhos permitidos.
setOptions(string $key, mixed $value): void Defina opções genéricas
getOptions([string $key]): mixed Obtenha opções genéricas
getOptionsUpdate(): int Retorna um contador incremental interno usado para determinar se as opções do driver foram alteradas.
setAllowedUrls(array $urls): void Defina a lista de URLs permitidas para download.
addAllowedType(string $type, bool $binary): void Adicione um Content-Type à lista de permitidos, true= codificação Base64, false= codificação de URL
removeAllowedType(string $type): void Remover um Content-Type da lista de permitidos
isAllowedType(string $type, string &$errorMessage): bool Verificar se uma determinada ação Content-Type é permitida (este método será usado pelos motoristas)
setTemporary(string $path): void Defina o caminho ou fluxo de armazenamento temporário para o conteúdo baixado (por exemplo, /mnt/storage/, php://temp, php://memory)
getTemporary(): resource|null Obtenha o recurso de fluxo temporário usado para o conteúdo baixado.
download(string $url): void Efetue o download
setResponseCacheTime(int $seconds): void Defina a duração do cache (em segundos) ou desative o cache para Proxy::response() ou Proxy::jsonp()
response(): void Despejar resposta para saída
jsonp(string $callback): void Saída de retorno JSONP com conteúdo de URL ou URI de dados
getContents([int $length[, int $offset]]): string|null Se o último download foi bem-sucedido, o conteúdo será retornado.
getContentType(): string|null Se o último download foi bem-sucedido, Content-Type o valor será retornado.
getHttpStatus(): int|null Se o último download foi bem-sucedido, o status HTTP será retornado.
reset(): void Redefinir último download
Página inicial
Apoie com uma estrela no GitHub