| 34 | #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX |
| 35 | |
| 36 | AP_DECLARE(int) ap_xml_parse_input(request_rec * r, apr_xml_doc **pdoc) |
| 37 | { |
| 38 | apr_xml_parser *parser; |
| 39 | apr_bucket_brigade *brigade; |
| 40 | int seen_eos; |
| 41 | apr_status_t status; |
| 42 | char errbuf[200]; |
| 43 | apr_size_t total_read = 0; |
| 44 | apr_size_t limit_xml_body = ap_get_limit_xml_body(r); |
| 45 | int result = HTTP_BAD_REQUEST; |
| 46 | |
| 47 | parser = apr_xml_parser_create(r->pool); |
| 48 | brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); |
| 49 | |
| 50 | seen_eos = 0; |
| 51 | total_read = 0; |
| 52 | |
| 53 | do { |
| 54 | apr_bucket *bucket; |
| 55 | |
| 56 | /* read the body, stuffing it into the parser */ |
| 57 | status = ap_get_brigade(r->input_filters, brigade, |
| 58 | AP_MODE_READBYTES, APR_BLOCK_READ, |
| 59 | READ_BLOCKSIZE); |
| 60 | |
| 61 | if (status != APR_SUCCESS) { |
| 62 | result = ap_map_http_request_error(status, HTTP_BAD_REQUEST); |
| 63 | goto read_error; |
| 64 | } |
| 65 | |
| 66 | for (bucket = APR_BRIGADE_FIRST(brigade); |
| 67 | bucket != APR_BRIGADE_SENTINEL(brigade); |
| 68 | bucket = APR_BUCKET_NEXT(bucket)) |
| 69 | { |
| 70 | const char *data; |
| 71 | apr_size_t len; |
| 72 | |
| 73 | if (APR_BUCKET_IS_EOS(bucket)) { |
| 74 | seen_eos = 1; |
| 75 | break; |
| 76 | } |
| 77 | |
| 78 | if (APR_BUCKET_IS_METADATA(bucket)) { |
| 79 | continue; |
| 80 | } |
| 81 | |
| 82 | status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); |
| 83 | if (status != APR_SUCCESS) { |
| 84 | goto read_error; |
| 85 | } |
| 86 | |
| 87 | total_read += len; |
| 88 | if (total_read > limit_xml_body) { |
| 89 | ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00539) |
| 90 | "XML request body is larger than the configured " |
| 91 | "limit of %lu", (unsigned long)limit_xml_body); |
| 92 | result = HTTP_REQUEST_ENTITY_TOO_LARGE; |
| 93 | goto read_error; |
no test coverage detected