diff options
Diffstat (limited to 'module/mod_auth_singleid.c')
-rw-r--r-- | module/mod_auth_singleid.c | 93 |
1 files changed, 93 insertions, 0 deletions
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; |