author | Michael Krelin <hacker@klever.net> | 2007-09-22 20:56:57 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2007-09-22 20:56:57 (UTC) |
commit | 5cb71518360f865cd4448a083b5d481e6f356a3e (patch) (side-by-side diff) | |
tree | 4faeab2b1a1a14c589745be714be18471879e781 | |
parent | 5cfe3f2743c2b2eb2689090516a4e667fd8ca29a (diff) | |
download | libopkele-5cb71518360f865cd4448a083b5d481e6f356a3e.zip libopkele-5cb71518360f865cd4448a083b5d481e6f356a3e.tar.gz libopkele-5cb71518360f865cd4448a083b5d481e6f356a3e.tar.bz2 |
got rid of all pcre wrappers altogether
although all claims against pcre++ make absolutely no sense. But for now I'll
live with no wrappers at all. I may reconsider it when implementing more
sophisticated discovery mechanisms for upcoming extensions.
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | configure.ac | 47 | ||||
-rw-r--r-- | include/opkele/exception.h | 9 | ||||
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/consumer.cc | 124 | ||||
-rw-r--r-- | libopkele.pc.in | 2 |
5 files changed, 80 insertions, 106 deletions
diff --git a/configure.ac b/configure.ac index 00c6bc4..53e22ba 100644 --- a/configure.ac +++ b/configure.ac @@ -53,50 +53,9 @@ LIBCURL_CHECK_CONFIG(,,,[ AC_MSG_ERROR([no required libcurl library. get one from http://curl.haxx.se/]) ]) -want_pcre_impl="" -AC_ARG_WITH([pcre-bindings], - AC_HELP_STRING([--with-pcre-bindings=(pcrepp|none|libpcrecpp)],[Specify which pcre c++ bindings to use. 'pcrepp' stands for quite sensible library, found at http://www.daemon.de/PCRE/, 'libcrecpp' makes use of crappy bindings by google and 'none' disables internal implementation of OP discovery]), - [ - case "$withval" in - pcrepp) want_pcre_impl="pcrepp" ;; - libpcrecpp) want_pcre_impl="libpcrecpp" ;; - none) want_pcre_impl="none";; - *) AC_MSG_ERROR([I'm not sure I understand what do you want for a pcre c++ bindings]) ;; - esac - ] -) - -found_pcre_impl="" - -if test -z "$want_pcre_impl" -o "$want_pcre_impl" = "pcrepp" ; then - AC_WITH_PCRE([ - AC_WITH_PCREPP([ - found_pcre_impl=pcrepp - ]) - ],[ - AC_MSG_ERROR([no pcre library found. get one at http://www.pcre.org/]) - ] - ) - test "$want_pcre_impl,$found_pcre_impl" = "pcrepp," && AC_MSG_ERROR([no pcre++ library found. get one at http://www.daemon.de/PCRE]) -fi - -if test "$found_pcre_impl,$want_pcre_impl" = "," -o "$want_pcre_impl" = "libpcrecpp" ; then - test -z "$want_pcre_impl" || AC_MSG_NOTICE([You want to use crappy libpcre c++ bindings]) - PKG_CHECK_MODULES([LIBPCRECPP],[libpcrecpp],[ - found_pcre_impl=libpcrecpp - CXXFLAGS="$CXXFLAGS $LIBPCRECPP_CFLAGS" - LIBS="$LIBS $LIBPCRECPP_LIBS" - ],[ - test -z "$want_pcre_impl" || AC_MSG_ERROR([no libpcre c++ bindings found. why would you want it if you don't have it installed?]) - ] - ) -fi -test "$want_pcre_impl,$found_pcre_impl" = "," && AC_MSG_ERROR([no pcre c++ bindings found, use --with-pcre-bindings=none to disable code that makes use of it]) - -case "$found_pcre_impl" in - pcrepp) AC_DEFINE([USE_PCREPP],,[defined if pcre++ is to be used]) ;; - libpcrecpp) AC_DEFINE([USE_LIBPCRECPP],,[defined if crappy google bindings are to be used]) ;; -esac +PKG_CHECK_MODULES([PCRE],[libpcre],,[ + AC_MSG_ERROR([no libpcre found, go get it at http://www.pcre.org/]) +]) curl_ssl_verify_host="true" AC_ARG_ENABLE([ssl-verify-host], diff --git a/include/opkele/exception.h b/include/opkele/exception.h index 0150e6b..753a818 100644 --- a/include/opkele/exception.h +++ b/include/opkele/exception.h @@ -212,6 +212,15 @@ namespace opkele { : exception(OPKELE_E_CONS) { } }; + /** + * internal error, indicates internal libopkele problem + */ + class internal_error : public exception { + public: + internal_error(OPKELE_E_PARS) + : exception(OPKELE_E_CONS) { } + }; + } #endif /* __OPKELE_EXCEPTION_H */ diff --git a/lib/Makefile.am b/lib/Makefile.am index a68faf6..b008a52 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -5,10 +5,10 @@ INCLUDES = \ ${KONFORKA_CFLAGS} \ ${OPENSSL_CFLAGS} \ ${LIBCURL_CPPFLAGS} \ - ${PCREPP_CFLAGS} + ${PCRE_CFLAGS} libopkele_la_LIBADD = \ ${LIBCURL} \ - ${PCREPP_LIBS} \ + ${PCRE_LIBS} \ ${OPENSSL_LIBS} \ ${KONFORKA_LIBS} diff --git a/lib/consumer.cc b/lib/consumer.cc index ff5da91..df95b64 100644 --- a/lib/consumer.cc +++ b/lib/consumer.cc @@ -12,17 +12,55 @@ #include "config.h" -#if defined(USE_LIBPCRECPP) -# include <pcrecpp.h> -#elif defined(USE_PCREPP) -# include <pcre++.h> -#else - /* internal implementation won't be built */ -#endif +#include <pcre.h> namespace opkele { using namespace std; + class pcre_matches_t { + public: + int *_ov; + int _s; + + pcre_matches_t() : _ov(0), _s(0) { } + pcre_matches_t(int s) : _ov(0), _s(s) { + if(_s&1) ++_s; + _s += _s>>1; + _ov = new int[_s]; + } + ~pcre_matches_t() throw() { if(_ov) delete[] _ov; } + + int begin(int i) const { return _ov[i<<1]; } + int end(int i) const { return _ov[(i<<1)+1]; } + int length(int i) const { int t=i<<1; return _ov[t+1]-_ov[t]; } + }; + + class pcre_t { + public: + pcre *_p; + + pcre_t() : _p(0) { } + pcre_t(pcre *p) : _p(p) { } + pcre_t(const char *re,int opts) : _p(0) { + static const char *errptr; static int erroffset; + _p = pcre_compile(re,opts,&errptr,&erroffset,NULL); + if(!_p) + throw internal_error(OPKELE_CP_ string("Failed to compile regexp: ")+errptr); + } + ~pcre_t() throw() { if(_p) (*pcre_free)(_p); } + + pcre_t& operator=(pcre *p) { if(_p) (*pcre_free)(_p); _p=p; return *this; } + + operator const pcre*(void) const { return _p; } + operator pcre*(void) { return _p; } + + int exec(const string& s,pcre_matches_t& m) { + if(!_p) + throw internal_error(OPKELE_CP_ "Trying to execute absent regexp"); + return pcre_exec(_p,NULL,s.c_str(),s.length(),0,0,m._ov,m._s); + } + }; + class curl_t { public: CURL *_c; @@ -268,7 +306,6 @@ namespace opkele { } void consumer_t::retrieve_links(const string& url,string& server,string& delegate) { -#if defined(USE_LIBPCRECPP) || defined(USE_PCREPP) server.erase(); delegate.erase(); curl_t curl = curl_easy_init(); @@ -286,67 +323,36 @@ namespace opkele { r = curl_easy_perform(curl); if(r && r!=CURLE_WRITE_ERROR) throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r); - // strip out everything past body - static const char *re_hdre = "<\\s*head[^>]*>", + static const char *re_bre = "<\\s*body\\b", *re_hdre = "<\\s*head[^>]*>", *re_lre = "<\\s*link\\b([^>]+)>", *re_rre = "\\brel\\s*=\\s*['\"]\\s*([^'\"\\s]+)\\s*['\"]", *re_hre = "\\bhref\\s*=\\s*['\"]\\s*([^'\"\\s]+)\\s*['\"]"; -#if defined(USE_LIBPCRECPP) - static pcrecpp::RE_Options ro(PCRE_CASELESS|PCRE_DOTALL); - static pcrecpp::RE - bre("<body\\b.*",ro), hdre(re_hdre,ro), - lre(re_lre,ro), rre(re_rre), hre(re_hre,ro); - bre.Replace("",&html); - pcrecpp::StringPiece hpiece(html); - if(!hdre.FindAndConsume(&hpiece)) - throw bad_input(OPKELE_CP_ "failed to find head"); - string attrs; - while(lre.FindAndConsume(&hpiece,&attrs)) { - pcrecpp::StringPiece rel, href; - if(!(rre.PartialMatch(attrs,&rel) && hre.PartialMatch(attrs,&href))) + pcre_matches_t m1(3), m2(3); + pcre_t bre(re_bre,PCRE_CASELESS); + if(bre.exec(html,m1)>0) + html.erase(m1.begin(0)); + pcre_t hdre(re_hdre,PCRE_CASELESS); + if(hdre.exec(html,m1)<=0) + throw bad_input(OPKELE_CP_ "failed to find <head>"); + html.erase(0,m1.end(0)+1); + pcre_t lre(re_lre,PCRE_CASELESS), rre(re_rre,PCRE_CASELESS), hre(re_hre,PCRE_CASELESS); + while(lre.exec(html,m1)>=2) { + string attrs(html,m1.begin(1),m1.length(1)); + html.erase(0,m1.end(0)+1); + if(!( rre.exec(attrs,m1)>=2 && hre.exec(attrs,m2)>=2 )) continue; + string rel(attrs,m1.begin(1),m1.length(1)); + string href(attrs,m2.begin(1),m2.length(1)); if(rel=="openid.server") { - href.CopyToString(&server); - if(!delegate.empty()) - break; + server = href; + if(!delegate.empty()) break; }else if(rel=="openid.delegate") { - href.CopyToString(&delegate); - if(!server.empty()) - break; - } - } -#elif defined(USE_PCREPP) - pcrepp::Pcre bre("<body\\b",PCRE_CASELESS); - if(bre.search(html)) - html.erase(bre.get_match_start()); - pcrepp::Pcre hdre(re_hdre,PCRE_CASELESS); - if(!hdre.search(html)) - throw bad_input(OPKELE_CP_ "failed to find head"); - html.erase(0,hdre.get_match_end()+1); - pcrepp::Pcre lre(re_lre,PCRE_CASELESS), rre(re_rre,PCRE_CASELESS), hre(re_hre,PCRE_CASELESS); - while(lre.search(html)) { - string attrs = lre[0]; - html.erase(0,lre.get_match_end()+1); - if(!(rre.search(attrs)&&hre.search(attrs))) - continue; - if(rre[0]=="openid.server") { - server = hre[0]; - if(!delegate.empty()) - break; - }else if(rre[0]=="openid.delegate") { - delegate = hre[0]; - if(!server.empty()) - break; + delegate = href; + if(!server.empty()) break; } } -#else - #error "I must have gone crazy" -#endif if(server.empty()) throw failed_assertion(OPKELE_CP_ "The location has no openid.server declaration"); -#else /* none of the RE bindings enabled */ - throw not_implemented(OPKELE_CP_ "No internal implementation of retrieve_links were provided at compile-time"); -#endif } assoc_t consumer_t::find_assoc(const string& server) { diff --git a/libopkele.pc.in b/libopkele.pc.in index 286720e..5f8684b 100644 --- a/libopkele.pc.in +++ b/libopkele.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: libopkele Description: C++ implementation of OpenID protocol Version: @VERSION@ -Requires: openssl @KONFORKA_KONFORKA@ +Requires: openssl libpcre @KONFORKA_KONFORKA@ Cflags: -I${includedir} @LIBCURL_CPPFLAGS@ @PCREPP_CFLAGS@ Libs: -L${libdir} -lopkele @LIBCURL@ @PCREPP_LIBS@ |