summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--acinclude.m46
-rw-r--r--configure.ac41
-rw-r--r--lib/consumer.cc53
3 files changed, 88 insertions, 12 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 349d3cf..532f978 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -84,8 +84,8 @@ dnl Outputs:
dnl AC_SUBST: PCRE_CONFIG PCRE_PREFIX PCRE_EXEC_PREFIX
dnl PCRE_VERSION PCRE_CFLAGS PCRE_LIBS
dnl PCRE_LIBS_POSIX PCRE_CFLAGS_POSIX
-dnl AM_CONDITIONAL: HAVE_PCRE
dnl AC_DEFINE: HAVE_PCRE PCRE_VERSION
+dnl env: HAVE_PCRE=yes|no
AC_DEFUN([AC_WITH_PCRE],[
HAVE_PCRE="no"
PCRE_CONFIG=""
@@ -142,15 +142,14 @@ AC_DEFUN([AC_WITH_PCRE],[
fi
fi
fi
- AM_CONDITIONAL([HAVE_PCRE],[test "${HAVE_PCRE}" = "yes"])
])
dnl AC_WITH_PCREPP([ACTION-IF-FOUND[,ACTION-IF-NOT-FOUND]])
dnl Outputs:
dnl AC_SUBST: PCREPP_CONFIG PCREPP_PREFIX PCREPP_EXEC_PREFIX
dnl PCREPP_VERSION PCREPP_CFLAGS PCREPP_LIBS
-dnl AM_CONDITIONAL: HAVE_PCREPP
dnl AC_DEFINE: HAVE_PCREPP PCREPP_VERSION
+dnl env: HAVE_PCREPP=yes|no
AC_DEFUN([AC_WITH_PCREPP],[
HAVE_PCREPP="no"
PCREPP_CONFIG=""
@@ -207,7 +206,6 @@ AC_DEFUN([AC_WITH_PCREPP],[
fi
fi
fi
- AM_CONDITIONAL([HAVE_PCREPP],[test "${HAVE_PCREPP}" = "yes"])
])
m4_include([acinclude.d/libcurl.m4])
diff --git a/configure.ac b/configure.ac
index 2094273..00c6bc4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,14 +52,51 @@ fi
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(,[
- AC_MSG_ERROR([no pcre++ library found. get one at http://www.daemon.de/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
curl_ssl_verify_host="true"
AC_ARG_ENABLE([ssl-verify-host],
diff --git a/lib/consumer.cc b/lib/consumer.cc
index 8f66688..299b3bc 100644
--- a/lib/consumer.cc
+++ b/lib/consumer.cc
@@ -7,12 +7,19 @@
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <curl/curl.h>
-#include <pcre++.h>
#include <iostream>
#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
+
namespace opkele {
using namespace std;
@@ -261,6 +268,7 @@ 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();
@@ -278,17 +286,44 @@ namespace opkele {
r = curl_easy_perform(curl);
if(r && r!=CURLE_WRITE_ERROR)
throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r);
- pcrepp::Pcre bre("<body\\b",PCRE_CASELESS);
// strip out everything past body
+ static const char *re_hdre = "<head[^>]*>",
+ *re_lre = "<link\\b([^>]+)>",
+ *re_rre = "\\brel=['\"]([^'\"]+)['\"]",
+ *re_hre = "\\bhref=['\"]([^'\"]+)['\"]";
+#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)))
+ continue;
+ if(rel=="openid.server") {
+ href.CopyToString(&server);
+ 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("<head[^>]*>",PCRE_CASELESS);
+ 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("<link\\b([^>]+)>",PCRE_CASELESS),
- rre("\\brel=['\"]([^'\"]+)['\"]",PCRE_CASELESS),
- hre("\\bhref=['\"]([^'\"]+)['\"]",PCRE_CASELESS);
+ 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);
@@ -304,8 +339,14 @@ namespace opkele {
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) {