Habilite o controle de acesso no servidor HTTP simples

121

Eu tenho o seguinte script de shell para um servidor HTTP muito simples:

#!/bin/sh

echo "Serving at http://localhost:3000"
python -m SimpleHTTPServer 3000

Eu queria saber como posso habilitar ou adicionar um cabeçalho CORS como Access-Control-Allow-Origin: *neste servidor?

MChan
fonte

Respostas:

197

Infelizmente, o servidor HTTP simples é realmente tão simples que não permite nenhuma personalização, especialmente para os cabeçalhos que envia. No entanto, você mesmo pode criar um servidor HTTP simples, usando a maior parte dele SimpleHTTPRequestHandler, e apenas adicionar o cabeçalho desejado.

Para isso, basta criar um arquivo simple-cors-http-server.py(ou qualquer outro) e, dependendo da versão do Python que estiver usando, coloque um dos seguintes códigos dentro dele.

Então você pode fazer python simple-cors-http-server.pye ele irá lançar seu servidor modificado que irá definir o cabeçalho CORS para cada resposta.

Com o shebang no topo, torne o arquivo executável e coloque-o em seu PATH, e você também pode executá-lo usando simple-cors-http-server.py.

Solução Python 3

Python 3 usa SimpleHTTPRequestHandlere HTTPServerdo http.servermódulo para executar o servidor:

#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)

Solução Python 2

Python 2 usa SimpleHTTPServer.SimpleHTTPRequestHandlere o BaseHTTPServermódulo para executar o servidor.

#!/usr/bin/env python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
import BaseHTTPServer

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    BaseHTTPServer.test(CORSRequestHandler, BaseHTTPServer.HTTPServer)

Solução Python 2 e 3

Se você precisa de compatibilidade para Python 3 e Python 2, pode usar este script poliglota que funciona em ambas as versões. Primeiro, ele tenta importar dos locais do Python 3 e, caso contrário, volta para o Python 2:

#!/usr/bin/env python
try:
    # Python 3
    from http.server import HTTPServer, SimpleHTTPRequestHandler, test as test_orig
    import sys
    def test (*args):
        test_orig(*args, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
except ImportError: # Python 2
    from BaseHTTPServer import HTTPServer, test
    from SimpleHTTPServer import SimpleHTTPRequestHandler

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer)
cutucar
fonte
Segui as instruções, mas ao executar python simple-cors-http-server.py recebo o erro: python: não é possível abrir o arquivo 'simple-cors-http-server.py': [Errno 2] Não existe esse arquivo ou diretório logout ....Alguma ideia?
MChan de
4
@poke O servidor responde com o método 501 não suportado ('OPÇÕES'). Estou executando o OS X 10.10.1 com Python 2.7.6. Alguma sugestão? HTTP/1.0 501 Unsupported method ('OPTIONS') Server: SimpleHTTP/0.6 Python/2.7.6 Date: Wed, 21 Jan 2015 23:16:10 GMT Content-Type: text/html Connection: close Access-Control-Allow-Origin: *
HairOfTheDog
1
@HairOfTheDog O SimpleHTTPRequestHandler não suporta o método OPTIONS HTTP. Você pode adicioná-lo se quiser (leia o manual do Python sobre servidores HTTP); ou você simplesmente não pode tentar acessar o servidor dessa forma.
toque em
2
@RobertoFranceschini Você pode estar encontrando solicitações pré- iluminadas que exigem que o OPTIONSmétodo seja implementado corretamente. Quanto a solicitações simples, a solução de enviar apenas o Access-Control-Allow-Origincabeçalho ainda deve funcionar bem.
toque em
1
@ Tyguy7 Esse pode ser um comportamento geral com o servidor HTTP simples. Eu tive resultados variados em relação ao desempenho antes. Mas por simplesmente rodar um servidor por um momento, ainda considero a solução mais rápida.
cutucar
108

Tente uma alternativa como servidor http

Como SimpleHTTPServer não é realmente o tipo de servidor que você implanta para produção, estou assumindo aqui que você não se preocupa muito com a ferramenta que usa, desde que faça o trabalho de expor seus arquivos http://localhost:3000com cabeçalhos CORS de uma forma simples linha de comando

# install (it requires nodejs/npm)
npm install http-server -g

#run
http-server -p 3000 --cors

Precisa de HTTPS?

Se você precisa de https no local, também pode tentar caddy ou certbot


Algumas ferramentas relacionadas que você pode achar úteis

  • ngrok : ao ser executado ngrok http 3000, cria uma url https://$random.ngrok.comque permite que qualquer pessoa acesse seu http://localhost:3000servidor. Ele pode expor ao mundo o que é executado localmente em seu computador (incluindo back-ends / apis locais)

  • localtunnel : quase o mesmo que ngrok

  • agora : quando em execução now, ele carrega seus ativos estáticos online e os distribui https://$random.now.sh. Eles permanecem online para sempre, a menos que você decida o contrário. A implantação é rápida (exceto a primeira) graças ao diffing. Agora é adequado para implantação de código de frontend / SPA de produção. Ele também pode implantar aplicativos Docker e NodeJS. Não é realmente gratuito, mas eles têm um plano gratuito.

Sebastien Lorber
fonte
5
Sou um homem simples. Vejo uma solução que requer instalação npmem uma máquina que só se sabe ter python, eu voto negativo.
Parthian Shot
6
@ParthianShot: você pode querer aprender a usar a melhor ferramenta para o trabalho.
Dan Dascalescu
2
@ParthianShot Muitos desenvolvedores já têm node / npm instalado. E o título da pergunta é genérico o suficiente para direcionar um grande público de usuários que claramente não se importam com python ou SimpleHTTPServer, o que é confirmado por votos positivos. Não é porque não é útil para você que é para todos. Existem boas razões para não gostar do Node e do Python também. Coisas como leftpad / publicação incorreta / uso incorreto do git parecem totalmente não relacionados a mim.
Sebastien Lorber
5
Adicionar uma linguagem e estrutura adicionais incorre em dívidas técnicas e aumenta a superfície de ataque de um ambiente. "Erros fatais podem ser cometidos em qualquer linguagem de programação" Verdade, mas JS torna isso mais fácil do que a maioria das outras linguagens. E cada idioma tem pegadinhas; quanto menos linguagens você usa, menos provável é que algum desenvolvedor que não esteja familiarizado com uma das linguagens cometa um erro que não seria um erro em outro idioma.
Parthian Shot
2
É como adotar uma criança toda vez que precisar de ajuda em casa; ele cria mais problemas do que resolve no futuro.
Parthian Shot
1

Eu tive o mesmo problema e cheguei a esta solução:

class Handler(SimpleHTTPRequestHandler):
    def send_response(self, *args, **kwargs):
        SimpleHTTPRequestHandler.send_response(self, *args, **kwargs)
        self.send_header('Access-Control-Allow-Origin', '*')

Simplesmente criei uma nova classe herdada de SimpleHTTPRequestHandler que apenas altera o send_responsemétodo.

Hugo Trentesaux
fonte
0

Você precisará fornecer suas próprias instâncias de do_GET () (e do_HEAD () se escolher suportar operações HEAD). algo assim:

class MyHTTPServer(SimpleHTTPServer):

    allowed_hosts = (('127.0.0.1', 80),)

    def do_GET(self):
        if self.client_address not in allowed_hosts:
            self.send_response(401, 'request not allowed')
        else:
            super(MyHTTPServer, self).do_Get()
user590028
fonte
Obrigado por sua resposta, mas eu não tenho nenhum conhecimento de Python, estou apenas usando o script de shell mencionado acima como um servidor http simples para meus aplicativos Emberjs. Só quando colidi com o problema de controle de acesso, pesquisei para descobrir que preciso habilitá-lo neste servidor http simples. Então, depois de alguma pesquisa, adicionei (habilite 'CrossOrigin', origins => '*';) mas não surpreendentemente não funcionou. Se você puder, por favor, me indique qualquer script de shell de servidor http simples do Python que inclua o recurso de controle de acesso que será muito apreciado
MChan
Em uma nota menor, não estou tentando ser preguiçoso aqui, realmente, mas começar a aprender Python apenas para adicionar esse recurso ao servidor simpleHTTP não parece lógico neste ponto, então eu esperava que fosse fácil de adicionar OU espero que eu possa encontrar um script Python alternativo / pronto para fazer o trabalho para que eu possa continuar com meu trabalho de desenvolvimento
MChan
3
O SimpleHTTPServer não tem opções para suportar controles de acesso. Você precisará criar seu próprio código - ou alternar para outro servidor da web que ofereça suporte a controles de acesso. Pense em lighttpd.net
user590028