Có thể chạy python SimpleHTTPServer chỉ trên localhost không?


87

Tôi có kết nối vpn và khi tôi đang chạy python -m SimpleHTTPServer, nó phục vụ trên 0.0.0.0:8000, có nghĩa là nó có thể được truy cập qua localhost qua ip thực của tôi. Tôi không muốn rô bốt quét mình và quan tâm rằng máy chủ sẽ chỉ được truy cập thông qua localhost.

Có khả thi không?

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

Bất kỳ máy chủ http đơn giản nào khác có thể được thực thi ngay lập tức bằng dòng lệnh cũng được hoan nghênh.


4
Bạn chỉ cần chặn các kết nối bên ngoài trên cổng đó từ tường lửa / bộ định tuyến của mình.
Burhan Khalid

8
Trong khi một câu hỏi hay cho python2, nó có thể được lưu ý ở đây là trong python3 thay thế http.servercho phép ràng buộc ngay lập tức, ví dụ như python3 -m http.server --bind 127.0.0.1 8000sẽ đủ
humanityANDpeace

1
Sidenote : SimpleHTTPServerlà một luồng và chặn, có nghĩa là bạn sẽ không thể thực hiện một yêu cầu khác cho đến khi yêu cầu trước đó kết thúc. Và nó không có hỗ trợ phạm vi, ví dụ như phát trực tuyến / tìm kiếm tệp phương tiện từ một vị trí cụ thể. Một giải pháp thay thế tốt hơn là twisted( pip install twisted) mà bạn có thể chạy với twistd -n web --path /. Nó cũng có thể thực hiện FTP ẩn danh với twistd -n ftp -p 2121 -r /. Thêm một lớp lót cho máy chủ http: gist.github.com/willurd/5720255 .
ccpizza

Câu trả lời:


54

Nếu bạn đọc mã nguồn, bạn sẽ thấy rằng chỉ có thể ghi đè cổng trên dòng lệnh. Nếu bạn muốn thay đổi máy chủ mà nó được phục vụ, bạn sẽ cần phải triển khai test()phương thức của SimpleHTTPServerBaseHTTPServerchính bạn. Nhưng điều đó sẽ thực sự dễ dàng.

Đây là cách bạn có thể làm điều đó, khá dễ dàng:

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

Và để sử dụng nó:

> 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 ...

95

Trong phiên bản Python 3.4 trở lên, http.servermô-đun chấp nhận một bindtham số.

Theo tài liệu :

python -m http.server 8000

Theo mặc định, máy chủ tự liên kết với tất cả các giao diện. Tùy chọn -b / - bind chỉ định một địa chỉ cụ thể mà nó sẽ liên kết. Ví dụ: lệnh sau khiến máy chủ chỉ liên kết với localhost:

python -m http.server 8000 --bind 127.0.0.1

Mới trong phiên bản 3.4: Đối số --bind đã được giới thiệu.


75

Như @sberry đã giải thích, việc thực hiện đơn giản bằng cách sử dụng python -m ...phương pháp tốt sẽ không thể thực hiện được, vì địa chỉ IP được mã hóa cứng trong quá trình triển khai BaseHttpServer.testchức năng.

Một cách thực hiện điều đó từ dòng lệnh mà không cần viết mã vào tệp trước tiên sẽ là

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

Nếu điều đó vẫn được tính là một lớp lót phụ thuộc vào chiều rộng thiết bị đầu cuối của bạn ;-) Nó chắc chắn không dễ nhớ lắm.


4
Thêm cái này vào .bash_profile. Yum. Bây giờ tôi có thể chỉ cần gõ H. Cảm ơn! - gist.github.com/cmawhorter/f2a09bcf63c68b0cff10
Cory Mawhorter 21/10/14

4
Để nó hoạt động như một máy chủ http đơn giản trên windows 10 bằng Python 3.5.1, tôi đã phải thay đổi nó như sau: python -c "import http.server as hs; hs.HTTPServer(('127.0.0.1', 8888), hs.SimpleHTTPRequestHandler).serve_forever()" Lưu ý sự thay đổi trong báo giá và thực tế là Máy chủ HTTP cơ sở và Đơn giản hiện đang ở trong http.server.
Alexander Varwijk

+1 khi sử dụng bí danh hồ sơ, tôi đã gọi là 'servelocal' - có một chút thay đổi và thoát khỏi dấu ngoặc kép để làm cho cú pháp bash hài lòng, nhưng kết quả là tốt.
sdupton

Rất hữu ích ... :)
user3145373 ツ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.