domenica 17 ottobre 2010

AddHeader - ISAPI

Durante lo sviluppo di una ISAPI filter mi è capitata la necessità di creare una variabile server IIS durante la gestione della notifica SF_NOTIFY_AUTHENTICATION.

Peccato che in questa notifica il parametro pvNotification passato da IIS sia di tipo PHTTP_FILTER_AUTHENT e non vi sia il modo di recuperare la struttura di tipo PHTTP_FILTER_PREPROC_HEADERS che contiene il metodo AddHeader.

Dopo un po' di tentativi ho percorso questa strada:

 

1. Definisco i seguenti typedef e define

   1: #define MYISAPI_HEADER       "MYISAPI-HEADER:"
   2: #define HTTP_MYISAPI_HEADER    "HTTP_MYISAPI_HEADER"
   3:  
   4: typedef BOOL (WINAPI * PAddHeader) 
   5:               (
   6:                 struct _HTTP_FILTER_CONTEXT * pfc,
   7:                 LPSTR                         lpszName,
   8:                 LPSTR                         lpszValue
   9:               );

2. Nella notifica SF_NOTIFY_PREPROC_HEADERS creo una variabile server che contiene l'indirizzo del metodo AddHeader come nel codice seguente



   1: TCHAR szTmp[256];
   2: sprintf_s(szTmp, sizeof(szTmp), "%08lx", ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->AddHeader);
   3: if(((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->HttpStatus == 0)
   4: {
   5:     TCHAR szValue[256];
   6:     DWORD dwValue = sizeof(szValue);
   7:  
   8:     *szValue = 0;
   9:     ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->GetHeader(pfc, MYISAPI_HEADER, szValue, &dwValue);
  10:  
  11:     if(*szValue == 0)
  12:         ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->AddHeader(pfc, MYISAPI_HEADER, szTmp);
  13: }
  14: return(SF_STATUS_REQ_NEXT_NOTIFICATION);

3. Nella notifica SF_NOTIFY_AUTHENTICATION utilizzo la variabile server creata precedentemente nella notifica SF_NOTIFY_PREPROC_HEADERS, eseguo il cast su il pointer a funzione definito nel typedef e la richiamo per impostare una nuova variabile server



   1: TCHAR szValue[256];
   2: DWORD dwValue = sizeof(szValue);
   3:  
   4: *szValue = 0;
   5: pfc->GetServerVariable(pfc, HTTP_MYISAPI_HEADER, szValue, &dwValue);
   6: if(*szValue != 0)
   7: {
   8:     try
   9:     {
  10:         PAddHeader pHeader = (PAddHeader)strtoul(szTmp, NULL, 16);
  11:         if(pHeader)
  12:            (pHeader)(pfc, MYISAPI_USER_ID_LDAP, W2A(pszUidLdap));    
  13:     }
  14:     catch(CException *e)
  15:     {
  16:         DumpException(e)
  17:         e->Delete();
  18:     }
  19: }

 


Funziona :)