Отправить изображение через http Python - PullRequest
0 голосов
/ 20 мая 2018

Мне нужно создать http-сервер без использования библиотеки HTTP.

У меня работает сервер и загружается html-страница, но мои теги <img src="..."/> не загружаются, я получаю вызов, но не могупредварительно установить png / JPEG на странице.

httpServer.py

# Define socket host and port
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 8000

# Create socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((SERVER_HOST, SERVER_PORT))
server_socket.listen(1)
print('Listening on port %s ...' % SERVER_PORT)

while True:
    # Wait for client connections
    client_connection, client_address = server_socket.accept()

    # Handle client request
    request = client_connection.recv(1024).decode()
    content = handle_request(request)

    # Send HTTP response
    if content:
        response = 'HTTP/1.1 200 OK\n\n'
        response += content
    else:
        response = 'HTTP/1.1 404 NOT FOUND\n\nFile Not Found'

    client_connection.sendall(response.encode())
    client_connection.close()

# Close socket
server_socket.close()

Функция, которая обрабатывает вызов класса

 def handle_request(request):
    http = HttpHandler.HTTPHandler

    # Parse headers
    print(request)
    headers = request.split('\n')
    get_content = headers[0].split()

    accept = headers[6].split()
    type_content = accept[1].split('/')

    try:
        # Filename
        filename = get_content[1]

        if get_content[0] == "GET":
            content = http.get(None, get_content[1], type_content[0])


        return content
    except FileNotFoundError:
        return None

для обработки глаголов http

class HTTPHandler:

    def get(self, args, type):
        if args == '/':
            args = '/index.html'
            fin = open('htdocs' + args)
        if type != "image":
            fin = open('htdocs/' + args)

        if type == "image":
            fin = open('htdocs/' + args, 'rb')

        # Read file contents
        content = fin.read()
        fin.close()
        return content

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

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

httpServer.py

Завершается как:

while True:
# Wait for client connections
client_connection, client_address = server_socket.accept()

# Handle client request
request = client_connection.recv(10240).decode()
content = handle_request(request)

# Send HTTP response
if content:
    if str(content).find("html") > 0:
        client_connection.send('HTTP/1.1 200 OK\n\n'.encode())
        client_connection.send(content.encode())
    else:
        client_connection.send('HTTP/1.1 200 OK\r\n'.encode())
        client_connection.send("Content-Type: image/jpeg\r\n".encode())
        client_connection.send("Accept-Ranges: bytes\r\n\r\n".encode())
        client_connection.send(content)
else:
    response = 'HTTP/1.1 404 NOT FOUND\r\nFile Not Found'

client_connection.close()

И метод Get вроде:

class HTTPHandler:

def get(self, args, type):
    if args == '/':
        args = '/index.html'
        fin = open('htdocs' + args)
    if type != "image":
        fin = open('htdocs/' + args)

    if type.find("html") == -1:
        image_data = open('htdocs/' + args, 'rb')
        bytes = image_data.read()

        # Content-Type: image/jpeg, image/png \n\n
        content = bytes
        fin.close()
        return content

    # Read file contents
    content = fin.read()
    fin.close()
    return content
0 голосов
/ 20 мая 2018

Я не знаю, где вы узнали, как работает HTTP, но я почти уверен, что вы не изучали действительный стандарт , который вы должны делать при реализации протокола.Некоторые замечания о вашей реализации:

  • Концы строк должны быть \r\n, а не \n.Это верно для обоих ответов от сервера в виде запросов от клиента.
  • Вы предполагаете, что запросы клиентов никогда не превышают 1024 байта и что они могут быть прочитаны в одном recv.Но запросы могут иметь произвольную длину, и нет никакой гарантии, что вы получите все в течение одного recv (TCP является протоколом потоковой передачи, а не протоколом сообщений).
  • Хотя это нормально, просто закрытьTCP-соединение после тела было бы лучше включить длину тела в заголовок Content-length или использовать кодировку передачи по частям.
  • Тип содержимого должен быть задан с использованием заголовка Content-Type, т.е. Content-type: text/html для HTML и Content-type: image/jpeg для изображений JPEG.Без этого браузер может правильно или неправильно угадать, какой тип может быть, или в зависимости от контекста может также настаивать на правильном заголовке типа контента.

Кроме того, если вы устраняете такие проблемы, это полезновыяснить, что фактически обменивается между клиентом и сервером.Возможно, вы сами это проверили, но не включили такую ​​информацию в свой вопрос.Ваше единственное описание ошибки: "... Я принимаю вызов, но не могу предварительно настроить png / JPEG на странице" , а затем получить дамп вашего кода.

...