É possível executar python SimpleHTTPServer apenas no localhost?

87

Eu tenho uma conexão VPN e quando estou executando python -m SimpleHTTPServer, ele funciona em 0.0.0.0:8000, o que significa que pode ser acessado via localhost e via meu ip real. Não quero que robôs façam a varredura e estou interessado que o servidor seja acessado apenas via localhost.

É possível?

python -m SimpleHTTPServer 127.0.0.1:8000  # doesn't work.

Qualquer outro servidor http simples que possa ser executado instantaneamente usando a linha de comando também é bem-vindo.

user1639431
fonte
4
Você pode simplesmente bloquear conexões externas nessa porta do firewall / roteador.
Burhan Khalid
8
Embora seja uma boa pergunta para python2, pode-se notar aqui que em python3 a substituição http.serverpermite vinculação imediatamente, por exemplo, python3 -m http.server --bind 127.0.0.1 8000seria suficiente
humanidade e
1
Sidenote : SimpleHTTPServeré single-threading e bloqueador, o que significa que você não poderá fazer outra solicitação até que a solicitação anterior termine. E não tem suporte de alcance, por exemplo, para streaming / busca de um arquivo de mídia de uma posição específica. Uma alternativa melhor é twisted( pip install twisted) com o qual você pode executar twistd -n web --path /. Ele também pode fazer FTP anônimo com twistd -n ftp -p 2121 -r /. Mais one-liners de servidor http: gist.github.com/willurd/5720255 .
ccpizza

Respostas:

54

Se você ler o código-fonte, verá que apenas a porta pode ser substituída na linha de comando. Se quiser alterar o host em que ele é servido, você precisará implementar o test()método do SimpleHTTPServere BaseHTTPServervocê mesmo. Mas isso deve ser muito fácil.

Aqui está como você pode fazer isso, com bastante facilidade:

import sys
from SimpleHTTPServer import SimpleHTTPRequestHandler
import BaseHTTPServer


def test(HandlerClass=SimpleHTTPRequestHandler,
         ServerClass=BaseHTTPServer.HTTPServer):

    protocol = "HTTP/1.0"
    host = ''
    port = 8000
    if len(sys.argv) > 1:
        arg = sys.argv[1]
        if ':' in arg:
            host, port = arg.split(':')
            port = int(port)
        else:
            try:
                port = int(sys.argv[1])
            except:
                host = sys.argv[1]

    server_address = (host, port)

    HandlerClass.protocol_version = protocol
    httpd = ServerClass(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print "Serving HTTP on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()


if __name__ == "__main__":
    test()

E para usar:

> python server.py 127.0.0.1     
Serving HTTP on 127.0.0.1 port 8000 ...

> python server.py 127.0.0.1:9000
Serving HTTP on 127.0.0.1 port 9000 ...

> python server.py 8080          
Serving HTTP on 0.0.0.0 port 8080 ...
sberry
fonte
95

Nas versões 3.4 e superior do Python, o http.servermódulo aceita um bindparâmetro.

De acordo com a documentação :

python -m http.server 8000

Por padrão, o servidor se liga a todas as interfaces. A opção -b / - bind especifica um endereço específico ao qual deve se ligar. Por exemplo, o comando a seguir faz com que o servidor se vincule apenas ao host local:

python -m http.server 8000 --bind 127.0.0.1

Novo na versão 3.4: o argumento --bind foi introduzido.

Jet Blue
fonte
75

Como @sberry explicou, simplesmente fazer isso usando o python -m ...método nice não será possível, porque o endereço IP está codificado na implementação da BaseHttpServer.testfunção.

Uma maneira de fazer isso a partir da linha de comando sem escrever o código em um arquivo primeiro seria

python -c 'import BaseHTTPServer as bhs, SimpleHTTPServer as shs; bhs.HTTPServer(("127.0.0.1", 8888), shs.SimpleHTTPRequestHandler).serve_forever()'

Se isso ainda conta como um liner depende da largura do seu terminal ;-) Certamente não é muito fácil de lembrar.

Lukas Graf
fonte
4
Adicionando isso a .bash_profile. Yum. Agora posso apenas digitar H. Obrigado! - gist.github.com/cmawhorter/f2a09bcf63c68b0cff10
Cory Mawhorter
4
Para que isso funcione como um servidor http simples no windows 10 usando Python 3.5.1, tive que alterá-lo da seguinte maneira: python -c "import http.server as hs; hs.HTTPServer(('127.0.0.1', 8888), hs.SimpleHTTPRequestHandler).serve_forever()" Observe a mudança na cotação e o fato de que o servidor HTTP básico e simples agora estão em http.server.
Alexander Varwijk de
+1 sobre como usar o apelido de perfil, chamei o meu de 'servelocal' - há um pouco de dança mudando e escapando das aspas para tornar a sintaxe do bash feliz, mas o resultado é bom.
sdupton
Muito útil ... :)
user3145373 ツ