[cpp-sp] branch main updated: Move HTTP request/response interfaces/impls out of xmltooling.
Scott Cantor
cantor.2 at osu.edu
Mon Dec 2 16:16:17 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=33077df5ef8857c2a4f02f341e3abd5119d505d7
The following commit(s) were added to refs/heads/main by this push:
new 33077df5 Move HTTP request/response interfaces/impls out of xmltooling.
33077df5 is described below
commit 33077df5ef8857c2a4f02f341e3abd5119d505d7
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Dec 2 11:16:12 2024 -0500
Move HTTP request/response interfaces/impls out of xmltooling.
---
shibsp/Application.h | 4 +-
shibsp/Makefile.am | 10 +
shibsp/RequestMapper.h | 7 +-
shibsp/SPRequest.h | 30 ++-
shibsp/ServiceProvider.cpp | 2 +-
shibsp/SessionCache.h | 39 +---
shibsp/handler/AbstractHandler.h | 20 +-
shibsp/handler/AssertionConsumerService.h | 12 +-
shibsp/handler/Handler.h | 16 +-
shibsp/handler/LogoutHandler.h | 8 +-
shibsp/handler/RemotedHandler.h | 16 +-
shibsp/handler/impl/AbstractHandler.cpp | 2 +-
shibsp/handler/impl/AttributeCheckerHandler.cpp | 2 +-
shibsp/handler/impl/LogoutHandler.cpp | 2 +-
shibsp/handler/impl/RemotedHandler.cpp | 22 --
shibsp/impl/StorageServiceSessionCache.cpp | 5 +-
shibsp/impl/StorageServiceSessionCache.h | 29 +--
shibsp/impl/StoredSession.cpp | 12 +-
shibsp/impl/XMLApplication.h | 2 +-
shibsp/internal.h | 2 +-
shibsp/io/GenericRequest.h | 221 ++++++++++++++++++++
shibsp/io/GenericResponse.h | 78 +++++++
shibsp/io/HTTPRequest.h | 128 ++++++++++++
shibsp/io/HTTPResponse.h | 161 +++++++++++++++
shibsp/io/impl/HTTPRequest.cpp | 259 ++++++++++++++++++++++++
shibsp/io/impl/HTTPResponse.cpp | 172 ++++++++++++++++
shibsp/util/CGIParser.cpp | 2 +-
shibsp/util/CGIParser.h | 8 +-
28 files changed, 1104 insertions(+), 167 deletions(-)
diff --git a/shibsp/Application.h b/shibsp/Application.h
index 5e80059d..b4f16ac9 100644
--- a/shibsp/Application.h
+++ b/shibsp/Application.h
@@ -34,7 +34,6 @@
namespace xmltooling {
class XMLTOOL_API CredentialResolver;
- class XMLTOOL_API GenericRequest;
class XMLTOOL_API RWLock;
class XMLTOOL_API SOAPTransport;
class XMLTOOL_API StorageService;
@@ -43,6 +42,7 @@ namespace xmltooling {
namespace shibsp {
class SHIBSP_API Attribute;
+ class SHIBSP_API GenericRequest;
class SHIBSP_API Handler;
class SHIBSP_API ServiceProvider;
class SHIBSP_API SessionInitiator;
@@ -260,7 +260,7 @@ namespace shibsp {
* @param request the request leading to the redirect
* @param url an absolute URL to validate
*/
- virtual void limitRedirect(const xmltooling::GenericRequest& request, const char* url) const;
+ virtual void limitRedirect(const GenericRequest& request, const char* url) const;
};
#if defined (_MSC_VER)
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index f5794045..a2eb0ebd 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -8,6 +8,8 @@ attrincludedir = $(includedir)/shibsp/attribute
handincludedir = $(includedir)/shibsp/handler
+ioincludedir = $(includedir)/shibsp/io
+
logincludedir = $(includedir)/shibsp/logging
remincludedir = $(includedir)/shibsp/remoting
@@ -48,6 +50,12 @@ handinclude_HEADERS = \
handler/SecuredHandler.h \
handler/SessionInitiator.h
+ioinclude_HEADERS = \
+ io/GenericRequest.h \
+ io/GenericResponse.h \
+ io/HTTPRequest.h \
+ io/HTTPResponse.h
+
loginclude_HEADERS = \
logging/Category.h \
logging/LoggingService.h \
@@ -119,6 +127,8 @@ libshibsp_la_SOURCES = \
impl/XMLApplication.cpp \
impl/XMLRequestMapper.cpp \
impl/XMLServiceProvider.cpp \
+ io/impl/HTTPRequest.cpp \
+ io/impl/HTTPResponse.cpp \
logging/impl/AbstractLoggingService.cpp \
logging/impl/Category.cpp \
logging/impl/ConsoleLoggingService.cpp \
diff --git a/shibsp/RequestMapper.h b/shibsp/RequestMapper.h
index 86513f6e..36c1e1fa 100644
--- a/shibsp/RequestMapper.h
+++ b/shibsp/RequestMapper.h
@@ -30,13 +30,10 @@
#include <shibsp/base.h>
#include <xmltooling/Lockable.h>
-namespace xmltooling {
- class XMLTOOL_API HTTPRequest;
-};
-
namespace shibsp {
class SHIBSP_API AccessControl;
+ class SHIBSP_API HTTPRequest;
class SHIBSP_API PropertySet;
/**
@@ -62,7 +59,7 @@ namespace shibsp {
* @param request SP request
* @return configuration settings and effective AccessControl plugin, if any
*/
- virtual Settings getSettings(const xmltooling::HTTPRequest& request) const=0;
+ virtual Settings getSettings(const HTTPRequest& request) const=0;
};
/**
diff --git a/shibsp/SPRequest.h b/shibsp/SPRequest.h
index 8764d796..4eeab88f 100644
--- a/shibsp/SPRequest.h
+++ b/shibsp/SPRequest.h
@@ -1,21 +1,15 @@
/**
- * Licensed to the University Corporation for Advanced Internet
- * Development, Inc. (UCAID) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * UCAID licenses this file to you under the Apache License,
- * Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the
- * License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
/**
@@ -28,8 +22,8 @@
#define __shibsp_req_h__
#include <shibsp/RequestMapper.h>
-#include <xmltooling/io/HTTPRequest.h>
-#include <xmltooling/io/HTTPResponse.h>
+#include <shibsp/io/HTTPRequest.h>
+#include <shibsp/io/HTTPResponse.h>
namespace shibsp {
@@ -46,7 +40,7 @@ namespace shibsp {
*
* <p>This interface need not be threadsafe.
*/
- class SHIBSP_API SPRequest : public virtual xmltooling::HTTPRequest, public virtual xmltooling::HTTPResponse
+ class SHIBSP_API SPRequest : public virtual HTTPRequest, public virtual HTTPResponse
{
protected:
SPRequest();
diff --git a/shibsp/ServiceProvider.cpp b/shibsp/ServiceProvider.cpp
index 6ff684cd..c7e2f37b 100644
--- a/shibsp/ServiceProvider.cpp
+++ b/shibsp/ServiceProvider.cpp
@@ -715,7 +715,7 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
Locker slocker(session, false); // pop existing lock on exit
TemplateParameters tp(&e, nullptr, session);
tp.m_map["requestURL"] = targetURL.substr(0, targetURL.find('?'));
- tp.m_request = &request;
+ //stp.m_request = &request;
return make_pair(true, sendError(log, request, app, "session", tp));
}
}
diff --git a/shibsp/SessionCache.h b/shibsp/SessionCache.h
index 4ca7cb88..4739b429 100644
--- a/shibsp/SessionCache.h
+++ b/shibsp/SessionCache.h
@@ -37,28 +37,12 @@
#include <xercesc/util/XercesDefs.hpp>
#include <xmltooling/Lockable.h>
-namespace xmltooling {
- class XMLTOOL_API HTTPRequest;
- class XMLTOOL_API HTTPResponse;
-};
-
-#ifndef SHIBSP_LITE
-# include <set>
-namespace opensaml {
- class SAML_API Assertion;
- namespace saml2 {
- class SAML_API NameID;
- };
- namespace saml2md {
- class SAML_API EntityDescriptor;
- };
-};
-#endif
-
namespace shibsp {
class SHIBSP_API Application;
class SHIBSP_API Attribute;
+ class SHIBSP_API HTTPRequest;
+ class SHIBSP_API HTTPResponse;
/**
* Encapsulates access to a user's security session.
@@ -131,17 +115,6 @@ namespace shibsp {
*/
virtual const char* getAuthnInstant() const=0;
-#ifndef SHIBSP_LITE
- /**
- * Returns the NameID associated with a session.
- *
- * <p>SAML 1.x identifiers will be promoted to the 2.0 type.</p>
- *
- * @return a SAML 2.0 NameID associated with the session, if any
- */
- virtual const opensaml::saml2::NameID* getNameID() const=0;
-#endif
-
/**
* Returns the SessionIndex provided with the session.
*
@@ -328,7 +301,7 @@ namespace shibsp {
* @param request request from client containing session, or a reference to it
* @return ID of session, if any known, or an empty string
*/
- virtual std::string active(const Application& application, const xmltooling::HTTPRequest& request)=0;
+ virtual std::string active(const Application& application, const HTTPRequest& request)=0;
/**
* Locates an existing session bound to a request.
@@ -347,7 +320,7 @@ namespace shibsp {
*/
virtual Session* find(
const Application& application,
- xmltooling::HTTPRequest& request,
+ HTTPRequest& request,
const char* client_addr=nullptr,
time_t* timeout=nullptr
)=0;
@@ -364,8 +337,8 @@ namespace shibsp {
*/
virtual void remove(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse* response=nullptr,
+ const HTTPRequest& request,
+ HTTPResponse* response=nullptr,
time_t revocationExp=0
)=0;
diff --git a/shibsp/handler/AbstractHandler.h b/shibsp/handler/AbstractHandler.h
index b25c0b01..60a29057 100644
--- a/shibsp/handler/AbstractHandler.h
+++ b/shibsp/handler/AbstractHandler.h
@@ -135,8 +135,8 @@ namespace shibsp {
*/
virtual void preservePostData(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse& response,
+ const HTTPRequest& request,
+ HTTPResponse& response,
const char* relayState
) const;
@@ -154,8 +154,8 @@ namespace shibsp {
*/
virtual DDF recoverPostData(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse& response,
+ const HTTPRequest& request,
+ HTTPResponse& response,
const char* relayState
) const;
@@ -169,7 +169,7 @@ namespace shibsp {
*/
virtual long sendPostResponse(
const Application& application,
- xmltooling::HTTPResponse& response,
+ HTTPResponse& response,
const char* url,
DDF& postData
) const;
@@ -198,7 +198,7 @@ namespace shibsp {
* @param type bitmask of property sources to use
* @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
*/
- std::pair<bool,bool> getBool(const char* name, const xmltooling::HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+ std::pair<bool,bool> getBool(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
/**
* Returns a string-valued property.
@@ -208,7 +208,7 @@ namespace shibsp {
* @param type bitmask of property sources to use
* @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
*/
- std::pair<bool,const char*> getString(const char* name, const xmltooling::HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+ std::pair<bool,const char*> getString(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
/**
* Returns an unsigned integer-valued property.
@@ -218,7 +218,7 @@ namespace shibsp {
* @param type bitmask of property sources to use
* @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
*/
- std::pair<bool,unsigned int> getUnsignedInt(const char* name, const xmltooling::HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+ std::pair<bool,unsigned int> getUnsignedInt(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
/**
* Returns an integer-valued property.
@@ -228,7 +228,7 @@ namespace shibsp {
* @param type bitmask of property sources to use
* @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
*/
- std::pair<bool,int> getInt(const char* name, const xmltooling::HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+ std::pair<bool,int> getInt(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
/** Logging object. */
Category& m_log;
@@ -238,7 +238,7 @@ namespace shibsp {
private:
std::string getPostCookieName(const Application& app, const char* relayState) const;
- DDF getPostData(const Application& application, const xmltooling::HTTPRequest& request) const;
+ DDF getPostData(const Application& application, const HTTPRequest& request) const;
};
#if defined (_MSC_VER)
diff --git a/shibsp/handler/AssertionConsumerService.h b/shibsp/handler/AssertionConsumerService.h
index de531b32..a3c1255b 100644
--- a/shibsp/handler/AssertionConsumerService.h
+++ b/shibsp/handler/AssertionConsumerService.h
@@ -81,7 +81,7 @@ namespace shibsp {
* @param httpRequest client request that initiated session
* @param issuedTo address for which security assertion was issued
*/
- void checkAddress(const Application& application, const xmltooling::HTTPRequest& httpRequest, const char* issuedTo) const;
+ void checkAddress(const Application& application, const HTTPRequest& httpRequest, const char* issuedTo) const;
/**
@@ -94,8 +94,8 @@ namespace shibsp {
*/
virtual std::pair<bool,long> finalizeResponse(
const Application& application,
- const xmltooling::HTTPRequest& httpRequest,
- xmltooling::HTTPResponse& httpResponse,
+ const HTTPRequest& httpRequest,
+ HTTPResponse& httpResponse,
std::string& relayState
) const;
@@ -182,13 +182,13 @@ namespace shibsp {
#endif
private:
std::pair<bool,long> processMessage(
- const Application& application, const xmltooling::HTTPRequest& httpRequest, xmltooling::HTTPResponse& httpResponse
+ const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse
) const;
std::pair<bool,long> sendRedirect(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse& response,
+ const HTTPRequest& request,
+ HTTPResponse& response,
const char* entityID,
const char* relayState
) const;
diff --git a/shibsp/handler/Handler.h b/shibsp/handler/Handler.h
index 49652a1d..c9e1d742 100644
--- a/shibsp/handler/Handler.h
+++ b/shibsp/handler/Handler.h
@@ -30,13 +30,11 @@
#include <shibsp/SPRequest.h>
#include <shibsp/util/PropertySet.h>
-namespace xmltooling {
- class XMLTOOL_API HTTPRequest;
- class XMLTOOL_API HTTPResponse;
-};
-
namespace shibsp {
+ class SHIBSP_API HTTPRequest;
+ class SHIBSP_API HTTPResponse;
+
/**
* Pluggable runtime functionality that implement protocols and services
*/
@@ -65,7 +63,7 @@ namespace shibsp {
* @param response outgoing HTTP response
*/
virtual void cleanRelayState(
- const Application& application, const xmltooling::HTTPRequest& request, xmltooling::HTTPResponse& response
+ const Application& application, const HTTPRequest& request, HTTPResponse& response
) const;
/**
@@ -80,7 +78,7 @@ namespace shibsp {
* @param relayState RelayState token to supply with message
*/
virtual void preserveRelayState(
- const Application& application, xmltooling::HTTPResponse& response, std::string& relayState
+ const Application& application, HTTPResponse& response, std::string& relayState
) const;
/**
@@ -98,8 +96,8 @@ namespace shibsp {
*/
virtual void recoverRelayState(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse& response,
+ const HTTPRequest& request,
+ HTTPResponse& response,
std::string& relayState,
bool clear=true
) const;
diff --git a/shibsp/handler/LogoutHandler.h b/shibsp/handler/LogoutHandler.h
index 79c60e38..5658f62b 100644
--- a/shibsp/handler/LogoutHandler.h
+++ b/shibsp/handler/LogoutHandler.h
@@ -91,8 +91,8 @@ namespace shibsp {
*/
std::pair<bool,long> notifyFrontChannel(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse& response,
+ const HTTPRequest& request,
+ HTTPResponse& response,
const std::map<std::string,std::string>* params=nullptr
) const;
@@ -119,8 +119,8 @@ namespace shibsp {
*/
std::pair<bool,long> sendLogoutPage(
const Application& application,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse& response,
+ const HTTPRequest& request,
+ HTTPResponse& response,
const char* type
) const;
};
diff --git a/shibsp/handler/RemotedHandler.h b/shibsp/handler/RemotedHandler.h
index a22a5ec5..728cd4ca 100644
--- a/shibsp/handler/RemotedHandler.h
+++ b/shibsp/handler/RemotedHandler.h
@@ -32,13 +32,11 @@
#include <set>
-namespace xmltooling {
- class XMLTOOL_API HTTPRequest;
- class XMLTOOL_API HTTPResponse;
-};
-
namespace shibsp {
+ class SHIBSP_API HTTPRequest;
+ class SHIBSP_API HTTPResponse;
+
/**
* Base class for handlers that need HTTP request/response layer to be remoted.
*/
@@ -102,7 +100,7 @@ namespace shibsp {
* @param in the dataflow object containing the remoted request
* @return a call-specific request object based on the input, to be freed by the caller
*/
- xmltooling::HTTPRequest* getRequest(const Application& app, DDF& in) const;
+ HTTPRequest* getRequest(const Application& app, DDF& in) const;
/**
* Builds a new response instance around an outgoing data object.
@@ -111,7 +109,7 @@ namespace shibsp {
* @param out the dataflow object to be returned by the caller
* @return a call-specific response object, to be freed by the caller
*/
- xmltooling::HTTPResponse* getResponse(const Application& app, DDF& out) const;
+ HTTPResponse* getResponse(const Application& app, DDF& out) const;
/**
* @Deprecated
@@ -122,7 +120,7 @@ namespace shibsp {
* @param in the dataflow object containing the remoted request
* @return a call-specific request object based on the input, to be freed by the caller
*/
- xmltooling::HTTPRequest* getRequest(DDF& in) const;
+ HTTPRequest* getRequest(DDF& in) const;
/**
* @Deprecated
@@ -133,7 +131,7 @@ namespace shibsp {
* @param out the dataflow object to be returned by the caller
* @return a call-specific response object, to be freed by the caller
*/
- xmltooling::HTTPResponse* getResponse(DDF& out) const;
+ HTTPResponse* getResponse(DDF& out) const;
/** Message address for remote half. */
std::string m_address;
diff --git a/shibsp/handler/impl/AbstractHandler.cpp b/shibsp/handler/impl/AbstractHandler.cpp
index 000854ac..ccb22612 100644
--- a/shibsp/handler/impl/AbstractHandler.cpp
+++ b/shibsp/handler/impl/AbstractHandler.cpp
@@ -128,7 +128,7 @@ void Handler::log(SPRequest::SPLogLevel level, const string& msg) const
}
void Handler::cleanRelayState(
- const Application& application, const xmltooling::HTTPRequest& request, xmltooling::HTTPResponse& response
+ const Application& application, const HTTPRequest& request, HTTPResponse& response
) const
{
pair<bool,const char*> mech = getString("relayState");
diff --git a/shibsp/handler/impl/AttributeCheckerHandler.cpp b/shibsp/handler/impl/AttributeCheckerHandler.cpp
index 548b870e..910870d3 100644
--- a/shibsp/handler/impl/AttributeCheckerHandler.cpp
+++ b/shibsp/handler/impl/AttributeCheckerHandler.cpp
@@ -195,7 +195,7 @@ pair<bool,long> AttributeCheckerHandler::run(SPRequest& request, bool isHandler)
pair<bool,bool> externalParameters =
props ? props->getBool("externalParameters") : pair<bool,bool>(false,false);
if (externalParameters.first && externalParameters.second) {
- tp.m_request = &request;
+ //tp.m_request = &request;
}
stringstream str;
diff --git a/shibsp/handler/impl/LogoutHandler.cpp b/shibsp/handler/impl/LogoutHandler.cpp
index e5d41019..c38bb0ac 100644
--- a/shibsp/handler/impl/LogoutHandler.cpp
+++ b/shibsp/handler/impl/LogoutHandler.cpp
@@ -77,7 +77,7 @@ pair<bool,long> LogoutHandler::sendLogoutPage(
pair<bool,bool> externalParameters =
props ? props->getBool("externalParameters") : pair<bool,bool>(false,false);
if (externalParameters.first && externalParameters.second) {
- tp.m_request = &request;
+ //tp.m_request = &request;
}
tp.setPropertySet(props);
diff --git a/shibsp/handler/impl/RemotedHandler.cpp b/shibsp/handler/impl/RemotedHandler.cpp
index 6c3a2651..20290c06 100644
--- a/shibsp/handler/impl/RemotedHandler.cpp
+++ b/shibsp/handler/impl/RemotedHandler.cpp
@@ -357,28 +357,6 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector<string>* headers
}
}
- if (certs) {
-#ifndef SHIBSP_LITE
- const vector<XSECCryptoX509*>& xvec = request.getClientCertificates();
- if (!xvec.empty()) {
- DDF clist = in.addmember("certificates").list();
- for (vector<XSECCryptoX509*>::const_iterator x = xvec.begin(); x!=xvec.end(); ++x) {
- DDF x509 = DDF(nullptr).string((*x)->getDEREncodingSB().rawCharBuffer());
- clist.add(x509);
- }
- }
-#else
- const vector<string>& xvec = request.getClientCertificates();
- if (!xvec.empty()) {
- DDF clist = in.addmember("certificates").list();
- for (vector<string>::const_iterator x = xvec.begin(); x!=xvec.end(); ++x) {
- DDF x509 = DDF(nullptr).string(x->c_str());
- clist.add(x509);
- }
- }
-#endif
- }
-
return in;
}
diff --git a/shibsp/impl/StorageServiceSessionCache.cpp b/shibsp/impl/StorageServiceSessionCache.cpp
index dc5fa796..8531344e 100644
--- a/shibsp/impl/StorageServiceSessionCache.cpp
+++ b/shibsp/impl/StorageServiceSessionCache.cpp
@@ -41,16 +41,15 @@
#include "handler/RemotedHandler.h"
#include "impl/StoredSession.h"
#include "impl/StorageServiceSessionCache.h"
+#include "io/HTTPRequest.h"
+#include "io/HTTPResponse.h"
#include "util/IPRange.h"
#include "util/SPConstants.h"
#include <algorithm>
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/bind.hpp>
-#include <xmltooling/io/HTTPRequest.h>
-#include <xmltooling/io/HTTPResponse.h>
#include <xmltooling/security/DataSealer.h>
-#include <xmltooling/util/NDC.h>
#include <xmltooling/util/Threads.h>
#include <xmltooling/util/URLEncoder.h>
#include <xmltooling/util/XMLHelper.h>
diff --git a/shibsp/impl/StorageServiceSessionCache.h b/shibsp/impl/StorageServiceSessionCache.h
index d67915f1..65eb1453 100644
--- a/shibsp/impl/StorageServiceSessionCache.h
+++ b/shibsp/impl/StorageServiceSessionCache.h
@@ -28,11 +28,11 @@
#define __shibsp_sscache_h__
#include "SessionCache.h"
+#include "io/HTTPResponse.h"
#include "remoting/ListenerService.h"
#include <ctime>
#include <boost/shared_ptr.hpp>
-#include <xmltooling/io/HTTPResponse.h>
namespace xmltooling {
class CondWait;
@@ -40,28 +40,11 @@ namespace xmltooling {
class Thread;
}
-#ifndef SHIBSP_LITE
-namespace opensaml {
- class Assertion;
-
- namespace saml2 {
- class NameID;
- };
-
- namespace saml2md {
- class EntityDescriptor;
- };
-};
-#endif
-
namespace shibsp {
class IPRange;
class StoredSession;
class SHIBSP_DLLLOCAL SSCache : public SessionCache
-#ifndef SHIBSP_LITE
- ,public virtual Remoted
-#endif
{
public:
SSCache(const xercesc::DOMElement* e, bool deprecationSupport);
@@ -104,13 +87,13 @@ namespace shibsp {
const std::set<std::string>* indexes
);
#endif
- std::string active(const Application& app, const xmltooling::HTTPRequest& request);
- Session* find(const Application& app, xmltooling::HTTPRequest& request, const char* client_addr=nullptr, time_t* timeout=nullptr);
+ std::string active(const Application& app, const HTTPRequest& request);
+ Session* find(const Application& app, HTTPRequest& request, const char* client_addr=nullptr, time_t* timeout=nullptr);
void remove(
const Application& app,
- const xmltooling::HTTPRequest& request,
- xmltooling::HTTPResponse* response=nullptr,
+ const HTTPRequest& request,
+ HTTPResponse* response=nullptr,
time_t revocationExp=0
);
@@ -165,7 +148,7 @@ namespace shibsp {
// handle potentially inexact address comparisons
bool compareAddresses(const char* client_addr, const char* session_addr) const;
- xmltooling::HTTPResponse::samesite_t getSameSitePolicy(const Application& app) const;
+ HTTPResponse::samesite_t getSameSitePolicy(const Application& app) const;
// management of buffered sessions
void dormant(const char* key);
diff --git a/shibsp/impl/StoredSession.cpp b/shibsp/impl/StoredSession.cpp
index eab517f3..490cdf7d 100644
--- a/shibsp/impl/StoredSession.cpp
+++ b/shibsp/impl/StoredSession.cpp
@@ -34,17 +34,7 @@
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/Threads.h>
-#ifndef SHIBSP_LITE
-# include <saml/exceptions.h>
-# include <saml/saml2/core/Assertions.h>
-# include <xmltooling/XMLToolingConfig.h>
-# include <xmltooling/util/ParserPool.h>
-# include <xmltooling/util/StorageService.h>
-# include <xercesc/util/XMLStringTokenizer.hpp>
-using namespace opensaml::saml2md;
-#else
-# include <xercesc/util/XMLDateTime.hpp>
-#endif
+#include <xercesc/util/XMLDateTime.hpp>
using namespace shibsp;
using namespace xmltooling;
diff --git a/shibsp/impl/XMLApplication.h b/shibsp/impl/XMLApplication.h
index a12c80f6..a0a44801 100644
--- a/shibsp/impl/XMLApplication.h
+++ b/shibsp/impl/XMLApplication.h
@@ -95,7 +95,7 @@ namespace shibsp {
const Handler* getAssertionConsumerServiceByProtocol(const XMLCh* protocol, const char* binding=nullptr) const;
const Handler* getHandler(const char* path) const;
void getHandlers(std::vector<const Handler*>& handlers) const;
- void limitRedirect(const xmltooling::GenericRequest& request, const char* url) const;
+ void limitRedirect(const GenericRequest& request, const char* url) const;
void receive(DDF& in, std::ostream& out);
diff --git a/shibsp/internal.h b/shibsp/internal.h
index 35f052cc..c3c01dc9 100644
--- a/shibsp/internal.h
+++ b/shibsp/internal.h
@@ -45,8 +45,8 @@
#include "logging/Category.h"
#include <memory>
-#include <xmltooling/io/HTTPRequest.h>
#include <shibsp/Application.h>
+#include <shibsp/io/HTTPRequest.h>
using namespace xercesc;
diff --git a/shibsp/io/GenericRequest.h b/shibsp/io/GenericRequest.h
new file mode 100644
index 00000000..a51e8581
--- /dev/null
+++ b/shibsp/io/GenericRequest.h
@@ -0,0 +1,221 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/io/GenericRequest.h
+ *
+ * Interface to generic protocol requests handled by agents.
+ */
+
+#ifndef __shibsp_genreq_h__
+#define __shibsp_genreq_h__
+
+#include <xmltooling/unicode.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4251 )
+#endif
+
+ /**
+ * Interface to generic protocol requests handled by agents.
+ *
+ * <p>This interface need not be threadsafe.</p>
+ */
+ class SHIBSP_API GenericRequest {
+ MAKE_NONCOPYABLE(GenericRequest);
+ protected:
+ GenericRequest();
+ public:
+ virtual ~GenericRequest();
+
+ /**
+ * Returns the URL scheme of the request (http, https, ftp, ldap, etc.)
+ *
+ * @return the URL scheme
+ */
+ virtual const char* getScheme() const=0;
+
+ /**
+ * Returns true iff the request is over a confidential channel.
+ *
+ * @return confidential channel indicator
+ */
+ virtual bool isSecure() const=0;
+
+ /**
+ * Returns hostname of service that received request.
+ *
+ * @return hostname of service
+ */
+ virtual const char* getHostname() const=0;
+
+ /**
+ * Returns incoming port.
+ *
+ * @return incoming port
+ */
+ virtual int getPort() const=0;
+
+ /**
+ * Returns true iff the request port is the default port for the request protocol.
+ *
+ * @return default port indicator
+ */
+ virtual bool isDefaultPort() const;
+
+ /**
+ * Returns the MIME type of the request, if known.
+ *
+ * @return the MIME type, or an empty string
+ */
+ virtual std::string getContentType() const=0;
+
+ /**
+ * Returns the length of the request body, if known.
+ *
+ * @return the content length, or -1 if unknown
+ */
+ virtual long getContentLength() const=0;
+
+ /**
+ * Returns the raw request body.
+ *
+ * @return the request body, or nullptr
+ */
+ virtual const char* getRequestBody() const=0;
+
+ /**
+ * Returns a decoded named parameter value from the request.
+ * If a parameter has multiple values, only one will be returned.
+ *
+ * @param name the name of the parameter to return
+ * @return a single parameter value or nullptr
+ */
+ virtual const char* getParameter(const char* name) const=0;
+
+ /**
+ * Returns all of the decoded values of a named parameter from the request.
+ * All values found will be returned.
+ *
+ * @param name the name of the parameter to return
+ * @param values a vector in which to return pointers to the decoded values
+ * @return the number of values returned
+ */
+ virtual std::vector<const char*>::size_type getParameters(
+ const char* name, std::vector<const char*>& values
+ ) const=0;
+
+ /**
+ * Returns the transport-authenticated identity associated with the request,
+ * if authentication is solely handled by the transport.
+ *
+ * @return the authenticated username or an empty string
+ */
+ virtual std::string getRemoteUser() const=0;
+
+ /**
+ * Gets the authentication type associated with the request.
+ *
+ * @return the authentication type or nullptr
+ */
+ virtual std::string getAuthType() const {
+ return "";
+ }
+
+ /**
+ * Returns the IP address of the client.
+ *
+ * @return the client's IP address
+ */
+ virtual std::string getRemoteAddr() const=0;
+
+ /**
+ * Converts a relative URL into an absolute one based on the properties of the request.
+ *
+ * @param url input URL to convert, will be modified in place
+ */
+ virtual void absolutize(std::string& url) const;
+
+ /**
+ * Returns a language range to use in selecting language-specific
+ * content for this request.
+ * <p>The syntax is that of the HTTP 1.1 Accept-Language header, even
+ * if the underlying request is not HTTP.
+ *
+ * @return an HTTP 1.1 syntax language range specifier
+ */
+ virtual std::string getLanguageRange() const {
+ return "";
+ }
+
+ /**
+ * Initializes the language matching process; call this method to begin the
+ * matching process by calling the matchLang method.
+ * <p>The language matching process is not thread-safe and must be externally
+ * syncronized.
+ *
+ * @return true iff language matching is possible
+ */
+ bool startLangMatching() const;
+
+ /**
+ * Continues the language matching process; additional calls to matchLang can
+ * be done as long as this method returns true.
+ * <p>The language matching process is not thread-safe and must be externally
+ * syncronized.
+ *
+ * @return true iff more ranges are available to match against
+ */
+ bool continueLangMatching() const;
+
+ /**
+ * Matches a language tag against the currently active range.
+ * <p>The language matching process is not thread-safe and must be externally
+ * syncronized.
+ *
+ * @param tag a language tag (e.g., an xml:lang value)
+ * @return true iff the tag matches the active range
+ */
+ bool matchLang(const XMLCh* tag) const;
+
+ /**
+ * Establish default handling of language ranges.
+ *
+ * @param langFromClient honor client's language preferences if any
+ * @param defaultRange priority list of space-delimited language tags to use by default
+ */
+ static void setLangDefaults(bool langFromClient, const XMLCh* defaultRange);
+
+ private:
+ typedef std::multimap< float,std::vector<xmltooling::xstring> > langrange_t;
+ mutable langrange_t m_langRange;
+ mutable langrange_t::const_reverse_iterator m_langRangeIter;
+ static langrange_t m_defaultRange;
+ static bool m_langFromClient;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+};
+
+#endif /* __shibsp_genreq_h__ */
diff --git a/shibsp/io/GenericResponse.h b/shibsp/io/GenericResponse.h
new file mode 100644
index 00000000..94cadf2b
--- /dev/null
+++ b/shibsp/io/GenericResponse.h
@@ -0,0 +1,78 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/io/GenericResponse.h
+ *
+ * Interface to generic protocol responses issued by agents.
+ */
+
+#ifndef __shibsp_genres_h__
+#define __shibsp_genres_h__
+
+#include <shibsp/base.h>
+
+#include <iostream>
+
+namespace shibsp {
+
+ /**
+ * Interface to generic protocol responses issued by agents.
+ *
+ * <p>This interface need not be threadsafe.</p>
+ */
+ class SHIBSP_API GenericResponse {
+ MAKE_NONCOPYABLE(GenericResponse);
+ protected:
+ GenericResponse();
+ public:
+ virtual ~GenericResponse();
+
+ /**
+ * Sets or clears the MIME type of the response.
+ *
+ * @param type the MIME type, or nullptr to clear
+ */
+ virtual void setContentType(const char* type=nullptr)=0;
+
+ /**
+ * Sends a completed response to the client along with a
+ * transport-specific "OK" indication. Used for "normal" responses.
+ *
+ * @param inputStream reference to source of response data
+ * @return a result code to return from the calling MessageEncoder
+ */
+ virtual long sendResponse(std::istream& inputStream)=0;
+
+ /**
+ * Sends an "error" response to the client along with a
+ * transport-specific error indication.
+ *
+ * @param inputStream reference to source of response data
+ * @return a result code to return from the calling MessageEncoder
+ */
+ virtual long sendError(std::istream& inputStream)=0;
+
+ /**
+ * Sends a completed response to the client.
+ *
+ * @param inputStream reference to source of response data
+ * @param status transport-specific status to return
+ * @return a result code to return from the calling MessageEncoder
+ */
+ virtual long sendResponse(std::istream& inputStream, long status)=0;
+ };
+};
+
+#endif /* __shibsp_genres_h__ */
diff --git a/shibsp/io/HTTPRequest.h b/shibsp/io/HTTPRequest.h
new file mode 100644
index 00000000..a37e44ba
--- /dev/null
+++ b/shibsp/io/HTTPRequest.h
@@ -0,0 +1,128 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/io/HTTPRequest.h
+ *
+ * Interface to HTTP requests handled by agents.
+ */
+
+#ifndef __shibsp_httpreq_h__
+#define __shibsp_httpreq_h__
+
+#include <shibsp/io/GenericRequest.h>
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4251 )
+#endif
+
+ /**
+ * Interface to HTTP requests handled by agents.
+ *
+ * <p>To supply information from the surrounding web server environment,
+ * a shim must be supplied in the form of this interface to adapt the
+ * library to different proprietary server APIs.</p>
+ *
+ * <p>This interface need not be threadsafe.</p>
+ */
+ class SHIBSP_API HTTPRequest : public GenericRequest {
+ protected:
+ HTTPRequest();
+ public:
+ virtual ~HTTPRequest();
+
+ bool isSecure() const;
+ bool isDefaultPort() const;
+ std::string getLanguageRange() const;
+
+ /**
+ * Returns the HTTP method of the request (GET, POST, etc.)
+ *
+ * @return the HTTP method
+ */
+ virtual const char* getMethod() const=0;
+
+ /**
+ * Returns the request URI.
+ *
+ * @return the request URI
+ */
+ virtual const char* getRequestURI() const=0;
+
+ /**
+ * Returns the complete request URL, including scheme, host, port, and URI.
+ *
+ * @return the request URL
+ */
+ virtual const char* getRequestURL() const=0;
+
+ /**
+ * Returns the HTTP query string appened to the request. The query
+ * string is returned without any decoding applied, everything found
+ * after the ? delimiter.
+ *
+ * @return the query string
+ */
+ virtual const char* getQueryString() const=0;
+
+ /**
+ * Returns a request header value.
+ *
+ * @param name the name of the header to return
+ * @return the header's value, or an empty string
+ */
+ virtual std::string getHeader(const char* name) const=0;
+
+ /**
+ * Get a cookie value supplied by the client.
+ *
+ * @param name name of cookie
+ * @return cookie value or nullptr
+ */
+ virtual const char* getCookie(const char* name) const;
+
+ /**
+ * Get a cookie value supplied by the client.
+ *
+ * The boolean flag enables the workaround for older clients with
+ * broken SameSite support by looking for a second cookie with
+ * a decorated name that would not carry the SameSite flag.
+ *
+ * @param name name of cookie
+ * @param sameSiteFallback enables lookaside to fallback cookie name
+ * @return cookie value or nullptr
+ */
+ virtual const char* getCookie(const char* name, bool sameSiteFallback) const;
+
+ /**
+ * Gets all the cookies supplied by the client.
+ *
+ * @return a map of cookie name/value pairs
+ */
+ virtual const std::map<std::string,std::string>& getCookies() const;
+
+ private:
+ mutable std::map<std::string,std::string> m_cookieMap;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+};
+
+#endif /* __shibsp_httpreq_h__ */
diff --git a/shibsp/io/HTTPResponse.h b/shibsp/io/HTTPResponse.h
new file mode 100644
index 00000000..56afe511
--- /dev/null
+++ b/shibsp/io/HTTPResponse.h
@@ -0,0 +1,161 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/io/HTTPResponse.h
+ *
+ * Interface to HTTP responses issued by agents.
+ */
+
+#ifndef __shibsp_httpres_h__
+#define __shibsp_httpres_h__
+
+#include <shibsp/io/GenericResponse.h>
+
+#include <string>
+#include <vector>
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4251 )
+#endif
+
+ /**
+ * Interface to HTTP response issued by agents.
+ *
+ * <p>To supply information to the surrounding web server environment,
+ * a shim must be supplied in the form of this interface to adapt the
+ * library to different proprietary server APIs.</p>
+ *
+ * <p>This interface need not be threadsafe.</p>
+ */
+ class SHIBSP_API HTTPResponse : public GenericResponse {
+ protected:
+ HTTPResponse();
+ public:
+ virtual ~HTTPResponse();
+
+ void setContentType(const char* type);
+
+ /**
+ * Sets, adds, or clears a response header.
+ *
+ * @param name header name
+ * @param value value to set, or nullptr to clear
+ * @param replace true iff this should replace existing header(s)
+ */
+ virtual void setResponseHeader(const char* name, const char* value, bool replace = false);
+
+ /** Cookie SameSite values. */
+ enum samesite_t {
+ SAMESITE_ABSENT = 0,
+ SAMESITE_NONE = 1,
+ SAMESITE_LAX = 2,
+ SAMESITE_STRICT = 3
+ };
+
+ /**
+ * Sets or unsets a client cookie.
+ *
+ * <p>The boolean flag enables the workaround for older clients with
+ * broken SameSite support by setting a second cookie with
+ * a decorated name that would not carry the SameSite flag.</p>
+ *
+ * @param name cookie name
+ * @param value value to set, or nullptr to clear
+ * @param expires optional expiration time for the cookie, 0 means session
+ * @param sameSiteValue the SameSite value to apply to the cookie
+ * @param sameSiteFallback enables setting of a fallback cookie
+ */
+ virtual void setCookie(
+ const char* name,
+ const char* value,
+ time_t expires,
+ samesite_t sameSiteValue,
+ bool sameSiteFallback);
+
+ /**
+ * Sets or unsets a client cookie.
+ *
+ * <p>Now defaults to calling the new version with a false flag.</p>
+ *
+ * @param name cookie name
+ * @param value value to set, or nullptr to clear
+ * @param expires optional expiration time for the cookie, 0 means session
+ * @param sameSiteValue the SameSite value to apply to the cookie
+ */
+ virtual void setCookie(
+ const char* name,
+ const char* value,
+ time_t expires = 0,
+ samesite_t sameSiteValue = SAMESITE_ABSENT);
+
+ /**
+ * Redirect the client to the specified URL and complete the response.
+ *
+ * <p>Any headers previously set will be sent ahead of the redirect.
+ *
+ * <p>The URL will be validated with the sanitizeURL method below.
+ *
+ * @param url location to redirect client
+ * @return a result code to return from the calling MessageEncoder
+ */
+ virtual long sendRedirect(const char* url);
+
+ /** Some common HTTP status codes. */
+ enum status_t {
+ XMLTOOLING_HTTP_STATUS_OK = 200,
+ XMLTOOLING_HTTP_STATUS_MOVED = 302,
+ XMLTOOLING_HTTP_STATUS_NOTMODIFIED = 304,
+ XMLTOOLING_HTTP_STATUS_BADREQUEST = 400,
+ XMLTOOLING_HTTP_STATUS_UNAUTHORIZED = 401,
+ XMLTOOLING_HTTP_STATUS_FORBIDDEN = 403,
+ XMLTOOLING_HTTP_STATUS_NOTFOUND = 404,
+ XMLTOOLING_HTTP_STATUS_ERROR = 500
+ };
+
+ long sendError(std::istream& inputStream);
+
+ using GenericResponse::sendResponse;
+ long sendResponse(std::istream& inputStream);
+
+ /**
+ * Returns a modifiable array of schemes to permit in sanitized URLs.
+ *
+ * <p>Updates to this array must be externally synchronized with any use
+ * of this class or its subclasses.
+ *
+ * @return a mutable array of strings containing the schemes to permit
+ */
+ static std::vector<std::string>& getAllowedSchemes();
+
+ /**
+ * Manually check for unsafe URLs vulnerable to injection attacks.
+ *
+ * @param url location to check
+ */
+ static void sanitizeURL(const char* url);
+
+ private:
+ static std::vector<std::string> m_allowedSchemes;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+};
+
+#endif /* __shibsp_httpres_h__ */
diff --git a/shibsp/io/impl/HTTPRequest.cpp b/shibsp/io/impl/HTTPRequest.cpp
new file mode 100644
index 00000000..1f147750
--- /dev/null
+++ b/shibsp/io/impl/HTTPRequest.cpp
@@ -0,0 +1,259 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * io/impl/HTTPRequest.cpp
+ *
+ * Interface to HTTP requests handled by agents.
+ */
+
+#include "internal.h"
+
+#include "io/HTTPRequest.h"
+
+#include <cstring>
+#include <boost/algorithm/string.hpp>
+#define BOOST_BIND_GLOBAL_PLACEHOLDERS
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/tokenizer.hpp>
+#include <xercesc/util/XMLStringTokenizer.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/util/Threads.h>
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace xercesc;
+using namespace boost;
+using namespace std;
+
+bool GenericRequest::m_langFromClient = true;
+GenericRequest::langrange_t GenericRequest::m_defaultRange;
+
+GenericRequest::GenericRequest() : m_langRangeIter(m_langRange.rend())
+{
+}
+
+GenericRequest::~GenericRequest()
+{
+}
+
+bool GenericRequest::isDefaultPort() const
+{
+ return false;
+}
+
+void GenericRequest::absolutize(string& url) const
+{
+ if (url.empty())
+ url = '/';
+ if (url[0] == '/') {
+ // Compute a URL to the root of the site.
+ const char* scheme = getScheme();
+ string root = string(scheme) + "://" + getHostname();
+ if (!isDefaultPort())
+ root += ":" + lexical_cast<string>(getPort());
+ url = root + url;
+ }
+}
+
+void GenericRequest::setLangDefaults(bool langFromClient, const XMLCh* defaultRange)
+{
+ m_langFromClient = langFromClient;
+ m_defaultRange.clear();
+ if (!defaultRange)
+ return;
+ float q = 0.0f;
+ XMLStringTokenizer tokens(defaultRange);
+ while (tokens.hasMoreTokens()) {
+ const XMLCh* t = tokens.nextToken();
+ if (t && *t) {
+ vector<xstring> tagArray;
+ static const XMLCh delims[] = {chDash, chNull};
+ XMLStringTokenizer tags(t, delims);
+ while (tags.hasMoreTokens())
+ tagArray.push_back(tags.nextToken());
+ m_defaultRange.insert(langrange_t::value_type(q, tagArray));
+ q -= 0.0001f;
+ }
+ }
+}
+
+bool GenericRequest::startLangMatching() const
+{
+ // This is a no-op except on the first call, to populate the
+ // range information to use in matching.
+ if (m_langRange.empty()) {
+ if (m_langFromClient) {
+ string hdr(getLanguageRange());
+ char_separator<char> sep1(", "); // tags are split by commas or spaces
+ char_separator<char> sep2("; "); // quality is separated by semicolon
+ tokenizer< char_separator<char> > tokens(hdr, sep1);
+ for (tokenizer< char_separator<char> >::iterator t = tokens.begin(); t != tokens.end(); ++t) {
+ string tag = trim_copy(*t); // handle any surrounding ws
+ tokenizer< char_separator<char> > subtokens(tag, sep2);
+ tokenizer< char_separator<char> >::iterator s = subtokens.begin();
+ if (s != subtokens.end() && *s != "*") {
+ float q = 1.0f;
+ auto_ptr_XMLCh lang((s++)->c_str());
+
+ // Check for quality tag
+ if (s != subtokens.end() && starts_with(*s, "q=")) {
+ try {
+ q = lexical_cast<float,string>(s->c_str() + 2);
+ }
+ catch (bad_lexical_cast&) {
+ q = 0.0f;
+ }
+ }
+
+ // Split range into tokens.
+ vector<xstring> tagArray;
+ static const XMLCh delims[] = {chDash, chNull};
+ XMLStringTokenizer tags(lang.get(), delims);
+ const XMLCh* tag;
+ while (tags.hasMoreTokens()) {
+ tag = tags.nextToken();
+ if (*tag != chAsterisk)
+ tagArray.push_back(tag);
+ }
+
+ if (tagArray.empty())
+ continue;
+
+ // Adjust q using the server priority list. As long as the supplied q deltas are larger than
+ // factors like .0001, the client settings will always trump ours.
+ if (!m_defaultRange.empty()) {
+ float adj = (m_defaultRange.size() + 1) * 0.0001f;
+ for (langrange_t::const_iterator prio = m_defaultRange.begin(); prio != m_defaultRange.end(); ++prio) {
+ if (prio->second == tagArray) {
+ adj = prio->first;
+ break;
+ }
+ }
+ q -= adj;
+ }
+ m_langRange.insert(langrange_t::value_type(q, tagArray));
+ }
+ }
+ }
+ else {
+ m_langRange = m_defaultRange;
+ }
+ }
+
+ m_langRangeIter = m_langRange.rbegin();
+ return (m_langRangeIter != const_cast<const langrange_t&>(m_langRange).rend());
+}
+
+bool GenericRequest::continueLangMatching() const
+{
+ return (++m_langRangeIter != const_cast<const langrange_t&>(m_langRange).rend());
+}
+
+bool GenericRequest::matchLang(const XMLCh* tag) const
+{
+ if (m_langRangeIter == const_cast<const langrange_t&>(m_langRange).rend())
+ return false;
+
+ // To match against a given range, the range has to be built up and then
+ // truncated segment by segment to look for a match against the tag.
+ // That allows more specific ranges like en-US to match the tag en.
+ // The "end" fence tells us how much of the original range to recompose
+ // into a hyphenated string, and we stop on a match, or when the fence
+ // moves back to the beginning of the array.
+ bool match = false;
+ vector<xstring>::size_type end = m_langRangeIter->second.size();
+ do {
+ // Skip single-character private extension separators.
+ while (end > 1 && m_langRangeIter->second[end-1].length() <= 1)
+ --end;
+ // Build a range from 0 to end - 1 of segments.
+ xstring compareTo(m_langRangeIter->second[0]);
+ for (vector<xstring>::size_type ix = 1; ix <= end - 1; ++ix)
+ compareTo = compareTo + chDash + m_langRangeIter->second[ix];
+ match = (compareTo.length() > 1 && XMLString::compareIStringASCII(compareTo.c_str(), tag) == 0);
+ } while (!match && --end > 0);
+ return match;
+}
+
+HTTPRequest::HTTPRequest()
+{
+}
+
+HTTPRequest::~HTTPRequest()
+{
+}
+
+bool HTTPRequest::isSecure() const
+{
+ return strcmp(getScheme(),"https")==0;
+}
+
+bool HTTPRequest::isDefaultPort() const
+{
+ if (isSecure())
+ return getPort() == 443;
+ else
+ return getPort() == 80;
+}
+
+string HTTPRequest::getLanguageRange() const
+{
+ return getHeader("Accept-Language");
+}
+
+namespace {
+ void handle_cookie_fn(map<string,string>& cookieMap, vector<string>& nvpair, const string& s) {
+ nvpair.clear();
+ split(nvpair, s, is_any_of("="));
+ if (nvpair.size() == 2) {
+ trim(nvpair[0]);
+ if (ends_with(nvpair[0], "_fgwars")) {
+ nvpair[0].erase(nvpair[0].end() - 7, nvpair[0].end());
+ }
+ cookieMap[nvpair[0]] = nvpair[1];
+ }
+ }
+}
+
+const map<string,string>& HTTPRequest::getCookies() const
+{
+ if (m_cookieMap.empty()) {
+ string cookies=getHeader("Cookie");
+ vector<string> nvpair;
+ tokenizer< char_separator<char> > nvpairs(cookies, char_separator<char>(";"));
+ for_each(nvpairs.begin(), nvpairs.end(),
+ boost::bind(handle_cookie_fn, boost::ref(m_cookieMap), boost::ref(nvpair), _1));
+ }
+ return m_cookieMap;
+}
+
+const char* HTTPRequest::getCookie(const char* name) const
+{
+ return getCookie(name, false);
+}
+
+const char* HTTPRequest::getCookie(const char* name, bool) const
+{
+ // The fallback support is implemented via the getCookies() load above
+ // so we ignore it here.
+
+ map<string,string>::const_iterator lookup = getCookies().find(name);
+ if (lookup != m_cookieMap.end()) {
+ return lookup->second.c_str();
+ }
+
+ return nullptr;
+}
diff --git a/shibsp/io/impl/HTTPResponse.cpp b/shibsp/io/impl/HTTPResponse.cpp
new file mode 100644
index 00000000..cdada70c
--- /dev/null
+++ b/shibsp/io/impl/HTTPResponse.cpp
@@ -0,0 +1,172 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * io/impl/HTTPResponse.cpp
+ *
+ * Interface to HTTP responses issued by agents.
+ */
+
+#include "internal.h"
+#include "io/HTTPResponse.h"
+
+#include <stdexcept>
+
+#include <boost/algorithm/string/predicate.hpp>
+#define BOOST_BIND_GLOBAL_PLACEHOLDERS
+#include <boost/bind.hpp>
+
+using namespace shibsp;
+using namespace boost;
+using namespace std;
+
+GenericResponse::GenericResponse()
+{
+}
+
+GenericResponse::~GenericResponse()
+{
+}
+
+vector<string> HTTPResponse::m_allowedSchemes;
+
+vector<string>& HTTPResponse::getAllowedSchemes()
+{
+ return m_allowedSchemes;
+}
+
+void HTTPResponse::sanitizeURL(const char* url)
+{
+ // predicate for checking scheme below
+ static bool (*fn)(const string&, const string&, const std::locale&) = iequals;
+
+ const char* ch;
+ for (ch=url; *ch; ++ch) {
+ if (iscntrl((unsigned char)(*ch))) // convert to unsigned to allow full range from 00-FF
+ throw domain_error("URL contained a control character.");
+ }
+
+ ch = strchr(url, ':');
+ if (!ch)
+ throw domain_error("URL is missing a colon where expected; improper URL encoding?");
+ string s(url, ch - url);
+ std::locale loc;
+ vector<string>::const_iterator i =
+ find_if(m_allowedSchemes.begin(), m_allowedSchemes.end(), boost::bind(fn, boost::cref(s), _1, boost::cref(loc)));
+ if (i != m_allowedSchemes.end())
+ return;
+
+ throw domain_error("URL contains invalid scheme.");
+}
+
+HTTPResponse::HTTPResponse()
+{
+}
+
+HTTPResponse::~HTTPResponse()
+{
+}
+
+void HTTPResponse::setContentType(const char* type)
+{
+ setResponseHeader("Content-Type", type);
+}
+
+void HTTPResponse::setCookie(const char* name, const char* value, time_t expires, samesite_t sameSiteValue)
+{
+ setCookie(name, value, expires, sameSiteValue, false);
+}
+
+void HTTPResponse::setCookie(const char* name, const char* value, time_t expires, samesite_t sameSiteValue, bool sameSiteFallback)
+{
+ string decoratedValue;
+ if (!value) {
+ decoratedValue += "; expires=Mon, 01 Jan 2001 00:00:00 GMT";
+ }
+ else {
+ decoratedValue = value;
+ if (expires > 0) {
+ expires += time(nullptr);
+#ifndef HAVE_GMTIME_R
+ struct tm* ptime = gmtime(&expires);
+#else
+ struct tm res;
+ struct tm* ptime = gmtime_r(&expires, &res);
+#endif
+ char cookietimebuf[64];
+ strftime(cookietimebuf, 64, "; expires=%a, %d %b %Y %H:%M:%S GMT", ptime);
+ decoratedValue.append(cookietimebuf);
+ }
+ }
+
+ if (sameSiteValue != SAMESITE_ABSENT) {
+ // Add SameSite to the primary cookie and optionally set a fallback cookie without SameSite.
+ switch (sameSiteValue) {
+ case SAMESITE_NONE:
+ if (sameSiteFallback) {
+ string hackedName(name);
+ setResponseHeader("Set-Cookie", hackedName.append("_fgwars=").append(decoratedValue).c_str());
+ }
+ decoratedValue.append("; SameSite=None");
+ break;
+ case SAMESITE_LAX:
+ decoratedValue.append("; SameSite=Lax");
+ break;
+ case SAMESITE_STRICT:
+ decoratedValue.append("; SameSite=Strict");
+ break;
+ default:
+ throw invalid_argument("Invalid SameSite value supplied");
+ }
+ string header(name);
+ setResponseHeader("Set-Cookie", header.append("=").append(decoratedValue).c_str());
+ }
+ else {
+ string header(name);
+ setResponseHeader("Set-Cookie", header.append("=").append(decoratedValue).c_str());
+ }
+}
+
+void HTTPResponse::setResponseHeader(const char* name, const char* value, bool)
+{
+ if (name) {
+ for (const char* ch=name; *ch; ++ch) {
+ if (iscntrl(*ch))
+ throw domain_error("Response header name contained a control character.");
+ }
+ }
+
+ if (value) {
+ for (const char* ch=value; *ch; ++ch) {
+ if (iscntrl(*ch))
+ throw domain_error("Value for response header contained a control character.");
+ }
+ }
+}
+
+long HTTPResponse::sendRedirect(const char* url)
+{
+ sanitizeURL(url);
+ return XMLTOOLING_HTTP_STATUS_MOVED;
+}
+
+long HTTPResponse::sendError(istream& inputStream)
+{
+ return sendResponse(inputStream, XMLTOOLING_HTTP_STATUS_ERROR);
+}
+
+long HTTPResponse::sendResponse(istream& inputStream)
+{
+ return sendResponse(inputStream, XMLTOOLING_HTTP_STATUS_OK);
+}
diff --git a/shibsp/util/CGIParser.cpp b/shibsp/util/CGIParser.cpp
index 85d999bf..8c767226 100644
--- a/shibsp/util/CGIParser.cpp
+++ b/shibsp/util/CGIParser.cpp
@@ -25,12 +25,12 @@
*/
#include "internal.h"
+#include "io/HTTPRequest.h"
#include "util/CGIParser.h"
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/bind.hpp>
#include <xmltooling/XMLToolingConfig.h>
-#include <xmltooling/io/HTTPRequest.h>
#include <xmltooling/util/URLEncoder.h>
using namespace shibsp;
diff --git a/shibsp/util/CGIParser.h b/shibsp/util/CGIParser.h
index 3e8c1c20..7dd3036f 100644
--- a/shibsp/util/CGIParser.h
+++ b/shibsp/util/CGIParser.h
@@ -32,12 +32,10 @@
#include <map>
#include <string>
-namespace xmltooling {
- class XMLTOOL_API HTTPRequest;
-};
-
namespace shibsp {
+ class SHIBSP_API HTTPRequest;
+
#if defined (_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4251 )
@@ -56,7 +54,7 @@ namespace shibsp {
* @param request HTTP request interface
* @param queryOnly true iff the POST body should be ignored
*/
- CGIParser(const xmltooling::HTTPRequest& request, bool queryOnly=false);
+ CGIParser(const HTTPRequest& request, bool queryOnly=false);
~CGIParser();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list