/*
- * Copyright 2001-2006 Internet2
+ * Copyright 2001-2007 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "internal.h"
#include "AbstractSPRequest.h"
#include "Application.h"
+#include "ServiceProvider.h"
+#include "SessionCache.h"
#include "util/CGIParser.h"
#include <log4cpp/Category.hh>
using namespace log4cpp;
using namespace std;
-AbstractSPRequest::AbstractSPRequest(const Application* app)
- : m_app(app), m_log(&Category::getInstance(SHIBSP_LOGCAT)), m_parser(NULL)
+AbstractSPRequest::AbstractSPRequest()
+ : m_sp(NULL), m_mapper(NULL), m_app(NULL), m_sessionTried(false), m_session(NULL),
+ m_log(&Category::getInstance(SHIBSP_LOGCAT)), m_parser(NULL)
{
- if (m_app)
- return;
+ m_sp=SPConfig::getConfig().getServiceProvider();
+ m_sp->lock();
}
AbstractSPRequest::~AbstractSPRequest()
{
+ if (m_session)
+ m_session->unlock();
+ if (m_mapper)
+ m_mapper->unlock();
+ if (m_sp)
+ m_sp->unlock();
delete m_parser;
}
+RequestMapper::Settings AbstractSPRequest::getRequestSettings() const
+{
+ if (m_mapper)
+ return m_settings;
+
+ // Map request to application and content settings.
+ m_mapper=m_sp->getRequestMapper();
+ m_mapper->lock();
+ return m_settings = m_mapper->getSettings(*this);
+
+}
+
+const Application& AbstractSPRequest::getApplication() const
+{
+ if (!m_app) {
+ // Now find the application from the URL settings
+ m_app=m_sp->getApplication(getRequestSettings().first->getString("applicationId").second);
+ if (!m_app)
+ throw ConfigurationException("Unable to map request to application settings, check configuration.");
+ }
+ return *m_app;
+}
+
+Session* AbstractSPRequest::getSession() const
+{
+ // Only attempt this once.
+ if (m_sessionTried)
+ return m_session;
+ m_sessionTried = true;
+
+ // Get session ID from cookie.
+ const Application& app = getApplication();
+ pair<string,const char*> shib_cookie = app.getCookieNameProps("_shibsession_");
+ const char* session_id = getCookie(shib_cookie.first.c_str());
+ if (!session_id || !*session_id)
+ return NULL;
+
+ // Need address checking and timeout settings.
+ int timeout=0;
+ bool consistent=true;
+ const PropertySet* props=app.getPropertySet("Sessions");
+ if (props) {
+ pair<bool,unsigned int> p=props->getUnsignedInt("timeout");
+ if (p.first)
+ timeout = p.second;
+ pair<bool,bool> pcheck=props->getBool("consistentAddress");
+ if (pcheck.first)
+ consistent = pcheck.second;
+ }
+
+ // The cache will either silently pass a session or NULL back, or throw an exception out.
+ return m_session = getServiceProvider().getSessionCache()->find(
+ session_id, app, consistent ? getRemoteAddr().c_str() : NULL, timeout
+ );
+}
+
+const char* AbstractSPRequest::getRequestURL() const {
+ if (m_url.empty()) {
+ // Compute the full target URL
+ int port = getPort();
+ const char* scheme = getScheme();
+ m_url = string(scheme) + "://" + getHostname();
+ if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) {
+ ostringstream portstr;
+ portstr << port;
+ m_url += ":" + portstr.str();
+ }
+ scheme = getRequestURI();
+ if (scheme)
+ m_url += scheme;
+ }
+ return m_url.c_str();
+}
+
const char* AbstractSPRequest::getParameter(const char* name) const
{
if (!m_parser)