void AbstractHandler::recoverRelayState( const Application& application, const HTTPRequest& request, HTTPResponse& response, string& relayState, bool clear ) const { SPConfig& conf = SPConfig::getConfig(); // Look for StorageService-backed state of the form "ss:SSID:key". const char* state = relayState.c_str(); if (strstr(state,"ss:")==state) { state += 3; const char* key = strchr(state,':'); if (key) { string ssid = relayState.substr(3, key - state); key++; if (!ssid.empty() && *key) { if (conf.isEnabled(SPConfig::OutOfProcess)) { #ifndef SHIBSP_LITE StorageService* storage = conf.getServiceProvider()->getStorageService(ssid.c_str()); if (storage) { ssid = key; if (storage->readString("RelayState",ssid.c_str(),&relayState)>0) { if (clear) storage->deleteString("RelayState",ssid.c_str()); return; } else relayState.erase(); } else { m_log.error("Storage-backed RelayState with invalid StorageService ID (%s)", ssid.c_str()); relayState.erase(); } #endif } else if (conf.isEnabled(SPConfig::InProcess)) { DDF out,in = DDF("get::RelayState").structure(); in.addmember("id").string(ssid.c_str()); in.addmember("key").string(key); in.addmember("clear").integer(clear ? 1 : 0); DDFJanitor jin(in),jout(out); out = application.getServiceProvider().getListenerService()->send(in); if (!out.isstring()) { m_log.error("StorageService-backed RelayState mechanism did not return a state value."); relayState.erase(); } else { relayState = out.string(); return; } } } } } // Look for cookie-backed state of the form "cookie:key". if (strstr(state,"cookie:")==state) { state += 7; if (*state) { // Pull the value from the "relay state" cookie. pair<string,const char*> relay_cookie = application.getCookieNameProps("_shibstate_"); relay_cookie.first = string("_shibstate_") + state; state = request.getCookie(relay_cookie.first.c_str()); if (state && *state) { // URL-decode the value. char* rscopy=strdup(state); XMLToolingConfig::getConfig().getURLEncoder()->decode(rscopy); relayState = rscopy; free(rscopy); if (clear) { string exp(relay_cookie.second); exp += "; expires=Mon, 01 Jan 2001 00:00:00 GMT"; response.setCookie(relay_cookie.first.c_str(), exp.c_str()); } return; } } relayState.erase(); } // Check for "default" value (or the old "cookie" value that might come from stale bookmarks). if (relayState.empty() || relayState == "default" || relayState == "cookie") { pair<bool,const char*> homeURL=application.getString("homeURL"); if (homeURL.first) relayState=homeURL.second; else { // Compute a URL to the root of the site. int port = request.getPort(); const char* scheme = request.getScheme(); relayState = string(scheme) + "://" + request.getHostname(); if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) { ostringstream portstr; portstr << port; relayState += ":" + portstr.str(); } relayState += '/'; } } }