Включить контроль доступа на простом HTTP-сервере

У меня есть следующий скрипт для очень простого HTTP-сервера:

#!/bin/sh

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

Мне было интересно, как я могу включить или добавить заголовок CORS, например Access-Control-Allow-Origin: * на этот сервер?

Ответ 1

К сожалению, простой HTTP-сервер действительно настолько прост, что не допускает никакой настройки, особенно для заголовков, которые он отправляет. Однако вы можете создать простой HTTP-сервер самостоятельно, используя большую часть SimpleHTTPRequestHandler, и просто добавить нужный заголовок.

Для этого просто создайте файл simple-cors-http-server.py (или любой другой) и, в зависимости от используемой версии Python, поместите один из следующих кодов внутрь.

Затем вы можете сделать python simple-cors-http-server.py и он запустит ваш измененный сервер, который будет устанавливать заголовок CORS для каждого ответа.

С притон в верхней части, сделать файл исполняемым и поместить его в PATH, и вы можете просто запустить его с помощью simple-cors-http-server.py тоже.

Решение Python 3

Python 3 использует SimpleHTTPRequestHandler и HTTPServer из модуля http.server для запуска сервера:

#!/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)

Решение Python 2

Python 2 использует SimpleHTTPServer.SimpleHTTPRequestHandler и модуль BaseHTTPServer для запуска сервера.

#!/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)

Решение Python 2 & 3

Если вам нужна совместимость как для Python 3, так и для Python 2, вы можете использовать этот скрипт polyglot, который работает в обеих версиях. Сначала он пытается импортировать из местоположений Python 3, а в противном случае возвращается к 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)

Ответ 2

Попробуйте альтернативу, такую как http-сервер

Так как SimpleHTTPServer на самом деле не тот тип сервера, который вы развертываете в рабочей среде, я предполагаю, что вам не важно, какой инструмент вы используете, если он выполняет работу по представлению ваших файлов на http://localhost:3000 с заголовками CORS в простой командной строке

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

#run
http-server -p 3000 --cors

Если вам нужен https на местном уровне, вы также можете попробовать Caddy


Некоторые связанные инструменты, которые вы можете найти полезными

  • ngrok: при запуске ngrok http 3000 он создает URL-адрес https://$random.ngrok.com который разрешает любому доступ к вашему серверу http://localhost:3000. Он может показать миру, что работает локально на вашем компьютере (включая локальные бэкэнды /apis)

  • localtunnel: почти такой же, как ngrok

  • сейчас: при запуске now он загружает ваши статические ресурсы в онлайн и развертывает их по https://$random.now.sh. Они остаются онлайн навсегда, если вы не решите иначе. Развертывание происходит быстро (за исключением первого) благодаря дифференцированию. Теперь подходит для развертывания производственного кода/кода SPA. Он также может развертывать приложения Docker и NodeJS. Это не совсем бесплатно, но у них есть бесплатный план.

Ответ 3

У меня была такая же проблема, и я пришел к такому решению:

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

Я просто создал новый класс, унаследованный от SimpleHTTPRequestHandler, который изменяет send_response метод send_response.

Ответ 4

Вам нужно будет предоставить свои собственные экземпляры do_GET() (и do_HEAD(), если вы хотите поддерживать операции HEAD). что-то вроде этого:

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