2013-07-15 12 views
5

Wystąpił problem z ustawieniem wielu plików cookie w filtrze ISAPI. Chcę dodać flagę HttpOnly do wszystkich plików cookie.Jak ustawić wiele plików cookie w filtrze ISAPI

W pierwszej próbie podzielę wartość plików cookie i dodaję flagę HttpOnly, a następnie łączę je w jeden ciąg, w końcu wywołuję pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue), przeglądarka otrzymuje tylko pierwszą wartość cookie.

Kodeks 1. próba:

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:",""); 
      } 

W drugiej próbie, ja podzielić wartość ciasteczka, i powołać pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue) dla każdego pliku cookie, ale przeglądarka uzyskać tylko ostatni cookie w tej sprawie.

Kodeks 2. podejściu:

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); 
      } 

zrobić to w IE10 + Win2008 R2. W obu przypadkach wynikowy plik cookie ma prawidłowy format. Czy ktoś ma jakiekolwiek o tym pojęcie?

Ten problem występuje w zasadzie dlatego, że po wywołaniu GetHeader wszystkie pliki cookie są wysyłane w ciągu rozdzielanym przecinkami. Jaki byłby najlepszy sposób użycia metody SetHeader do ustawienia wszystkich plików cookie z powrotem na odpowiedź?

Odpowiedz

0

Twoja pierwsza próba jest lepsza niż druga, ponieważ powinieneś ustawić nagłówek tylko raz. Myślę, że algorytm analizy parsowania jest trochę nietypowy. Chciałbym to trochę uprościć. Najpierw podziel nagłówek na ciągi znaków dla każdego pliku cookie. Następnie zmodyfikuj plik cookie, aby dodać atrybut http tylko w razie potrzeby, a następnie połącz pliki cookie z powrotem w jednym nagłówku.

2

Szukałem rozwiązania tego problemu i znalazłem wiele niepoprawnych odpowiedzi.

Ten wpis doprowadził mnie do rozwiązania.

Oryginalne zaksięgowane rozwiązanie nie działa, ponieważ używało SetHeader dla każdego pliku cookie. SetHeader zastępuje nagłówek "Set-Cookie:" za każdym razem, gdy jest wywoływany, więc ustawiono tylko ostatni plik Cookie. Zamiast używać SetHeader, użyłem AddHeader dla każdego cookie. Ale przed użyciem AddHeadera po raz pierwszy użyłem SetHeader z "", aby "opróżnić" nagłówek "Set-Cookie:".

Ten pracował dla mnie za pomocą IIS5.1 i IIS7.0

to rozwiązanie działa na ASP Session ID cookies zbyt.

Wiem Klasyczna ASP to stara technologia, ale wciąż jest w użyciu i potrzebujemy takich rozwiązań.

Oto mój pełny kod:

#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; 
} 
+0

Powinieneś użyć '_countof (lszNewBuffer)' zamiast 'sizeof (lszNewBuffer)' z 'strcpy_s' i' strcat_s', ponieważ potrzebuje liczby znaków, a nie bajtów. Tutaj działa, ponieważ oba są równe łańcuchom ANSI. – McX

2

miałem ten sam problem i musiałem kontaktować się z firmą Microsoft, aby rozwiązać ten problem. Po otrzymaniu wielu plików cookie otrzymasz pełny ciąg znaków zawierający wszystkie pliki cookie oddzielone przecinkami. Praca polega na oddzieleniu każdego pliku cookie, a następnie wywołaniu metody SetHeader oddzielnie dla każdej z nich.

Ważne jest to, że każde ciasteczko musi mieć niepowtarzalną parę nazwa-wartość (http://www.quirksmode.org/js/cookies.html), aby każda zmiana mogła zostać właściwie odwzorowana.

Rozwiązaniem w Pseudokod

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

// split cookies here 

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

w ten sposób, nie trzeba oczyścić wszystkie pliki cookie, aby dodać je ponownie.

Powiązane problemy