Получение cookie расширением сервера Web
В этом разделе мы приведем пример документа HTML, создающего cookie, а также исходные тексты расширения сервера ISAPI, отображающее на динамически создаваемой странице заголовки HTTP этого документа. Когда браузер создает cookie, расширение сервера получает заголовок HTTP_COOKIE и отображает его.
Наш документ аналогичен описанному ранее в разделе “Записная книжка Cookies Notepad” (рис. 7.8).
Рис. 7.8. Документ HTML, работающий с cookie и расширением сервера ISAPI
Дополнительно мы разместили в документе кнопку Send. С помощью этой кнопки содержимое окна редактирования и заголовок HTTP_COOKIES передается расширению ISAPI сервера Web.
Расширение ISAPI отображает содержимое cookie, как это показано на рис. 7.9.
Рис. 7.9. Результат работы расширения ISAPI
Исходный текст документа HTML вы найдете в листинге 7.4.
Листинг 7.4. Файл chapter7/NotebookISAPI/NotebookISAPI.html
<HTML>
<HEAD>
<TITLE>Cookies demo</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function addCookie(szName,szValue,dtDaysExpires)
{
var dtExpires = new Date();
var dtExpiryDate = "";
dtExpires.setTime(dtExpires.getTime() + dtDaysExpires * 24 * 60 * 60 * 1000);
dtExpiryDate = dtExpires.toGMTString();
document.cookie = szName + "=" + escape(szValue) + ";
expires=" + dtExpiryDate;
}
function findCookie(szName)
{
var i = 0;
var nStartPosition = 0;
var nEndPosition = 0;
var szCookieString = document.cookie;
var szTemp = "";
while (i <= szCookieString.length)
{
nStartPosition = i;
nEndPosition = nStartPosition + szName.length;
if(szCookieString.substring(
nStartPosition,nEndPosition) == szName)
{
nStartPosition = nEndPosition + 1;
nEndPosition =
document.cookie.indexOf(";",nStartPosition);
if(nEndPosition < nStartPosition)
nEndPosition = document.cookie.length;
szTemp =
document.cookie.substring(
nStartPosition,nEndPosition);
return unescape(szTemp);
break;
}
i++;
}
return "";
}
function removeCookie(szName)
{
var dtExpires = new Date();
dtExpires.setTime(dtExpires.getTime() - 1);
var szValue = findCookie(szName);
document.cookie = szName + "=" + szValue +
"; expires=" + dtExpires.toGMTString();
}
function btnClick()
{
addCookie("MyText",TestForm.Comment.value,10);
}
// -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR=white>
<H1>Cookies Notepad</H1>
<FORM NAME="TestForm" METHOD=POST ACTION="http://frolov/scripts/ishello.dll?">
<P><TEXTAREA NAME="Comment"
ROWS="5" COLS="25" WRAP="physical">
</TEXTAREA>
<P><INPUT TYPE="button" VALUE="Store text"
onClick="btnClick();">
<INPUT TYPE="button" VALUE="Clear text"
onClick =
"removeCookie('MyText');TestForm.Comment.value=''">
<P><INPUT TYPE=submit VALUE="Send">
</FORM>
<SCRIPT LANGUAGE="JavaScript">
<!--
var szMyText="";
szMyText = findCookie("MyText");
if(szMyText != "")
{
TestForm.Comment.value = szMyText;
}
// -->
</SCRIPT>
</BODY>
</HTML>
В нем, по сравнению с документом из раздела “Записная книжка Cookies Notepad”, мы добавили параметр ACTION в оператор <FORM>, а также кнопку типа submit с надписью Send. С помощью этой кнопки данные из формы отправляются расширению ISAPI:
. . .
<FORM NAME="TestForm" METHOD=POST ACTION="http://frolov/scripts/ishello.dll?">
. . .
<INPUT TYPE=submit VALUE="Send">
. . .
Исходный текст расширения ISAPI представлен в листинге 7.5. Он сделан на базе примера, взятого из 29 тома нашей “Библиотеки системного программиста” (раздел “Приложение ISHELLO” восьмой главы).
Листинг 7.5. Файл chapter7/NotebookISAPI/ishello.c
// ===============================================
// Расширение ISAPI ishello.c
// Пример расширения ISAPI, отображающего
// содержимое cookie
//
// (C) Фролов А.В., 1997, 1998
// E-mail: frolov@glas.apc.org
// WWW: http://www.glasnet.ru/~frolov
// или
// http://www.dials.ccas.ru/frolov
// ===============================================
#include <windows.h>
#include <httpext.h>
// =========================================================
// Функция GetExtensionVersion
// Запись версии интерфейса ISAPI и
// строки описания расширения
// =========================================================
BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
// Записываем версию интерфейса ISAPI
pVer->dwExtensionVersion =
MAKELONG(HSE_VERSION_MINOR,HSE_VERSION_MAJOR );
// Записываем строку описания расширения
lstrcpyn(pVer->lpszExtensionDesc,
"Cookie show ISAPI DLL", HSE_MAX_EXT_DLL_NAME_LEN);
return TRUE;
}
// =========================================================
// Функция HttpExtensionProc
// =========================================================
DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *lpECB)
{
CHAR szBuff[4096];
CHAR szTempBuf[4096];
DWORD dwSize;
// Нулевой код состояния - признак успешного выполнения
lpECB->dwHttpStatusCode = 0;
// Записываем в буфер заголовок HTTP и начальный
// фрагмент формируемого динамически документа HTML
wsprintf(szBuff,
"Content-Type: text/html\r\n\r\n"
"<HTML><HEAD><TITLE>Simple ISAPI Extension</TITLE></HEAD>\n"
"<BODY BGCOLOR=#FFFFFF><H2>Hello from ISAPI Extension!</H2>\n");
// Добавляем разделительную линию
strcat(szBuff, "<HR>");
// Добавляем версию интерфейса ISAPI
wsprintf(szTempBuf, "<P>Extension Version: %d.%d",
HIWORD(lpECB->dwVersion), LOWORD(lpECB->dwVersion));
strcat(szBuff, szTempBuf);
// Название метода передачи данных
wsprintf(szTempBuf, "<BR>Method: %s", lpECB->lpszMethod);
strcat(szBuff, szTempBuf);
// Строка параметров запуска расширения ISAPI
wsprintf(szTempBuf, "<BR>QueryString: %s",
lpECB->lpszQueryString);
strcat(szBuff, szTempBuf);
// Физический путь к программному файлу расширения ISAPI
wsprintf(szTempBuf, "<BR>PathTranslated: %s",
lpECB->lpszPathTranslated);
strcat(szBuff, szTempBuf);
// Полный размер данных, которые нужно получить
wsprintf(szTempBuf, "<BR>TotalBytes: %d",
lpECB->cbTotalBytes);
strcat(szBuff, szTempBuf);
// Тип данных
wsprintf(szTempBuf, "<BR>ContentType: %s",
lpECB->lpszContentType);
strcat(szBuff, szTempBuf);
// Отображаем содержимое COOKIE
strcat(szBuff, "<HR><P><B>Cookie:</B><BR>");
dwSize = 4096;
lpECB->GetServerVariable(lpECB->ConnID,
(LPSTR)"HTTP_COOKIE", (LPVOID)szTempBuf, &dwSize);
strcat(szBuff, szTempBuf);
// Конечный фрагмент документа HTML
strcat(szBuff, "</BODY></HTML>");
// Посылаем содержимое буфера удаленному пользователю
if(!lpECB->ServerSupportFunction(lpECB->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER, NULL, NULL,
(LPDWORD)szBuff))
{
// Если послать данные не удалось,
// завершаем работу нашего расширения ISAPI
// с кодом ошибки
return HSE_STATUS_ERROR;
}
// Записываем код успешного завершения
lpECB->dwHttpStatusCode = 200;
// Возвращаем принак успешного завершения
return HSE_STATUS_SUCCESS;
}
Файл определения модуля для библиотеки DLL расширения приведен в листинге 7.6.
Листинг 7.6. Файл chapter7/NotebookISAPI/ishello.def
LIBRARY ishello
DESCRIPTION 'Simple ISAPI DLL'
EXPORTS
GetExtensionVersion
HttpExtensionProc
Для извлечения значения cookie, предаваемого расширению через заголовки HTTP, мы использовали функцию GetServerVariable, указав ей в качестве второго параметра имя интересующей нас переменной HTTP_COOKIE:
lpECB->GetServerVariable(lpECB->ConnID,
(LPSTR)"HTTP_COOKIE", (LPVOID)szTempBuf, &dwSize);
Полученное таким образом значение дописывается в буфер динамически создаваемого документа HTML. Этот буфер впоследствии будет отправлен клиенту при помощи функции ServerSupportFunction.