Могу ли я установить заголовок с помощью python SimpleHTTPServer?

Я использую SimpleHTTPServer для проверки некоторых веб-страниц, над которыми я работаю. Он отлично работает, однако мне нужно выполнить некоторые междоменные запросы. Для этого требуется установить заголовок Access-Control-Allow-Origin с доменами, на которые разрешен доступ к странице.

Есть ли простой способ установить заголовок с SimpleHTTPServer и обслуживать исходное содержимое? Заголовок будет одинаковым при каждом запросе.

Ответ 1

Это немного хак, потому что он изменяет поведение end_headers(), но я думаю, что он немного лучше, чем копирование и вставка всего файла SimpleHTTPServer.py.

Мой подход переопределяет end_headers() в подклассе и в нем вызывает send_my_headers(), а затем вызывает суперкласс end_headers().

Это не 1 - 2 строки, менее 20; в основном шаблон.

#!/usr/bin/env python
import SimpleHTTPServer

class MyHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_my_headers()

        SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)

    def send_my_headers(self):
        self.send_header("Access-Control-Allow-Origin", "*")


if __name__ == '__main__':
    SimpleHTTPServer.test(HandlerClass=MyHTTPRequestHandler)

Ответ 2

Я бы сказал, что нет простого способа сделать это, где просто означает "просто добавить 1-2 строки, которые будут писать дополнительный заголовок и сохранить существующую функциональность". Таким образом, лучшим решением будет подкласс класса SimpleHTTPRequestHandler и повторная реализация функциональности с добавлением нового заголовка.

Проблема, почему нет простого способа сделать это, можно наблюдать, посмотрев на реализацию класса SimpleHTTPRequestHandler в библиотеке Python: http://hg.python.org/cpython/file/19c74cadea95/Lib/http/server.py#l654

Обратите внимание на метод send_head(), особенно на строки в конце метода, которые отправляют заголовки ответов. Обратите внимание на вызов метода end_headers(). Этот метод записывает заголовки на вывод вместе с пустой строкой, которая сигнализирует о конце всех заголовков и начале тела ответа: http://docs.python.org/py3k/library/http.server.html#http.server.BaseHTTPRequestHandler.end_headers

Следовательно, было бы невозможно подклассифицировать обработчик SimpleHTTPRequestHandler, вызвать метод суперкласса do_GET(), а затем просто добавить другой заголовок - поскольку отправка заголовков уже завершена, когда вызов super-class do_GET() возвращает метод. И он должен работать так, потому что метод do_GET() должен отправить тело (запрошенный файл) и отправить тело - он должен завершить отправку заголовков.

Итак, опять же, я думаю, вы застряли в подклассификации класса SimpleHTTPRequestHandler, реализуя его точно как код в библиотеке (просто скопируйте-вставьте его?) и добавьте еще один заголовок перед вызовом end_headers() в send_head():

...
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
# this below is the new header
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
return f
...

Ответ 3

# coding: utf-8
import SimpleHTTPServer
import SocketServer
PORT = 9999

def do_GET(self):
    self.send_response(200)
    self.send_header('Access-Control-Allow-Origin', 'http://example.com')           
    self.end_headers()

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
Handler.do_GET = do_GET
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()

Ответ 4

Хотя это более старый ответ, его первый результат в google...

В основном то, что предложил @iMon0... Кажется правильным?.. Пример doPOST

def do_POST(self):
    self.send_response
    self.send_header('Content-type','application/json')
    self.send_header('Access-Control-Allow-Origin','*')
    self.end_headers()
    sTest = {}
    sTest['dummyitem'] = "Just an example of JSON"
    self.wfile.write(json.dumps(sTest))

Таким образом, поток чувствует себя правильно.

1: вы получаете запрос

2: вы применяете заголовки и тип ответа, который вы хотите

3: вы отправляете обратно нужные данные, будь то то, что вам нужно, и когда вы хотите.

Приведенный выше пример отлично работает для меня и может быть расширен дальше, его просто голосовой почтовый сервер JSON. Так что я оставлю это здесь на SOF, если кому-то это понадобится, или я сам вернусь через несколько месяцев для этого.

Это создает действительный файл JSON только с объектом sTest, таким же, как страница/файл, созданный PHP.