+
+ // 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)) {
+ StorageService* storage = conf.getServiceProvider()->getStorageService(ssid.c_str());
+ if (storage) {
+ if (storage->readString("RelayState",key,&relayState)>0)
+ storage->deleteString("RelayState",key);
+ else
+ relayState = "default";
+ }
+ else {
+ Category::getInstance(SHIBSP_LOGCAT".Handler").error(
+ "Storage-backed RelayState with invalid StorageService ID (%s)", ssid.c_str()
+ );
+ relayState = "default";
+ }
+ }
+ else if (conf.isEnabled(SPConfig::InProcess)) {
+ // In process, we should be able to cast down to a full SPRequest.
+ SPRequest& request = dynamic_cast<SPRequest&>(httpRequest);
+ DDF out,in = DDF("get::RelayState").structure();
+ in.addmember("id").string(ssid.c_str());
+ in.addmember("key").string(key);
+ DDFJanitor jin(in),jout(out);
+ out = request.getServiceProvider().getListenerService()->send(in);
+ if (!out.isstring())
+ throw IOException("StorageService-backed RelayState mechanism did not return a state value.");
+ relayState = out.string();
+ }
+ }
+ }