From d73e59e9834ff2447334d7a5e576cc4a2cb219f9 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 8 Mar 2007 04:42:01 +0000 Subject: [PATCH] Moved URLEncoder down to tooling lib, added exception->querystring method. --- xmltooling/Makefile.am | 2 ++ xmltooling/XMLToolingConfig.cpp | 12 +++++++ xmltooling/XMLToolingConfig.h | 25 ++++++++++++- xmltooling/exceptions.cpp | 14 ++++++-- xmltooling/exceptions.h | 8 +++++ xmltooling/util/URLEncoder.cpp | 77 +++++++++++++++++++++++++++++++++++++++++ xmltooling/util/URLEncoder.h | 74 +++++++++++++++++++++++++++++++++++++++ xmltooling/xmltooling.vcproj | 8 +++++ 8 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 xmltooling/util/URLEncoder.cpp create mode 100644 xmltooling/util/URLEncoder.h diff --git a/xmltooling/Makefile.am b/xmltooling/Makefile.am index d1d8467..c3f76e2 100644 --- a/xmltooling/Makefile.am +++ b/xmltooling/Makefile.am @@ -92,6 +92,7 @@ utilinclude_HEADERS = \ util/StorageService.h \ util/TemplateEngine.h \ util/Threads.h \ + util/URLEncoder.h \ util/XMLConstants.h \ util/XMLHelper.h \ util/XMLObjectChildrenList.h @@ -161,6 +162,7 @@ libxmltooling_la_SOURCES = \ util/ReplayCache.cpp \ util/StorageService.cpp \ util/TemplateEngine.cpp \ + util/URLEncoder.cpp \ util/XMLConstants.cpp \ util/XMLHelper.cpp \ validation/ValidatorSuite.cpp \ diff --git a/xmltooling/XMLToolingConfig.cpp b/xmltooling/XMLToolingConfig.cpp index 4a686fe..5b245d2 100644 --- a/xmltooling/XMLToolingConfig.cpp +++ b/xmltooling/XMLToolingConfig.cpp @@ -34,6 +34,7 @@ #include "util/ReplayCache.h" #include "util/StorageService.h" #include "util/TemplateEngine.h" +#include "util/URLEncoder.h" #include "util/XMLConstants.h" #include "validation/ValidatorSuite.h" @@ -176,6 +177,12 @@ void XMLToolingConfig::setTemplateEngine(TemplateEngine* templateEngine) m_templateEngine = templateEngine; } +void XMLToolingConfig::setURLEncoder(URLEncoder* urlEncoder) +{ + delete m_urlEncoder; + m_urlEncoder = urlEncoder; +} + bool XMLToolingInternalConfig::init() { #ifdef _DEBUG @@ -226,6 +233,8 @@ bool XMLToolingInternalConfig::init() registerKeyInfoClasses(); registerEncryptionClasses(); registerSOAPClasses(); + + m_urlEncoder = new URLEncoder(); REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling); REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling); @@ -297,6 +306,9 @@ void XMLToolingInternalConfig::term() delete m_templateEngine; m_templateEngine = NULL; + delete m_urlEncoder; + m_urlEncoder = NULL; + for (vector::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) { #if defined(WIN32) FARPROC fn=GetProcAddress(static_cast(*i),"xmltooling_extension_term"); diff --git a/xmltooling/XMLToolingConfig.h b/xmltooling/XMLToolingConfig.h index 7a333d6..cd04d71 100644 --- a/xmltooling/XMLToolingConfig.h +++ b/xmltooling/XMLToolingConfig.h @@ -48,6 +48,7 @@ namespace xmltooling { class XMLTOOL_API SOAPTransport; class XMLTOOL_API StorageService; class XMLTOOL_API TemplateEngine; + class XMLTOOL_API URLEncoder; /** * Singleton object that manages library startup/shutdown.configuration. @@ -60,13 +61,17 @@ namespace xmltooling { { MAKE_NONCOPYABLE(XMLToolingConfig); protected: - XMLToolingConfig() : m_replayCache(NULL), m_templateEngine(NULL), clock_skew_secs(180) {} + XMLToolingConfig() : m_replayCache(NULL), m_templateEngine(NULL), m_urlEncoder(NULL), clock_skew_secs(180) {} /** Global ReplayCache instance. */ ReplayCache* m_replayCache; /** Global TemplateEngine instance. */ TemplateEngine* m_templateEngine; + + /** Global URLEncoder instance for use by URL-related functions. */ + URLEncoder* m_urlEncoder; + public: virtual ~XMLToolingConfig() {} @@ -158,6 +163,24 @@ namespace xmltooling { } /** + * Sets the global URLEncoder instance. + * This method must be externally synchronized with any code that uses the object. + * Any previously set object is destroyed. + * + * @param urlEncoder new URLEncoder instance to store + */ + void setURLEncoder(URLEncoder* urlEncoder); + + /** + * Returns the global URLEncoder instance. + * + * @return global URLEncoder or NULL + */ + const URLEncoder* getURLEncoder() const { + return m_urlEncoder; + } + + /** * Sets the global TemplateEngine instance. * This method must be externally synchronized with any code that uses the object. * Any previously set object is destroyed. diff --git a/xmltooling/exceptions.cpp b/xmltooling/exceptions.cpp index 56ce6d3..3b37262 100644 --- a/xmltooling/exceptions.cpp +++ b/xmltooling/exceptions.cpp @@ -23,6 +23,7 @@ #include "internal.h" #include "exceptions.h" #include "XMLToolingConfig.h" +#include "util/URLEncoder.h" #include "util/XMLConstants.h" #include "util/XMLHelper.h" @@ -222,13 +223,22 @@ string XMLToolingException::toString() const const char* msg=getMessage(); if (msg) xml=xml + "" + msg + ""; - for (map::const_iterator i=m_params.begin(); i!=m_params.end(); i++) { + for (map::const_iterator i=m_params.begin(); i!=m_params.end(); i++) xml=xml + "first + "\">" + i->second + ""; - } xml+=""; return xml; } +string XMLToolingException::toQueryString() const +{ + const URLEncoder* enc = XMLToolingConfig::getConfig().getURLEncoder(); + string q("type="); + q = q + enc->encode(getClassName()) + "&message=" + enc->encode(what()); + for (map::const_iterator i=m_params.begin(); i!=m_params.end(); i++) + q = q + '&' + i->first + '=' + enc->encode(i->second.c_str()); + return q; +} + XMLToolingException* XMLToolingException::fromStream(std::istream& in) { static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull }; diff --git a/xmltooling/exceptions.h b/xmltooling/exceptions.h index ce032e1..643adbe 100644 --- a/xmltooling/exceptions.h +++ b/xmltooling/exceptions.h @@ -276,6 +276,14 @@ namespace xmltooling { */ std::string toString() const; + /** + * Returns a set of query string name/value pairs, URL-encoded, representing the + * exception's type, message, and parameters. + * + * @return the query string representation + */ + std::string toQueryString() const; + private: std::string m_msg; mutable std::string m_processedmsg; diff --git a/xmltooling/util/URLEncoder.cpp b/xmltooling/util/URLEncoder.cpp new file mode 100644 index 0000000..633a6f2 --- /dev/null +++ b/xmltooling/util/URLEncoder.cpp @@ -0,0 +1,77 @@ +/* + * 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. + * 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. + */ + +/** + * URLEncoder.cpp + * + * Interface to a URL-encoding mechanism along with a + * default implementation. + */ + +#include "internal.h" +#include "util/URLEncoder.h" + +using namespace xmltooling; +using namespace std; + +static char x2c(char *what) +{ + register char digit; + + digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); + digit *= 16; + digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); + return(digit); +} + +void URLEncoder::decode(char* s) const +{ + register int x,y; + + for(x=0,y=0;s[y];++x,++y) + { + if((s[x] = s[y]) == '%') + { + s[x] = x2c(&s[y+1]); + y+=2; + } + else if (s[x] == '+') + { + s[x] = ' '; + } + } + s[x] = '\0'; +} + +static inline char hexchar(unsigned short s) +{ + return (s<=9) ? ('0' + s) : ('A' + s - 10); +} + +string URLEncoder::encode(const char* s) const +{ + string ret; + for (; *s; s++) { + if (isBad(*s)) { + ret+='%'; + ret+=hexchar((unsigned char)*s >> 4); + ret+=hexchar((unsigned char)*s & 0x0F); + } + else + ret+=*s; + } + return ret; +} diff --git a/xmltooling/util/URLEncoder.h b/xmltooling/util/URLEncoder.h new file mode 100644 index 0000000..d30f0f1 --- /dev/null +++ b/xmltooling/util/URLEncoder.h @@ -0,0 +1,74 @@ +/* + * 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. + * 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 xmltooling/util/URLEncoder.h + * + * Interface to a URL-encoding mechanism along with a + * default implementation. + */ + +#ifndef __xmltool_urlenc_h__ +#define __xmltool_urlenc_h__ + +#include + +namespace xmltooling { + /** + * Interface to a URL-encoding mechanism along with a default implementation. + * + * Since URL-encoding is not canonical, it's important that the same + * encoder is used during some library operations and the calling code. + * Applications can supply an alternative implementation to the library + * if required. + */ + class XMLTOOL_API URLEncoder { + MAKE_NONCOPYABLE(URLEncoder); + public: + URLEncoder() {} + virtual ~URLEncoder() {} + + /** + * Produce a URL-safe but equivalent version of the input string. + * + * @param s input string to encode + * @return a string object containing the result of encoding the input + */ + virtual std::string encode(const char* s) const; + + /** + * Perform an in-place decoding operation on the input string. + * The resulting string will be NULL-terminated. + * + * @param s input string to decode in a writable buffer + */ + virtual void decode(char* s) const; + + protected: + /** + * Returns true iff the input character requires encoding. + * + * @param ch the character to check + * @return true iff the character should be encoded + */ + virtual bool isBad(char ch) const { + static char badchars[]="=&/?:\"\\+<>#%{}|^~[]`;@"; + return (strchr(badchars,ch) || ch<=0x20 || ch>=0x7F); + } + }; +}; + +#endif /* __xmltool_urlenc_h__ */ diff --git a/xmltooling/xmltooling.vcproj b/xmltooling/xmltooling.vcproj index e09b176..6846084 100644 --- a/xmltooling/xmltooling.vcproj +++ b/xmltooling/xmltooling.vcproj @@ -259,6 +259,10 @@ > + + @@ -561,6 +565,10 @@ > + + -- 2.1.4