| 719 | } |
| 720 | |
| 721 | AP_DECLARE(int) ap_parse_request_line(request_rec *r) |
| 722 | { |
| 723 | core_server_config *conf = ap_get_core_module_config(r->server->module_config); |
| 724 | int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE); |
| 725 | enum { |
| 726 | rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace, |
| 727 | rrl_missinguri, rrl_baduri, rrl_badprotocol, rrl_trailingtext, |
| 728 | rrl_badmethod09, rrl_reject09 |
| 729 | } deferred_error = rrl_none; |
| 730 | apr_size_t len = 0; |
| 731 | char *uri, *ll; |
| 732 | |
| 733 | r->method = r->the_request; |
| 734 | |
| 735 | /* If there is whitespace before a method, skip it and mark in error */ |
| 736 | if (apr_isspace(*r->method)) { |
| 737 | deferred_error = rrl_badwhitespace; |
| 738 | for ( ; apr_isspace(*r->method); ++r->method) |
| 739 | ; |
| 740 | } |
| 741 | |
| 742 | /* Scan the method up to the next whitespace, ensure it contains only |
| 743 | * valid http-token characters, otherwise mark in error |
| 744 | */ |
| 745 | if (strict) { |
| 746 | ll = (char*) ap_scan_http_token(r->method); |
| 747 | } |
| 748 | else { |
| 749 | ll = (char*) ap_scan_vchar_obstext(r->method); |
| 750 | } |
| 751 | |
| 752 | if (((ll == r->method) || (*ll && !apr_isspace(*ll))) |
| 753 | && deferred_error == rrl_none) { |
| 754 | deferred_error = rrl_badmethod; |
| 755 | ll = strpbrk(ll, "\t\n\v\f\r "); |
| 756 | } |
| 757 | |
| 758 | /* Verify method terminated with a single SP, or mark as specific error */ |
| 759 | if (!ll) { |
| 760 | if (deferred_error == rrl_none) |
| 761 | deferred_error = rrl_missinguri; |
| 762 | r->protocol = uri = ""; |
| 763 | goto rrl_done; |
| 764 | } |
| 765 | else if (strict && ll[0] && apr_isspace(ll[1]) |
| 766 | && deferred_error == rrl_none) { |
| 767 | deferred_error = rrl_excesswhitespace; |
| 768 | } |
| 769 | |
| 770 | /* Advance uri pointer over leading whitespace, NUL terminate the method |
| 771 | * If non-SP whitespace is encountered, mark as specific error |
| 772 | */ |
| 773 | for (uri = ll; apr_isspace(*uri); ++uri) |
| 774 | if (*uri != ' ' && deferred_error == rrl_none) |
| 775 | deferred_error = rrl_badwhitespace; |
| 776 | *ll = '\0'; |
| 777 | |
| 778 | if (!*uri && deferred_error == rrl_none) |
no test coverage detected