Рубрики
Без рубрики

Рассекать веб-стек

Это было грубо. Они хотели, чтобы я рассел лягушку. (Beetlejuice, 1988) Введение Имея … помеченные архитектурой, www, python, https.

Это было грубо. Они хотели, чтобы я рассел лягушку. (BeetleJuice, 1988)

Недавно работал с молодыми веб-разработчиками, которые впервые выставили на правильную производственную инфраструктуру, я получил много вопросов о различных компонентах, которые можно найти в архитектуре «веб-сервиса». Эти вопросы явно выразили путаницу (а иногда и разочарование) разработчиков, которые понимают, как создавать конечные точки на языке высокого уровня, такими как node.js или python, но никогда не были введены в сложность того, что происходит между браузером пользователя и их Рамки выбора. Большинство времен, которые они не знают, почему сама рамки там в первую очередь.

Вызов ясен, если мы просто списком (в случайном порядке), некоторые слова, которые мы используем, когда мы обсудим (Python) Web Development: http, cookies, веб-сервер, Websockets, ftp, multi-threaded, обратный прокси, django, nginx , Статические файлы, пост, сертификаты, рамки, колбы, SSL, GET, WSGI, управление сеансом, TLS, балансировка нагрузки, Apache.

В этом посте я хочу просмотреть все слова, упомянутые выше (и еще пару), пытаясь построить готовый веб-сервис с нуля. Я надеюсь, что это может помочь молодым разработчикам получить всю фотографию и иметь смысл этих «неясных» названий, которые старшие разработчики, как у меня, как правило, бросают повседневные разговоры (иногда, возможно, вне поворота).

Поскольку в центре внимания поста является глобальная архитектура и причины наличия определенных компонентов, примерное обслуживание, которое я буду использовать, будет основной веб-страницей HTML. Справочный язык будет Python, но общая дискуссия относится к любому языку или структуре.

Мой подход будет то, что сначала заявило обоснование, а затем реализацию возможного решения. После этого я указываю на недостающие части или нерешенные проблемы и переходите на следующий слой. В конце процесса читатель должен иметь четкую картину того, почему каждый компонент был добавлен в систему.

Очень важная базовая концепция системных архитектур заключается в том, что нет Идеальное решение Разработанный некоторым мудреем гением, что нам просто нужно подать заявку. К сожалению, часто люди ошибаются конструктивные узоры для такого «магического решения». Оригинальная книга «Шаблоны дизайна», однако, гласит, что

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

А также потом

Шаблоны дизайна облегчают повторное использование успешных проектов и архитектур. […] Шаблоны дизайна помогают вам выбрать альтернативы дизайна, которые делают систему многоразовой и избегают альтернатив, которые компромиссная повторное использование.

Авторы книги обсуждают объектно-ориентированные программирование, но эти предложения могут быть применены к любой архитектуре. Как видите, у нас есть «проблема под рукой» и «дизайнерские альтернативы», что означает, что наиболее важно понять, это требования, как настоящие, так и будущие. Только с ясными требованиями в виду, можно эффективно разработать решение, возможно, нажав на большое количество шаблонов, которые уже разработаны другие дизайнеры.

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

Давайте кратко рассмотрим некоторые из самых важных концепций, участвующих в веб-стеке, протоколы.

TCP/IP

TCP/IP – это сетевой протокол, то есть Набор установленных правил Два компьютера должны следовать, чтобы подключиться к физической сети для обмена сообщениями. TCP/IP состоит из двух разных протоколов, охватывающих два разных слоях стека OSI, а именно транспорт (TCP) и сетевой (IP). TCP/IP могут быть реализованы сверху любого физического интерфейса (ссылка на данные и физические слои OSI), такие как Ethernet и Wireless. Актеры в сети TCP/IP идентифицируются розетка , который представляет собой кортеж из IP-адреса и номера порта.

Насколько нас беспокоит при разработке веб-сервиса, однако мы должны знать, что TCP/IP – это надежный Протокол, который в телекоммуникациях означает, что сам протокол позаботится или повторные передачи, когда пакеты теряются. Другими словами, хотя скорость связи не предоставлена, мы можем быть уверены, что после отправки сообщения он достигнет своего назначения без ошибок.

Http.

TCP/IP могут гарантировать, что необработанные байты один компьютер отправляет, достигнет своего назначения, но это листья полностью нетронута проблема о том, как отправить значимую информацию. В частности, в 1989 году проблема Тим Бернерс-Ли хотел решить, было то, как однозначно назвать гипертекстовые ресурсы в сети и как к ним доступ.

HTTP – это протокол, который был разработан для решения такой проблемы и с тех пор сильно развивался. С помощью других протоколов, таких как Websocket, HTTP, вторые области связи, для которых он изначально считался неподходящим таким как связь в реальном времени.

В своем ядре HTTP является протоколом, который утверждает, что формат текстового запроса и возможные текстовые ответы. Первоначальная версия 0.9, опубликованная в 1991 году, определила концепцию URL и позволила только операции получить, которая запросила конкретный ресурс. HTTP 1.0 и 1.1 Добавлены решающие функции, такие как заголовки, больше методов, и важные оптимации производительности. На момент написания письма принятие HTTP/2 составляет около 45% сайтов в мире, и HTTP/3 все еще является проектом.

Самая важная особенность http, мы должны иметь в виду, как разработчики, это то, что это без гражданства протокол. Это означает, что протокол не требует сервера для отслеживания состояния связи между просьбами, в основном оставляя управление сессией разработчику самого обслуживания.

Управление сессией в настоящее время имеет решающее значение, потому что вы обычно хотите иметь слой аутентификации перед сервисом, где пользователь предоставляет учетные данные и доступ к некоторым личным данным. Это, однако, полезно в других контекстах, таких как визуальные предпочтения или выбор, сделанные пользователем, и повторно используются в более поздних доступах к одному и тому же саму. Типичные решения проблемы управления сеансом HTTP включают использование файлов cookie или жетонов сеансов.

HTTPS.

Безопасность стала очень важным словом в последние годы, и по причине. Количество чувствительных данных, которые мы обменяемся в Интернете или хранилище на цифровых устройствах, растут экспоненциально, но, к сожалению, так это число злонамеренных злоумышленников и уровень ущерба, который они могут вызвать своими действиями. Протокол HTTP по своей природе

Http по своей природе небезопасно, будучи простой текстовой связью между двумя серверами, которые обычно происходят в полностью ненадежной сети, такой как Интернет. Хотя Безопасность не была проблемой, когда протокол был первоначально задуман, в настоящее время проблема имеет проблему первостепенной важности, поскольку мы обменяем личную информацию, часто жизненно важную для безопасности людей или для бизнеса. Мы должны быть уверены, что мы отправляем информацию на правильный сервер и что данные, которые мы отправляем, не могут быть перехвачены.

HTTPS решает как проблему вмешательства и подслушивания, шифрования HTTP с протоколом безопасности транспортного слоя (TLS), который также обеспечивает использование цифровых сертификатов, выданных доверенным органом. На момент написания примерно 80% сайтов загружаются Firefox, используют HTTP по умолчанию. Когда сервер получает подключение HTTPS и преобразует его в HTTP One, обычно говорится, что это завершает TLS (или SSL, старое имя TLS).

Websocket.

Одним из больших недостатков HTTP является то, что связь всегда инициируется клиентом, и что сервер может отправлять данные только тогда, когда это явно запрошено. Опыление может быть реализовано для обеспечения исходного решения, но он не может гарантировать выступления надлежащей полнодуплексной связи, где канал остается открытым между сервером и клиентом, и оба могут отправлять данные без запроса. Такой канал предоставляется протоколом WebStocket.

Websocket – это технология убийц для приложений, таких как онлайн-игры, в режиме реального времени, такие как финансовые тикеры или спортивные новости, или мультимедийная связь, такая как конференц-связь или дистанционное образование.

Важно понимать, что Websocket не является HTTP и может существовать без него. Также верно, что этот новый протокол был разработан для использования в верхней части существующего HTTP-соединения, поэтому связь Websocket часто встречается в частях веб-страницы, которая изначально была получена с использованием HTTP в первую очередь.

Давайте наконец начнем обсуждать биты и байты. Начальная точка для нашего путешествия – это услуга по адресу http, что означает, что есть обмен HTTP-запроса. В качестве примера, давайте рассмотрим запрос на получение, самый простой из методов HTTP.

GET / HTTP/1.1
Host: localhost
User-Agent: curl/7.65.3
Accept: */*

Как видите, клиент отправляет чистое текстовое сообщение на сервер с форматом, указанным в HTTP-протоколе. Первая строка содержит имя метода ( Get ), URL ( / ) и протокол, который мы используем, включая его версию ( http/1.1 ). Остальные линии называются Заголовки и содержат метаданные, которые могут помочь серверу управлять запросом. Полное значение Хозяин Заголовок в этом случае localhost: 80. , но в качестве стандартного порта для HTTP Services 80, нам не нужно его указывать.

Если сервер localhost это Обслуживание Http (то есть запуск некоторого программного обеспечения, который понимает http) в порту 80 Ответ, который мы могли бы получить, это что-то похожее на

HTTP/1.0 200 OK
Date: Mon, 10 Feb 2020 08:41:33 GMT
Content-type: text/html
Content-Length: 26889
Last-Modified: Mon, 10 Feb 2020 08:41:27 GMT




...

Как произошло для запроса, ответ представляет собой текстовое сообщение, отформатированное в соответствии со стандартом. Первая строка упоминает протокол и состояние запроса ( 200 в этом случае, что означает успех), в то время как следующие строки содержат метаданные в разных заголовках. Наконец, после пустой строки сообщение содержит ресурс, который запросил клиент, исходный код базового URL-адреса веб-сайта в этом случае. Поскольку эта HTML-страница, вероятно, содержит ссылки на другие ресурсы, такие как CSS, JS, изображения и т. Д., Браузер отправит несколько других запросов, чтобы собрать все данные, которые необходимо правильно показать страницу пользователю.

Итак, первая проблема, которую у нас есть, – это реализация сервера, который понимает этот протокол и отправляет правильный ответ, когда он получает HTTP-запрос. Мы должны попытаться загрузить запрошенный ресурс и вернуть либо успех (HTTP 200), если мы сможем его найти или сбой (http 404), если мы не можем.

1.1 обоснование

TCP/IP – это сетевой протокол, который работает с розетки Отказ Разъем представляет собой кортеж IP-адреса (уникальный в сети) и порту (уникальный для определенного IP-адреса), что компьютер использует для связи с другими. Разъем – это файловой объект в операционной системе, что может быть таким открыл и Закрыто и что мы можем читать от или Напишите к. Программирование сокетов является довольно низкоуровневым подходом к сети, но вы должны знать, что каждое программное обеспечение на вашем компьютере, который предоставляет доступ к сети, в конечном итоге будет иметь дело с сокетами (скорее всего, через некоторую библиотеку).

Поскольку мы создаем вещи с нуля, давайте реализуем небольшую программу Python, которая открывает соединение сокета, получает HTTP-запрос и отправляет ответ HTTP. В качестве порта 80 является «низким портом» (число меньше 1024), у нас обычно нет разрешений для открытых сокетов там, поэтому я буду использовать порт 8080. Это не проблема на данный момент, поскольку HTTP может быть подан в любом порту.

1.2 Реализация

Создайте файл Server.py И введите этот код. Да, Введите это Не просто скопируйте и вставьте, вы не узнаете ничего другого.

import socket

# Create a socket instance
# AF_INET: use IP protocol version 4
# SOCK_STREAM: full-duplex byte stream
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Allow reuse of addresses
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Bind the socket to any address, port 8080, and listen
s.bind(('', 8080))
s.listen()

# Serve forever
while True:
    # Accept the connection
    conn, addr = s.accept()

    # Receive data from this socket using a buffer of 1024 bytes
    data = conn.recv(1024)

    # Print out the data
    print(data.decode('utf-8'))

    # Close the connection
    conn.close()

Эта небольшая программа принимает соединение по порту 8080 и печатает полученные данные на терминале. Вы можете проверить его выполнение, а затем работает Curl localhost: 8080 в другом терминале. Вы должны увидеть что-то вроде

$ python3 server.py 
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.65.3
Accept: */*

Сервер продолжает выполнять код в в то время как Цикл, поэтому, если вы хотите прекратить его, вы должны сделать это с Ctrl + C. До сих пор это хорошо, но это еще не HTTP-сервер, поскольку он не отправляет ответа; Вы должны на самом деле получить сообщение об ошибке от CURL, который говорит CURL: (52) Пустой ответ от сервера .

Отправка обратно Стандартный ответ очень прост, нам просто нужно позвонить Cond.sendall проезжая необработанные байты. Минимальный HTTP-ответ содержит протокол и состояние, пустую строку и фактический контент, например,

HTTP/1.1 200 OK

Hi there!

Наш сервер становится тогда

import socket

# Create a socket instance
# AF_INET: use IP protocol version 4
# SOCK_STREAM: full-duplex byte stream
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Allow reuse of addresses
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Bind the socket to any address, port 8080, and listen
s.bind(('', 8080))
s.listen()

# Serve forever
while True:
    # Accept the connection
    conn, addr = s.accept()

    # Receive data from this socket using a buffer of 1024 bytes
    data = conn.recv(1024)

    # Print out the data
    print(data.decode('utf-8'))

    conn.sendall(bytes("HTTP/1.1 200 OK\n\nHi there!\n", 'utf-8'))

    # Close the connection
    conn.close()

Однако на данный момент мы на самом деле не отвечаем на запрос пользователя. Попробуйте разные команды Curl, такие как Curl Localhost: 8080/index.html или Curl Localhost: 8080/Main.css И вы всегда получите тот же ответ. Мы должны попытаться найти ресурс, который пользователь просит и отправит это обратно в содержимое ответа.

Эта версия HTTP-сервера правильно извлекает ресурс и пытается загрузить его из текущего каталога, возвращая либо успех сбоя

import socket
import re

# Create a socket instance
# AF_INET: use IP protocol version 4
# SOCK_STREAM: full-duplex byte stream
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Allow reuse of addresses
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Bind the socket to any address, port 8080, and listen
s.bind(('', 8080))
s.listen()

HEAD_200 = "HTTP/1.1 200 OK\n\n"
HEAD_404 = "HTTP/1.1 404 Not Found\n\n"

# Serve forever
while True:
    # Accept the connection
    conn, addr = s.accept()

    # Receive data from this socket using a buffer of 1024 bytes
    data = conn.recv(1024)

    request = data.decode('utf-8')

    # Print out the data
    print(request)

    resource = re.match(r'GET /(.*) HTTP', request).group(1)
    try:
        with open(resource, 'r') as f:
            content = HEAD_200 + f.read()
        print('Resource {} correctly served'.format(resource))
    except FileNotFoundError:
        content = HEAD_404 + "Resource /{} cannot be found\n".format(resource)
        print('Resource {} cannot be loaded'.format(resource))

    print('--------------------')

    conn.sendall(bytes(content, 'utf-8'))

    # Close the connection
    conn.close()

Как вы можете видеть, это реализация чрезвычайно проста. Если вы создаете простой локальный файл с именем index.html с этим содержанием


    This is my page
    


    

Some random content

и бежать Curl Localhost: 8080/index.html Вы увидите содержимое файла. На данный момент вы даже можете использовать ваш браузер для открытия http://localhost: 8080/index.html И вы увидите название страницы и контент. Веб-браузер – это программное обеспечение, способное отправлять HTTP-запросы и интерпретации содержимого ответов, если это HTML (и многие другие типы файлов, такие как изображения или видео), так что это может оказывать Содержание сообщения. Браузер также отвечает за извлечение недостающих ресурсов, необходимых для рендеринга, поэтому при предоставлении ссылок на стиль листы или сценарии JS с <Ссылка> или

Оригинал: “https://dev.to/lgiordani/dissecting-a-web-stack-216c”