diff options
author | Stef Walter <stef@memberwebs.com> | 2009-08-19 17:38:46 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2009-08-19 17:38:46 +0000 |
commit | 2ba9d4412caec104410637674b179820eced7f02 (patch) | |
tree | 46643528390b55b2dc60138eaa275b3f6f44983a | |
parent | c7c67be49fb2b7307900db7e3da4b460f5603ac6 (diff) |
Support POST responses back from the provider
-rw-r--r-- | module/consumer.cc | 8 | ||||
-rw-r--r-- | module/mod_auth_singleid.c | 93 | ||||
-rw-r--r-- | module/mod_auth_singleid.h | 2 |
3 files changed, 102 insertions, 1 deletions
diff --git a/module/consumer.cc b/module/consumer.cc index cbdcfe3..c750771 100644 --- a/module/consumer.cc +++ b/module/consumer.cc @@ -570,7 +570,13 @@ sid_consumer_authenticate(sid_request_t *req, sid_storage_t *store, assert (req); - const char *qs = sid_request_qs (req); + const char *qs; + + if (strcmp (sid_request_method (req), "POST") == 0) + qs = sid_request_form (req); + else + qs = sid_request_qs (req); + parse_query_string (qs, params); filter_prefixed_params (params, openid, "openid."); diff --git a/module/mod_auth_singleid.c b/module/mod_auth_singleid.c index 5847829..53b1f04 100644 --- a/module/mod_auth_singleid.c +++ b/module/mod_auth_singleid.c @@ -75,6 +75,8 @@ extern module AP_MODULE_DECLARE_DATA auth_singleid_module; #define VALID_NAME "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-." #define VALID_ALIAS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" +#define MAX_POST_SIZE 256 * 1024 + enum { NONE = 0, SUFFIX = 1, @@ -759,6 +761,97 @@ sid_request_qs (sid_request_t *req) } const char* +sid_request_form (sid_request_t *req) +{ + int bytes, eos; + apr_size_t count; + apr_status_t rv; + apr_bucket_brigade *bb; + apr_bucket_brigade *bbin; + char *buf; + apr_bucket *b; + apr_bucket *nextb; + apr_bucket *copied; + const char *clen; + const char *data; + apr_size_t len; + request_rec *r = req->rec; + + clen = apr_table_get (r->headers_in, "Content-Length"); + if (clen != NULL) { + bytes = strtol (clen, NULL, 0); + if (bytes >= MAX_POST_SIZE) { + ap_log_rerror (APLOG_MARK, APLOG_ERR, 0, r, + "Request too big (%d bytes; limit %d)", + bytes, MAX_POST_SIZE); + return NULL; + } + } else { + bytes = MAX_POST_SIZE; + } + + bb = apr_brigade_create (r->pool, r->connection->bucket_alloc); + bbin = apr_brigade_create (r->pool, r->connection->bucket_alloc); + count = eos = 0; + + do { + rv = ap_get_brigade (r->input_filters, bbin, AP_MODE_READBYTES, + APR_BLOCK_READ, bytes); + if (rv != APR_SUCCESS) + return NULL; + for (b = APR_BRIGADE_FIRST (bbin); + b != APR_BRIGADE_SENTINEL (bbin); + b = nextb) { + nextb = APR_BUCKET_NEXT (b); + if (APR_BUCKET_IS_EOS (b)) + eos = 1; + if (!APR_BUCKET_IS_METADATA (b)) { + if (b->length != (apr_size_t)(-1)) { + count += b->length; + if (count > MAX_POST_SIZE) + apr_bucket_delete (b); + } + } + if (count <= MAX_POST_SIZE) { + if (b->length != 0) { + rv = apr_bucket_read (b, &data, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + ap_log_rerror (APLOG_MARK, APLOG_ERR, rv, r, + "Error reading post data in apr_bucket_read."); + return NULL; + } + if (len > 0) { + copied = apr_bucket_transient_create (apr_pmemdup (r->pool, data, len), + len, r->connection->bucket_alloc); + apr_bucket_delete (b); + APR_BRIGADE_INSERT_TAIL (bb, copied); + } + } + } + } + apr_brigade_cleanup (bbin); + } while (!eos); + + if (count > MAX_POST_SIZE) { + ap_log_rerror (APLOG_MARK, APLOG_ERR, 0, r, + "Request too big (%d bytes; limit %d)", + bytes, MAX_POST_SIZE); + return NULL; + } + + buf = apr_palloc (r->pool, count + 1); + rv = apr_brigade_flatten (bb, buf, &count); + if (rv != APR_SUCCESS) { + ap_log_rerror (APLOG_MARK, APLOG_ERR, rv, r, + "Error flattenning reading form data"); + return NULL; + } + + buf[count] = '\0'; + return buf; +} + +const char* sid_request_method (sid_request_t *req) { return req->rec->method; diff --git a/module/mod_auth_singleid.h b/module/mod_auth_singleid.h index 2619c3f..4ad3500 100644 --- a/module/mod_auth_singleid.h +++ b/module/mod_auth_singleid.h @@ -28,6 +28,8 @@ void sid_request_log_error (sid_request_t *req, const char* sid_request_qs (sid_request_t *req); +const char* sid_request_form (sid_request_t *req); + const char* sid_request_url (sid_request_t *req, int with_path); |