Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ PHP NEWS
(Bob)
. Fixed issue getting executable lines from custom wrappers. (Bob)

- Apache2handler:
. Fixed bug #61471 (POST request timeout did not handle correctly). (Zheng SHAO)

- Reflection:
. Fixed bug #46103 (ReflectionObject memory leak). (Nikita)

Expand Down
45 changes: 44 additions & 1 deletion sapi/apache2handler/sapi_apache2.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,33 @@ char *apache2_php_ini_path_override = NULL;
ZEND_TSRMLS_CACHE_DEFINE()
#endif

/* if apache's version is newer than 2.2.31 or 2.4.16 */
#if MODULE_MAGIC_COOKIE == 0x41503232UL && AP_MODULE_MAGIC_AT_LEAST(20051115,40) || \
MODULE_MAGIC_COOKIE == 0x41503234UL && AP_MODULE_MAGIC_AT_LEAST(20120211,47)
#define php_ap_map_http_request_error ap_map_http_request_error
#else
static int php_ap_map_http_request_error(apr_status_t rv, int status)
{
switch (rv) {
case AP_FILTER_ERROR: {
return AP_FILTER_ERROR;
}
case APR_ENOSPC: {
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
case APR_ENOTIMPL: {
return HTTP_NOT_IMPLEMENTED;
}
case APR_ETIMEDOUT: {
return HTTP_REQUEST_TIME_OUT;
}
default: {
return status;
}
}
}
#endif

static size_t
php_apache_sapi_ub_write(const char *str, size_t str_length)
{
Expand Down Expand Up @@ -184,6 +211,7 @@ php_apache_sapi_read_post(char *buf, size_t count_bytes)
php_struct *ctx = SG(server_context);
request_rec *r;
apr_bucket_brigade *brigade;
apr_status_t ret;

r = ctx->r;
brigade = ctx->brigade;
Expand All @@ -195,7 +223,7 @@ php_apache_sapi_read_post(char *buf, size_t count_bytes)
* need to make sure that if data is available we fill the buffer completely.
*/

while (ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) {
while ((ret=ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len)) == APR_SUCCESS) {
apr_brigade_flatten(brigade, buf, &len);
apr_brigade_cleanup(brigade);
tlen += len;
Expand All @@ -206,6 +234,14 @@ php_apache_sapi_read_post(char *buf, size_t count_bytes)
len = count_bytes - tlen;
}

if (ret != APR_SUCCESS) {
if (APR_STATUS_IS_TIMEUP(ret)) {
SG(sapi_headers).http_response_code = php_ap_map_http_request_error(ret, HTTP_REQUEST_TIME_OUT);
} else {
SG(sapi_headers).http_response_code = php_ap_map_http_request_error(ret, HTTP_BAD_REQUEST);
}
}

return tlen;
}

Expand Down Expand Up @@ -656,6 +692,13 @@ zend_first_try {
brigade = ctx->brigade;
}

if (SG(request_info).content_length > SG(read_post_bytes)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Error while attempting to read POST data: %d", SG(sapi_headers).http_response_code);
apr_brigade_cleanup(brigade);
PHPAP_INI_OFF;
return SG(sapi_headers).http_response_code;
}

if (AP2(last_modified)) {
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);
Expand Down