2015-06-30 2 views
0

Я использую этот класс, чтобы запустить HTTP-сервер в Python:Получить SimpleHTTPServer отправить заголовки ответа

class Server: 

    def __init__(self): 
     port = 81 
     httpd = SocketServer.ThreadingTCPServer(('', port), self.Proxy) 
     httpd.serve_forever() 

    class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): 

     def do_GET(self): 
      # just for demonstration: 
      url = "http://ovh.net/files/10Mio.dat" 
      opener = urllib2.build_opener() 
      handle = opener.open(url) 
      if hasattr(handle.info(), "headers"): 
       headers = handle.info().headers 
       for h in headers: 
        self.send_header(h[0], h[1]) 
      self.end_headers() 
      self.copyfile(handle, self.wfile) 

Но, к сожалению, не работает, как ожидалось. Если я отправлю запрос на сервер, я получаю файл, который немного больше, чем тот, который я ожидал бы. Когда я смотрю на это, я вижу, что заголовки ответов хранятся в начале этого файла. Сам ответ не содержит заголовков, поэтому я думаю, что SimpleHTTPServer закончил заголовки перед вызовом do_GET().

Я видел this answer и редактировать свой код соответственно:

class Server: 

    def __init__(self): 
     port = 81 
     httpd = SocketServer.ThreadingTCPServer(('', port), self.Proxy) 
     httpd.serve_forever() 



    class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): 

     def do_GET(self): 
      # get handle again 
      self.copyfile(handle, self.wfile) 

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

     def send_my_headers(self): 
      # Do something smart to get a file-like variable named handle 
      self.send_header("Access-Control-Allow-Origin", "*") 
      if hasattr(handle.info(), "headers"): 
       headers = handle.info().headers 
       for h in headers: 
        self.send_header(h[0], h[1]) 

Но это не имеет никакого значения. Заголовки ответов все еще заполнены в файле. Что тут происходит?

Редактировать: Я обновил свой первый пример, чтобы уточнить, что я имею в виду. То, что я хочу, немного похоже на HTTP-прокси: Мой сервер должен загрузить файл с другого сервера и просто отправить данные обратно клиенту. По некоторым причинам (было бы слишком много объяснять) я не могу использовать обычный прокси.

Теперь первый пример кода делает это довольно эффективно. Моя проблема заключается в том, что все заголовки теряются в процессе. Это означает, что клиент не знает размер загружаемого файла (таким образом отображается неопределенный индикатор выполнения) или имя файла (Content-disposition).

В моем втором примере кода я попытался отправить заголовки, которые я получил с восходящего сервера, но заголовки, кажется, закончены до вызова функции do_GET.

+0

Ваши намерения не ясны для меня. Не могли бы вы предоставить какой-нибудь (неправильный, как вы сказали) рабочий код? – Tupteq

+0

@Tupteq: Я обновил свой вопрос, чтобы уточнить, что я хочу делать. –

ответ

0

Ok, используя Wireshark я узнал, что на самом деле здесь не так:

Я забыл сделать

self.send_response(200) 

перед отправкой заголовков, которые посылает строку типа:

HTTP/1.1 200 OK 

Я предполагаю, что отсутствие этой строки заставляет HTTP-клиентов полагать, что сервер использует HTTP/0.9 и фактически неправильно заполняет заголовки.