— Andrew A. Inutcin 23:16 14.02.2009
Время чтения курса без практических занятий - 815 минут. Практические занятия включают в себя разбор котрольных заданий в объёме 540 минут (по часу на каждую главу курса).
Для успешного прохождения курса слушатель должен иметь следующие навыки
Протокол - набор правил обмена сообщений. http - один из протоколов для передачи данных по сети. Так же можно вспомнить: ftp, https, smb, и даже такие экзотические, как obex и svn. http - специализируется на передаче гипертекстовых документов (web-страниц).
Хост определяет к какому сайту направлен наш http - запрос. Хост выполняет двойную роль(направляется запрос к DNS-серверу):
Виртуалхост - запись в настройках web-сервера, определяющая из какого корневого каталога для какого хоста, прописанного в URL, отдавать данные.
Корневой каталог(DOCUMENT_ROOT) - каталог, начиная с которого клиенту отдаётся содержимое документов, находящихся в нём. То есть доступ к подкаталогам DOCUMENT_ROOT возможен, к надкаталогам - нет.
Рассмотрим последовательность совершения браузером запроса к web - серверу.
Часто встречающиеся ситуации, когда IP-адрес web-сервера получить не удаётся:
В данном случае ОС просто не знает под каким IP-адресом web-сервер подключен к сети, и браузер никуда не может послать имя домена и запрос документа(REQUEST_URI). В этом случае можно прямо указать какой к какому серверу необходимо подключиться (все браузеры имеют настройку «использовать прокси-сервер»), указав IP и порт(как правило это порт 80).
Для проверки доступности, и просмотра вывода, DNS - сервера используется команда nslookup.
Пуск->Выполнить->nslookup [имя домена]
Ответ DNS-сервера, если он доступен, выглядит так:
nslookup perpetum-mobile.ru Server: 62.213.0.12 Address: 62.213.0.12#53 Non-authoritative answer: Name: perpetum-mobile.ru Address: 81.177.46.165
Разберём вывод nsloockup:
Для проверки физической доступности web-сервера можно использовать команду telnet.
Пуск->Выполнить->nslookup [IP адрес или имя домена] [порт]
Как правило, web-сервер работает на порту 80.
Разберём вывод команды telnet
telnet perpetum-mobile.ru 80 Trying 81.177.46.165... Connected to perpetum-mobile.ru (81.177.46.165). Escape character is '^]'.
REQUEST_URI - запрос документа у web-сервера. Если HTTP_HOST определяет из какого корневого каталога будет получен документ, то REQUEST_URI определяет:
REQUEST_URI может содержать только следующие символы:
Mime-type - тип документа, определяемый по расширению. К типу может быть привязано какое-то действие, но по умолчанию web-сервер просто передаёт содержимое документа web-клиенту(браузеру), но может быть и какая-то обработка. Примеры mime-types:
QUERY_STRING - дополнительные параметры документа. Имеет вид пар «ключ=значение». Пары отделяются друг от друга амперсантами &. Ключ от значения отделяется знаком «равно». Отделяется от SCRIPT_NAME знаком вопроса.
HTTP - протокол - описания порядка обмена служебной информацией (заголовками) данными. Наблюдать какая служебная информация в виде заголовков передаётся от браузера web-серверу и обратно можно, например, с помощью плагина к FireFox, который называется LiveHTTPHeader
Скачать его можно тут: http://livehttpheaders.mozdev.org/
Независимо от типа запроса сохраняется следующая последовательность:
При осуществлении запроса методом GET все параметры запроса к сайту (за исключением cookie) передаются через REQUEST_URI.
http-заголовки запроса GET
GET /project_checkout.php HTTP/1.1 Host: xepace.localhost User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) Gecko/20070914 Firefox/2.0.0.9 Referer: http://xepace.localhost/
Основные элементы html-страницы, позволяющие делать GET-запросы
Гиперссылки
<a href="http://yandex.ru" title="Яндекс" target="_blank">
Гиперссылка
</a>
Изображения
<img src="/images/crazytux.png" title="Бешенный пингвин1" border="2" alt="Пингвин1"/> <img src="/images/crazytux_.png" title="Бешенный пингвин2" border="2" alt="Пингвин2"/>
Внешние таблицы стилей
<link href="css/style.css" rel="stylesheet" type="text/css" />
Внешние файлы с JavaScript
<script type="text/javascript" src="/scripts.js"></script>
Фреймы
<iframe src="/frame.php"></iframe>
Формы
<form action="" method="GET" target="_blank">
<input type="text" name="textfield" value="textvalue"/><br/>
<label>
<input type="checkbox" name="checkbox" checked/>Checked
</label><br/>
<label>
<input type="radio" name="radio" value="radio1" />radio-one
</label><br/>
<label>
<input type="radio" name="radio" value="radio2" selected/>radio-two
</label><br/>
<input type="submit" name="get" value="Отправить форму"/>
</form>
Данный html-код генерит страцичку следующего вида:
При отправке этой формы открывается новое окно, в которое загружается url:
http://xepace.localhost/images/index.html?textfield=textvalue&checkbox=o...... &radio=radio2&... get=%D0%9E%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D1%8C+%D1%84%D0%BE%D1%80%D0%BC%D1%83
При осуществлении запроса методом POST кроме параметров, которые можно наблюдать в строке браузера, передаётся скрытая строка параметров
http-заголовки запроса POST
POST /images/index.html HTTP/1.1
Host: xepace.localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) Gecko/20070914 Firefox/2.0.0.9
Referer: http://xepace.localhost/
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
pass=&hid=hidden_value&textarea1=textarea_value&post=POST_FORM
Основные элементы html-страницы, позволяющие делать POST-запросы
Формы
<form action="" method="POST" target="_blank">
<input type="password" name="pass" value=""/><br/>
<input type="hidden" name="hid" value="hidden_value"/>
<textarea name="textarea1">textarea_value</textarea><br/>
<input type="submit" name="get" value="Отправить POST форму"/>
</form>
В новую страницу будет загружен url
http://xepace.localhost/images/index.html
а в заголовках отправлены значения полей в виде
TTP/1.x 200 OK Date: Tue, 24 Jun 2008 17:34:13 GMT Server: Apache/2.2.6 (Mandriva Linux/PREFORK-8mdv2008.0) X-Powered-By: PHP/5.2.6 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 5547 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=utf-8
HTTP/1.x 200 OK Content-Type: text/html; charset=utf-8
HTTP/1.x 500 Internal Server Error Content-Type: text/html; charset=iso-8859-1
HTTP/1.x 403 Forbidden Content-Type: text/html; charset=iso-8859-1
HTTP/1.x 404 Not Found Content-Type: text/html; charset=iso-8859-1
GET /main.css HTTP/1.1
Host: xepace.localhost
Referer: http://xepace.localhost/project_checkout.php
If-Modified-Since: Wed, 04 Jun 2008 09:25:46 GMT
HTTP/1.x 304 Not Modified
HTTP/1.x 302 Found
Location: 1.php
Content-Length: 0
Content-Type: text/html
Куки - информация, отсылаемая в заголовке ответа. Сохраняется в браузере, и передается в виде заголовка запроса, если
Заголовок ответа, сохраняющий куки в браузере, выглядит так:
Set-Cookie: cookie1=qwerty; expires=Wed, 25-Jun-2008 22:49:28 GMT; path=/libs; domain=xepace.localhost
А это заголовок запроса, если хранящеся куки удовлетворяют необходимым условиям:
Cookie: cookie1=qwerty;
У куков есть определенные проблемы с безопасностью, связанные с тем, что все значения передаются в http-заголовках напрямую. Для данных, которые нежелательны для раскрытия (к примеру можно было запоминать логин и пароль входа) лучше применять механизм сессии.
Сессия - набор данных, хранящихся в файле во временном каталоге или в оперативной памяти, содержащих информацию, характерную для определенного посетителя. Принадлежность данных к конкретному файлу определяется на основе куков - ID сессии. Значение этих куков, как правило, совпадают с именем файла сессии. Значение ID сессии так же можно передавать не через cookie, а в качестве одного из параметров QUERY_STRING. Если web-приложение, работающее с сессией написано на php, то это можно сделать через файл .htaccess.
Для отдельного каталога в виртуальном хосте и всех его подкаталогов можно определить собственные настройки web-сервера. Это делается с помощью файла .htaccess
Немного забегая вперёд, отметим, что для настройки PHP, работающего в окружении web-сервера, используются ключи конфигурационного файла php.ini. Некоторые из них можно задавать через .htaccess, в том числе и эти 3 ключа, управляющие способом передачи ID сессии.
Для того, чтобы ID сессии передавался только через cookie в .htaccess достаточно прописать следующее
php_flag session.use_cookies On
php_flag session.use_only_cookies On
php_value session.use_trans_sid 0
AddDefaultCharset utf-8 AddDefaultCharset windows-1251
Если REQUEST_URI не содержит не содержит имени конечного файла, а только имя каталога, то имя файла в каталоге, которое берётся по умолчанию прописывается в .htaccess директивой
DirectoryIndex index.html
Если необходимо не использовать файл по умолчанию, а вывести содержимое запрашиваемого каталога - используйте:
Options +Indexes
Запретить доступ для всех
Deny from all
Запретить доступ для 192.168.0.1 и 192.168.0.1
Deny from 192.168.0.1 192.168.0.1
Запретить доступ для всех кроме 192.168.0.1 и 192.168.0.1
Deny from all Allow from 192.168.0.1 192.168.0.1
Авторизация и аутентификация будут производиться при помощи двух файлов: .htaccess и .htpasswd . При помощи первого файла будет выдаваться форма запроса логина и пароля. Для этого в файл .htaccess следует добавить следующие строки:
AuthUserFile /home/user/public_html/.htpasswd
AuthName "example of http-auth"
AuthType Basic
Require valid-user admin
AuthUserFile - указывает на файл, в котором хранятся имена пользователей и пароли. Требуется указать полный путь. Стоит заметить, что файл с паролями следует размещать так, чтобы он не был доступен для просмотра из интернета. О том, что из себя представляет этот файл, будет сказано ниже.
AuthName - текст, заключенный в кавычках после этой директивы, будет выведен в окне запроса логина и пароля.
AuthType - тип авторизации. В данном случае используется тип Basic. Есть еще один - Digest. Разница заключается в том, что тип Basic хранит пароли зашифрованные алгоритмом DES, а Digest для этих целей использует MD5.
Require - определяет кому давать доступ. valid-user означает что доступ будет предоставлен тем кто введет правильно логин и пароль. Эту директиву можно настроить так чтобы она впускала только пользователей определенной группы или просто пользователей перечисленных после нее через пробел.
Для создания парольного файла нужно выполнить:
htpasswd -c .htpasswd admin
Где:
Парольный файлик - готов. Можно просто создать файл .htpasswd и ручками впечатать туда: yourname:yourpass (где: yourname - логин, yourpass - пароль), но это крайность, т.к. если твой сайт находится на общем хостинге, есть вероятность что другие пользователи хостинга будут мониторить логин:пароль.
Переопределить стандартые страницы ошибок можно с помощью директивы
ErrorDocument
Например, чтобы для отображения 404-й ошибки использовалась страница с REQUEST_URI /errors/404.html достаточно прописать:
ErrorDocument 404 /errors/404.html
mod_rewrite - плагин к web-серверу apache, позволяющий налету подменять одни REQUEST_URI другими, с последющим редиректом или без.
Options +FollowSymLinks
RewriteEngine on
Это отдельная большая тема и тут рассматриваться не будет.
Скрипт PHP - по сути является приложением, принимающим заголовки от браузера и формирующим заголовки ответа и содержимое. Создадим в DOCUMENT_ROOT web-сервера файл 0.php следующего содержания.
<html>
<head>
</head>
<body>
<h1>Test</h1>
<h2>
<?php
$a = 1;
$b = 2;
$c = $a + $b;
echo $c;
?>
</h2>
</body>
</html>
Заголовки, которые будут сформированиы этим скриптом будут выглядеть так:
HTTP/1.x 200 OK Date: Sun, 06 Jul 2008 07:07:39 GMT Server: Apache/2.2.6 (Mandriva Linux/PREFORK-8mdv2008.0) X-Powered-By: PHP/5.2.6 Content-Length: 74 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html
В браузер будет передано следующее содержимое:
<html> <head> </head> <body> <h1>Test</h1> <h2> 3 </h2> </body> </html>
Которое в окне браузера отобразится как заголовок первого уровня «Test» и заголовок 2-гоуровня «3».
Из приведённых примеров можно сделать следующие выводы:
Есть возможность прописать собственные заголовки, для того, чтобы, например, содержимое генерируемой страницы отображалось не как html-страница, а как простой текст (без интерпретации тегов) (файл 1.php)
<?php header("Content-Type: text/plain");?>
<html>
<head>
</head>
<body>
<h1>Test</h1>
<h2>
<?php
$a = 1;
$b = 2;
$c = $a + $b;
echo $c;
?>
</h2>
</body>
</html>
Сгенерированная страничка выведется в виде простого текста.
<html> <head> </head> <body> <h1>Test</h1> <h2> 3</h2> </body> </html>
Ещё пара выводов:
В PHP есть стандартная функция, которая выводит в виде красивого форматированного html-кода параметры установленного интерпретатора PHP. Разместим в файле 2.php следующий код.
<?php phpinfo();?>
Сгенерированный этой функцией код формирует страницу следующего вида: