From 3abd829ef97c1b9cad9177e92c1833f8d9841ba0 Mon Sep 17 00:00:00 2001 From: warlord Date: Wed, 26 Jan 2005 19:12:15 +0000 Subject: [PATCH] Implement the ISAPI Extension callbacks. git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@1332 cb58f699-b61c-0410-a6fe-9272a202ed29 --- isapi_shib/isapi_shib.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/isapi_shib/isapi_shib.cpp b/isapi_shib/isapi_shib.cpp index fadd2ad..efde70f 100644 --- a/isapi_shib/isapi_shib.cpp +++ b/isapi_shib/isapi_shib.cpp @@ -923,6 +923,136 @@ extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificat return WriteClientError(pfc,"Server reached unreachable code, save my walrus!"); } +/****************************************************************************/ +// ISAPI Extension + +class ShibTargetIsapiE : public ShibTarget +{ +public: + ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site) : + m_cookie(NULL) + { + dynabuf ssl(5); + GetServerVariable(lpECB,"HTTPS",ssl,5); + bool SSL=(ssl=="on" || ssl=="ON"); + + // URL path always come from IIS. + dynabuf url(256); + GetServerVariable(lpECB,"URL",url,255); + + // Port may come from IIS or from site def. + dynabuf port(11); + if (site.m_port.empty() || !g_bNormalizeRequest) + GetServerVariable(lpECB,"SERVER_PORT",port,10); + else { + strncpy(port,site.m_port.c_str(),10); + static_cast(port)[10]=0; + } + + // Scheme may come from site def or be derived from IIS. + const char* scheme=site.m_scheme.c_str(); + if (!scheme || !*scheme || !g_bNormalizeRequest) { + scheme = SSL ? "https" : "http"; + } + + // Get the remote address + dynabuf remote_addr(16); + GetServerVariable(lpECB, "REMOTE_ADDR", remote_addr, 16); + + init(g_Config, string(scheme), site.m_name, atoi(port), + string(url), string(lpECB->lpszContentType ? lpECB->lpszContentType : ""), + string(remote_addr), string(lpECB->lpszMethod) + ); + + m_lpECB = lpECB; + } + ~ShibTargetIsapiE() { } + + virtual void log(ShibLogLevel level, const string &msg) { + LogEvent(NULL, (level == LogLevelDebug : EVENTLOG_DEBUG_TYPE ? + (level == LogLevelInfo : EVENTLOG_INFORMATION_TYPE ? + (level == LogLevelWarn : EVENTLOG_WARNING_TYPE ? + EVENTLOG_ERROR_TYPE))), + 2100, NULL, msg.c_str()); + } + // Not used in the extension. + //virtual string getCookies(void) { } + virtual void setCookie(const string &name, const string &value) { + // Set the cookie for later. Use it during the redirect. + m_cookie += "Set-Cookie: " + name + "=" + value + "\r\n"; + } + virtual string getArgs(void) { + return string(m_lpECB->lpszQueryString ? m_lpECB->lpszQueryString : ""); + } + virtual string getPostData(void) { + if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB? + throw ShibTargetException(SHIBRPC_OK, + "blocked too-large a post to SHIRE POST processor"); + else if (m_lpECB->cbTotalBytes != lpECB->cbAvailable) { + string cgistr; + char buf[8192]; + DWORD datalen=m_lpECB->cbTotalBytes; + while (datalen) { + DWORD buflen=8192; + BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen); + if (!ret || !buflen) + throw ShibTargetException(SHIBRPC_OK, + "error reading POST data from browser"); + cgistr.append(buf, buflen); + datalen-=buflen; + } + return cgistr; + } + else + return string(reinterpret_cast(m_lpECB->lpbData),m_lpECB->cbAvailable); + } + // Not used in the Extension + //virtual void clearHeader(const string &name) { } + //virtual void setHeader(const string &name, const string &value) { } + //virtual string getHeader(const string &name) { } + //virtual void setRemoteUser(const string &user) { } + //virtual string getRemoteUser(void) { } + virtual void* sendPage(const string &msg, const string content_type, + const pair headers[], int code) { + string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n"; + for (int k = 0; k < headers.size(); k++) { + hdr += headers[k].first + ": " + headers[k].second + "\r\n"; + } + hdr += "\r\n"; + // XXX Need to handle "code" + m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, + "200 OK", (LPDWORD)hdr.c_str()); + DWORD resplen = msg.size(); + m_lpECB->WriteClient(m_lpECB->ConnID, (LPVOID)msg.c_str(), &resplen, HSE_IO_SYNC); + return (void*)HSE_STATUS_SUCCESS; + } + virtual void* sendRedirect(const string url) { + // XXX: Don't support the httpRedirect option, yet. + string hdrs = m_cookie + "Location: " + url + "\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 40\r\n" + "Expires: 01-Jan-1997 12:00:00 GMT\r\n" + "Cache-Control: private,no-store,no-cache\r\n\r\n"; + m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, + "302 Moved", 0, (LPDWORD)hdrs.c_str()); + static const char* redmsg="Redirecting..."; + DWORD resplen=40; + m_lpECB->WriteClient(m_lpECB->ConnID, (LPVOID)redmsg, &resplen, HSE_IO_SYNC); + return (void*)HSE_STATUS_SUCCESS; + } + // Decline happens in the POST processor if this isn't the shire url + // Note that it can also happen with HTAccess, but we don't suppor that, yet. + virtual void* returnDecline(void) { + return (void*) + WriteClientError(m_lpECB, "UISAPA extension can only be unvoked to process incoming sessions." + "Make sure the mapped file extension doesn't match actual content."); + } + virtual void* returnOK(void) { return (void*) HSE_STATUS_SUCCESS; } + + LPEXTENSION_CONTROL_BLOCK m_lpECB; + string m_cookie; +}; + IRequestMapper::Settings map_request( LPEXTENSION_CONTROL_BLOCK lpECB, IRequestMapper* mapper, const site_t& site, string& target ) -- 2.1.4