Как установить несколько файлов cookie в фильтре ISAPI

Я столкнулся с проблемой установки нескольких файлов cookie в фильтре ISAPI. Я хочу добавить HttpOnly флаг во все куки.

Итак, в моей первой попытке я разделил значение куки и добавил HttpOnly флаг, затем я объединяю их в одну строку, вызывать pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue) в конце концов, браузер получает только первое значение cookie.

Код 1-й попытки:

cbValue = sizeof(szValue) / sizeof(szValue[0]);
if (pResponse->GetHeader(pfc, "Set-Cookie:", szValue, &cbValue))
{
char szNewValue[MAX_URI_SIZE] = "";
char* token = NULL;
char* context = NULL;
char delim[] = ",";

// szValue format like
// "Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly"// After first split
// token = "Language=en; expires=Sat"// context = " 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly"token = strtok_s(szValue, delim, &context);
while (token != NULL)
{
strcat_s(szNewValue, token);
if (NULL != context)
{
if (' ' != context[0] && !strstr(token, "HttpOnly"))
{
strcat_s(szNewValue, "; HttpOnly");
}

// context[0] = ' ' means it split the one whole cookie, not an entire cookie, we need append ","// context[0] != '\0' means other cookies after, we need append delimiter ","if (' ' == context[0] || '\0' != context[0])
{
strcat_s(szNewValue, ",");
}
}
// NULL, function just re-uses the context after the first read.
token = strtok_s(NULL, delim, &context);
}
if (!pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue))
{
// Fail securely - send no cookie!
pResponse->SetHeader(pfc,"Set-Cookie:","");
}

Во второй попытке я разделяю значение cookie и вызываю pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue) для каждого куки, но браузер получает только последний куки в этом случае.

Код 2-й попытки:

cbValue = sizeof(szValue) / sizeof(szValue[0]);
if (pResponse->GetHeader(pfc, "Set-Cookie:", szValue, &cbValue))
{
char szNewValue[MAX_URI_SIZE] = "";
char* token = NULL;
char* context = NULL;
char delim[] = ",";

// szValue format like
// "Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly"// After first split
// token = "Language=en; expires=Sat"// context = " 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly"token = strtok_s(szValue, delim, &context);
while (token != NULL)
{
strcat_s(szNewValue, token);
if (NULL != context)
{
if (' ' != context[0] && !strstr(token, "HttpOnly"))
{
strcat_s(szNewValue, "; HttpOnly");
}

// context[0] = ' ' means it split the one whole cookie, not an entire cookie, we need append ","// context[0] != '\0' means other cookies after, we need append delimiter ","if (' ' == context[0])// || '\0' != context[0])
{
strcat_s(szNewValue, ",");
}
if (' ' != context[0])
{
pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue);
strcpy(szNewValue, "");
}
}
// NULL, function just re-uses the context after the first read.
token = strtok_s(NULL, delim, &context);
}

Я делаю это в IE10 + Win2008 R2. В обоих случаях результирующие строки cookie имеют правильный формат. У кого-нибудь есть подсказки по этому поводу?

Эта проблема существует в основном потому, что когда вы вызываете GetHeader, вы получаете все куки в одной строке с разделителями-запятыми. Какой будет лучший способ использовать SetHeader способ установить все куки обратно на ответ?

5

Решение

Я искал решение этой проблемы и нашел много неправильных ответов.

Этот пост был тем, что привело меня к решению.

Исходное опубликованное решение не сработало, поскольку оно использовало SetHeader для каждого файла cookie. SetHeader заменяет заголовок «Set-Cookie:» каждый раз, когда он вызывается, поэтому был установлен только последний Cookie. Вместо того, чтобы использовать SetHeader, я использовал AddHeader для каждого файла cookie. Но перед первым использованием AddHeader я использовал SetHeader с «», чтобы «очистить» заголовок «Set-Cookie:».

Это работало для меня, используя IIS5.1 и IIS7.0

Это решение работает и для куки-файла ASP Session Id.

Я знаю, что Classic ASP — старая технология, но она все еще используется, и нам нужны подобные решения.

Вот мой полный код:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <httpfilt.h>

BOOL WINAPI __stdcall GetFilterVersion(HTTP_FILTER_VERSION *pVer)
{
pVer->dwFlags = SF_NOTIFY_SEND_RESPONSE | SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT;

pVer->dwFilterVersion = HTTP_FILTER_REVISION;

strcpy_s(pVer->lpszFilterDesc, sizeof(pVer->lpszFilterDesc), "httpOnly Filter, Version 1.0. JCGalvezV.");

return TRUE;
}

DWORD WINAPI __stdcall HttpFilterProc(HTTP_FILTER_CONTEXT *pfc, DWORD NotificationType, VOID *pvData)
{
DWORD   cbBuffer;
char lszBuffer[2000], lszNewBuffer[2000];
HTTP_FILTER_PREPROC_HEADERS *pFPH = (HTTP_FILTER_PREPROC_HEADERS *)pvData;

switch (NotificationType)
{
case SF_NOTIFY_SEND_RESPONSE :
cbBuffer = sizeof(lszBuffer);
if (pFPH->GetHeader(pfc, "Set-Cookie:", lszBuffer, &cbBuffer))
{
char* token = NULL;
char* context = NULL;
char delim[] = ",";

// Delete previous cookies

pFPH->SetHeader(pfc, "Set-Cookie:", "");

token = strtok_s(lszBuffer, delim, &context);
while (token != NULL)
{
strcpy_s(lszNewBuffer, sizeof(lszNewBuffer), token);
if (!strstr(token, "httpOnly"))
strcat_s(lszNewBuffer, sizeof(lszNewBuffer), "; httpOnly");

// AddHeader instead of SetHeader.

pFPH->AddHeader(pfc, "Set-Cookie:", lszNewBuffer);

// next token
token = strtok_s(NULL, delim, &context);
}

}
break;
default :
break;
}

return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
2

Другие решения

У меня была такая же проблема, и мне нужно было связаться с Microsoft, чтобы решить эту проблему. Когда вы получаете несколько файлов cookie, вы получите полную строку со всеми файлами cookie, разделенными запятыми.
Работа состоит в том, чтобы отделить каждый файл cookie, а затем вызвать метод SetHeader для каждого отдельно.

Важно то, что каждый файл cookie должен иметь уникальную пару имя-значение (http://www.quirksmode.org/js/cookies.html) поэтому каждое изменение может быть правильно отображено.

Решение в псевдокоде

pResponse->GetHeader(pfc, "Set-Cookie:", szValue, &cbValue)

// split cookies here

foreach separated cookie
pResponse->SetHeader(pfc, "Set-Cookie:", oneCookie)

Таким образом, вам не нужно очищать все куки, чтобы добавить их снова.

2

Ваша первая попытка лучше, чем вторая, потому что вы должны установить заголовок только один раз. Я думаю, что ваш алгоритм разбора строк немного не работает. Я бы попытался упростить это. Сначала разделите заголовок на строки для каждого файла cookie. Затем измените файл cookie, добавив атрибут http only, а затем объедините файлы cookie в один заголовок.

0
По вопросам рекламы [email protected]