Czy można uruchomić Python SimpleHTTPServer tylko na hoście lokalnym?

87

Mam połączenie VPN i kiedy używam Pythona -m SimpleHTTPServer, obsługuje on 0.0.0.0:8000, co oznacza, że ​​można uzyskać do niego dostęp przez localhost i przez mój prawdziwy adres IP. Nie chcę, aby roboty mnie skanowały i interesuje mnie, że serwer będzie dostępny tylko przez localhost.

Czy to możliwe?

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

Każdy inny prosty serwer http, który można uruchomić natychmiast za pomocą wiersza poleceń, również jest mile widziany.

user1639431
źródło
4
Możesz po prostu zablokować zewnętrzne połączenia na tym porcie ze swojej zapory / routera.
Burhan Khalid
8
Chociaż dobre pytanie do pythona2, można tutaj zauważyć, że w pythonie3 zastąpienie http.serverpozwala na natychmiastowe powiązanie, np. python3 -m http.server --bind 127.0.0.1 8000Wystarczyłoby
ludzkość i pokój
1
Uwaga dodatkowa : obsługuje jednowątekSimpleHTTPServer i blokuje, co oznacza, że ​​nie będzie można wykonać kolejnego żądania, dopóki poprzednie żądanie nie zostanie zakończone. I nie ma wsparcia zasięgu, np. Do przesyłania strumieniowego / wyszukiwania pliku multimedialnego z określonej pozycji. Lepszą alternatywą jest twisted( pip install twisted), z którą możesz uruchomić twistd -n web --path /. Może również wykonywać anonimowe FTP z twistd -n ftp -p 2121 -r /. Więcej jednoliniowych adresów serwera http: gist.github.com/willurd/5720255 .
ccpizza

Odpowiedzi:

54

Jeśli przeczytasz źródło, zobaczysz, że tylko port może zostać zastąpiony w linii poleceń. Jeśli chcesz zmienić hosta, na którym jest obsługiwany, musisz zaimplementować test()metodę SimpleHTTPServeri BaseHTTPServersamodzielnie. Ale to powinno być naprawdę łatwe.

Oto, jak możesz to zrobić dość łatwo:

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()

I aby z niego skorzystać:

> 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
źródło
95

W wersji Python 3.4 i nowszych http.servermoduł akceptuje bindparametr.

Według dokumentów :

python -m http.server 8000

Domyślnie serwer wiąże się ze wszystkimi interfejsami. Opcja -b / - bind określa konkretny adres, z którym ma się wiązać. Na przykład poniższe polecenie powoduje, że serwer łączy się tylko z hostem lokalnym:

python -m http.server 8000 --bind 127.0.0.1

Nowość w wersji 3.4: wprowadzono argument --bind.

Jet Blue
źródło
75

Jak wyjaśnił @sberry , po prostu zrobienie tego przy użyciu ładnej python -m ...metody nie będzie możliwe, ponieważ adres IP jest zakodowany na stałe w implementacji BaseHttpServer.testfunkcji.

Sposobem na zrobienie tego z wiersza poleceń bez wcześniejszego pisania kodu do pliku byłoby

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

To, czy nadal liczy się jako jeden wkład, zależy od szerokości terminala ;-) Z pewnością nie jest to łatwe do zapamiętania.

Lukas Graf
źródło
4
Dodanie tego do .bash_profile. Mniam. Teraz mogę po prostu pisać H. Dzięki! - gist.github.com/cmawhorter/f2a09bcf63c68b0cff10
Cory Mawhorter
4
Aby ten działał jako prosty serwer http w systemie Windows 10 przy użyciu Pythona 3.5.1, musiałem to zmienić w następujący sposób: python -c "import http.server as hs; hs.HTTPServer(('127.0.0.1', 8888), hs.SimpleHTTPRequestHandler).serve_forever()" Zwróć uwagę na zmianę w cudzysłowie oraz fakt, że podstawowy i prosty serwer HTTP znajdują się teraz w http.server.
Alexander Varwijk,
+1 za pomocą aliasu profilu, nazwałem mój „servelocal” - jest trochę tańca zmieniającego i unikającego cudzysłowów, aby uczynić składnię basha szczęśliwą, ale wynik jest ładny.
sdupton,
Bardzo pomocny ... :)
user3145373 ツ