HTTP example ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

# Примеры диалогов HTTP

# Обычный GET-запрос клиента:::::::::::::::::::::::::::

GET /wiki/страница HTTP/1.1
Host: ru.wikipedia.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5
Accept: text/html
Connection: close
# (пустая строка)  

# ответ сервера:

HTTP/1.1 200 OK
Date: Wed, 11 Feb 2009 11:20:59 GMT
Server: Apache
X-Powered-By: PHP/5.2.4-2ubuntu5wm1
Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT
Content-Language: ru
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Connection: close
# (пустая строка)
# (далее следует запрошенная страница в HTML)

# Аналогично выглядит ответ 203. Что существенно — непосредственно 
# запрашиваемые данные отделены от HTTP-заголовков с помощью CRLF CRLF 
# (двух переводов строки).



# Перенаправление::::::::::::::::::::::::::::::::::::::

# Предположим, что у вымышленной компании «Example Corp.» есть основной 
# сайт по адресу «http://example.com» и домен-псевдоним «example.org». 
# Клиент посылает запрос страницы «О компании» на вторичный домен 
# (часть заголовков опущена):

GET /about.html HTTP/1.1
Host: example.org
User-Agent: MyLonelyBrowser/5.0

# Так как домен «example.org» не является основным и компания не собирается 
# в будущем его использовать в других целях, их сервер вернёт код для 
# постоянного перенаправления, указав в заголовке Location целевой URL:

HTTP/1.x 301 Moved Permanently
Location: http://example.com/about.html#contacts
Date: Thu, 19 Feb 2009 11:08:01 GMT
Server: Apache/2.2.4
Content-Type: text/html; charset=windows-1251
Content-Length: 110
(пустая строка)
<html><body><a href="http://example.com/about.html#contacts">Click here</a></body></html>

# В заголовке Location можно указывать фрагменты как в данном примере. 
# Браузер не указал фрагмент в запросе, так как его интересует весь документ. 
# Но он автоматически прокрутит страницу до фрагмента «contacts», как только 
# загрузит её. В тело ответа также был помещён короткий HTML-документ со 
# ссылкой, с помощью которой посетитель попадёт на целевую страницу, если 
# браузер не перейдёт на неё автоматически. Заголовок Content-Type содержит 
# характеристики именно этого HTML-пояснения, а не документа, который находится 
# по целевому URI.

# Допустим, эта же компания «Example Corp.» имеет несколько региональных 
# представительств по всему миру. И для каждого представительства у них есть 
# сайт с соответствующим ccTLD. Запрос главной страницы основного сайта 
# «example.com» может выглядеть так:

GET / HTTP/1.1
Host: example.com
User-Agent: MyLonelyBrowser/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7

# Сервер принял во внимание заголовок Accept-Language и сформировал ответ со 
# временным перенаправлением на российский сервер «example.ru», указав его 
# адрес в заголовке Location:

HTTP/1.x 302 Found
Location: http://example.ru/
Cache-Control: private
Date: Thu, 19 Feb 2009 11:08:01 GMT
Server: Apache/2.2.6
Content-Type: text/html; charset=windows-1251
Content-Length: 82
(пустая строка)
<html><body><a href="http://example.ru">Example Corp.</a></body></html>

# Обратите внимание на заголовок Cache-Control: значение «private» сообщает 
# остальным серверам (в первую очередь прокси) что ответ может кэшироваться 
# только на стороне клиента. В противном случае не исключено, что следующие 
# посетители из других стран будут переходить всё время не в своё 
# представительство.

# Для перенаправления также используются коды ответа 303 (See Other) и 
# 307 (Temporary Redirect).




# Докачка и фрагментарное скачивание ::::::::::::::::::::::::::::::::::::::::::

# Допустим, вымышленная организация предлагает скачать с сайта видео прошедшей 
# конференции по адресу: «http://example.org/conf-2009.avi» — объёмом примерно 
# 160 МБ. Рассмотрим, как происходит докачивание этого файла в случае сбоя и 
# как менеджер закачек организовал бы многопоточную загрузку нескольких 
# фрагментов.

# В обоих случаях клиенты произведут свой первый запрос наподобие этого: 

GET /conf-2009.avi HTTP/1.0
Host: example.org
Accept: */*
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Referer: http://example.org/

# Заголовок Referer указывает, что файл был запрошен с главной страницы сайта. 
# Менеджеры закачек обычно тоже его указывают, чтобы эмулировать переход со 
# страницы сайта. Без него сервер может ответить 403 (Access Forbidden), если 
# не допускаются запросы с других сайтов. В нашем случае сервер вернул успешный 
# ответ:

HTTP/1.1 200 OK
Date: Thu, 19 Feb 2009 12:27:04 GMT
Server: Apache/2.2.3
Last-Modified: Wed, 18 Jun 2003 16:05:58 GMT
ETag: "56d-9989200-1132c580"
Content-Type: video/x-msvideo
Content-Length: 160993792
Accept-Ranges: bytes
Connection: close
# (пустая строка)
# (двоичное содержимое всего файла)

# Заголовок Accept-Ranges информирует клиента о том, что он может запрашивать 
# у сервера фрагменты, указывая их смещения от начала файла в байтах. Если этот 
# заголовок отсутствует, то клиент может предупредить пользователя, что 
# докачать файл, скорее всего, не удастся.

# Исходя из значения заголовка Content-Length, менеджер закачек поделит весь 
# объём на равные фрагменты и запросит их по отдельности, организовав несколько 
# потоков. Если сервер не укажет размер, то клиенту параллельное скачивание 
# реализовать не удастся, но при этом он сможет докачивать файл, пока сервер не 
# ответит416 (Requested Range Not Satisfiable).

# Допустим, на 84-м мегабайте соединение с Интернетом прервалось и процесс 
# загрузки приостановился. Когда соединение с Интернетом было восстановлено, 
# менеджер закачек автоматически послал новый запрос на сервер, но с указанием 
# выдать содержимое с 84-го мегабайта:

GET /conf-2009.avi HTTP/1.0
Host: example.org
Accept: */*
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Range: bytes=88080384-
Referer: http://example.org/

# Сервер не обязан помнить, какие и от кого запросы были до этого, и поэтому 
# клиент снова вставил заголовок Referer, как будто это его самый первый запрос. 
# Указанное значение заголовка Range говорит серверу: «Выдай содержимое от 
# 88080384-го байта до самого конца». В связи с этим сервер вернёт ответ:

HTTP/1.1 206 Partial Content
Date: Thu, 19 Feb 2009 12:27:08 GMT
Server: Apache/2.2.3
Last-Modified: Wed, 18 Jun 2003 16:05:58 GMT
ETag: "56d-9989200-1132c580"
Accept-Ranges: bytes
Content-Range: bytes 88080384-160993791/160993792
Content-Length: 72913408
Connection: close
Content-Type: video/x-msvideo
# (пустая строка)
# (двоичное содержимое от 84-го мегабайта)

# Заголовок Accept-Ranges здесь уже не обязателен, так как клиент уже 
# знает об этой возможности сервера. О том, что передаётся фрагмент, 
# клиент узнаёт по коду 206 (Partial Content). В заголовке Content-Range 
# содержится информация о данном фрагменте: номера начального и конечного 
# байта, а после слэша — суммарный объём всего файла в байтах. Обратите 
# внимание на заголовок Content-Length — в нём указывается размер тела 
# сообщения, то есть передаваемого фрагмента. Если сервер вернёт несколько 
# фрагментов, то Content-Length будет содержать их суммарный объём.

# Теперь вернёмся к менеджеру закачек. Зная суммарный объём файла 
# «conf-2009.avi», программа поделила его на 10 равных секций.

# Начальную менеджер загрузит при самом первом запросе, прервав соединение 
# как только дойдёт до начала второго. Остальные он запросит отдельно. 
# Например, 4-я секция будет запрошена со следующими заголовками (часть 
# заголовков опущена — см. полный пример выше):

GET /conf-2009.avi HTTP/1.0
Range: bytes=64397516-80496894

# Ответ сервера в этом случае будет следующим (часть заголовков 
# опущена — см. полный пример выше):

HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Range: bytes 64397516-80496894/160993792
Content-Length: 16099379
# (пустая строка)
# (двоичное содержимое 4-й части)

# Если подобный запрос отправить серверу, который не поддерживает фрагменты, 
# то он вернёт стандартный ответ 200 (OK) как было показано в самом начале, 
# но без заголовка Accept-Ranges.
