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

122

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

#!/bin/sh

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

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

MChan
источник

Ответы:

197

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

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

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

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

Решение Python 3

Python 3 использует модульSimpleHTTPRequestHandler and HTTPServerfrom для запуска сервера: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, вы можете использовать этот скрипт-полиглот, который работает в обеих версиях. Сначала он пытается импортировать из местоположений 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)
совать
источник
Я выполнил инструкции, но, выполнив python simple-cors-http-server.py, я получаю сообщение об ошибке: python: не удается открыть файл 'simple-cors-http-server.py': [Errno 2] Нет такого файла или выхода из каталога ....Есть предположения?
MChan
4
@poke Сервер отвечает 501 неподдерживаемым методом ('OPTIONS'). Я использую OS X 10.10.1 с Python 2.7.6. Какие-либо предложения? 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 SimpleHTTPRequestHandler не поддерживает HTTP-метод OPTIONS. Вы можете добавить его, если хотите (прочтите руководство Python о HTTP-серверах); или вы могли просто не пытаться получить доступ к серверу таким образом.
poke
2
@RobertoFranceschini Возможно, вы столкнулись с упреждающими запросами, которые требуют OPTIONSправильной реализации метода. Что касается простых запросов, решение с отправкой только Access-Control-Allow-Originзаголовка должно работать нормально.
тыкают
1
@ Tyguy7 Это может быть обычное поведение с простым HTTP-сервером. Раньше у меня были разные результаты относительно производительности. Но для простого запуска сервера на мгновение я все еще считаю это самым быстрым решением.
тыкает
108

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

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

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

#run
http-server -p 3000 --cors

Нужен HTTPS?

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


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

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

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

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

Себастьян Лорбер
источник
5
Я простой человек. Я вижу решение, которое требует установки npmна машину, о которой известно только python, я голосую против.
Парфянский выстрел
6
@ParthianShot: возможно, вы захотите научиться использовать лучший инструмент для работы.
Дэн Даскалеску
2
@ParthianShot Многие разработчики уже установили node / npm. И заголовок вопроса достаточно общий, чтобы привлечь большую аудиторию пользователей, которые явно не заботятся о python или SimpleHTTPServer, что подтверждается голосами за. Это не потому, что вам это не помогает, а для всех. Есть веские причины не любить и Node, и Python. Такие вещи, как использование leftpad / bad publish / bad git, кажутся мне совершенно не связанными.
Себастьен Лорбер
5
Добавление дополнительного языка и фреймворка влечет за собой технический долг и увеличивает поверхность атаки среды. «Фатальные ошибки могут быть сделаны на любом языке программирования» Верно, но JS делает этот способ проще, чем большинство других языков. И у каждого языка есть подводные камни; Чем меньше языков вы используете, тем меньше вероятность того, что разработчик, незнакомый с одним из языков, совершит ошибку, которая не была бы ошибкой на другом языке.
Парфянский выстрел
2
Это похоже на усыновление ребенка каждый раз, когда вам нужна помощь по дому; он создает больше проблем, чем решает в будущем.
Парфянский выстрел
1

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

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метод.

Hugo Trentesaux
источник
0

Вам нужно будет предоставить свои собственные экземпляры 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()
user590028
источник
Спасибо за ваш ответ, но я ничего не знаю о Python, я просто использую упомянутый выше сценарий оболочки в качестве простого HTTP-сервера для своих приложений Emberjs. Только когда я столкнулся с проблемой контроля доступа, я решил, что мне нужно включить его на этом простом HTTP-сервере. Итак, после некоторого исследования я добавил (включить 'CrossOrigin', origins => '*';), но неудивительно, что это не сработало. Если вы можете указать мне на любой простой сценарий оболочки HTTP-сервера Python, который включает функцию управления доступом, мы будем очень признательны
МЧан,
Вкратце, я не пытаюсь здесь лениться, но начать изучать python просто для того, чтобы добавить эту функцию к серверу simpleHTTP, на данный момент не звучит логично, поэтому я надеялся, что это будет легко добавить ИЛИ, надеюсь, я смогу найти альтернативный / готовый скрипт Python, который может выполнять эту работу, чтобы я мог продолжить свою работу по разработке
MChan
3
SimpleHTTPServer не имеет параметров для поддержки управления доступом. Либо вам нужно будет накрутить собственный код, либо переключиться на другой веб-сервер, поддерживающий контроль доступа. Подумайте о lighttpd.net
user590028