-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug fix #61471 (request error handling) #2180
Conversation
@axot |
@marcosptf There may have an impact on performance, so I also think this needs a test. Is there any exists mod_php related test case to use as reference? |
@axot i don't know if this case tests can help, but are some examples: @KalleZ do you have any suggestion to us ? |
while (ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) {
...
} ap_get_brigade will return error include timeout, maybe a better way is handle error cases inside |
@marcosptf I looked around a bit, and our general coverage for SAPIs is low, so I'd be alright with no test as the fix itself is relatively simple |
@marcosptf @KalleZ Before merging to master I want do some local tests for performance and large post data, I'll report the test result when it is done. By the way, how to make this commit to merge into PHP-5.6 branch, do I need create a new commit for this purpose? |
@axot you can commit in this same branch! |
@marcosptf Thank you! |
ff13a85
to
4dfc957
Compare
I tested this patch with PHP 5.6.27 and 7.0.11 in CentOS 7. Before patch: $ nc shao-test-xxx.ap-northeast-1.elb.amazonaws.com 80
POST /ajax/errors/test HTTP/1.1
HOST: shao-test-xxx.ap-northeast-1.elb.amazonaws.com
User-Agent: telnet
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
b=te
HTTP/1.1 200 OK
Date: Sat, 03 Dec 2016 12:55:15 GMT
Server: Apache
Charset: x-user-defined
Content-Length: 64
Connection: close
Content-Type: application/x-msgpack With this patch: $ nc shao-test-xxx.ap-northeast-1.elb.amazonaws.com 80
POST /ajax/errors/test HTTP/1.1
HOST: shao-test-xxx.ap-northeast-1.elb.amazonaws.com
User-Agent: telnet
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
b=te
HTTP/1.1 408 Request Timeout
Date: Sat, 03 Dec 2016 12:58:45 GMT
Server: Apache
Content-Length: 324
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>408 Request Timeout</title>
</head><body>
<h1>Request Timeout</h1>
<p>Server timeout waiting for the HTTP request from the client.</p>
<hr>
<address>Apache Server at shao-test-xxx.ap-northeast-1.elb.amazonaws.com Port 80</address>
</body></html> |
f237645
to
11ddf50
Compare
hmm, I am not sure about this fix, but maybe we could fix this in the place where we calling read_post, because we already have SG(request_info).content_length. And I think the fix could be more clean than the current one... what do you think ? thanks |
Thank you @laruence , did you mean to check SG(request_info).content_length in |
Here is a related discussion in apache community. By Yann Ylavic 2016-10-28 22:57:17 UTC
|
I understand the problem, your current fix is not quite right, like at least you should not use a global flag, because this sapi could also be used in apache-worker mpm(ZTS). anyway, the flow is php_handler() calls read_post, maybe we could compare readed length and SG(request_info).content_length, then return 400 to apache, but I am not sure about the side-affect. need some time and more work to verify it. thanks |
Thanks for the tips, I did not consider the MPM case. |
I delete the global variable and use SG(request_info).content_length to detect the error. It is more reasonable to me now, what do you think about this fix @laruence ? Thank you. |
9ae9551
to
53c4c38
Compare
seems much better now, if there is no concerns show up in next few days, I will merge this, thanks |
@@ -656,6 +665,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, "attemp to read POST data error: %d", SG(sapi_headers).http_response_code); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in error message: attemp -> attempt? Though maybe something like "Error while attempting to read POST data: %d" might be better.
6fb5e94
to
884e2a0
Compare
hmm, /home/huixinchen/opensource/php-7.0/sapi/apache2handler/sapi_apache2.c: In function ‘php_apache_sapi_read_post’:
/home/huixinchen/opensource/php-7.0/sapi/apache2handler/sapi_apache2.c:212:4: warning: implicit declaration of function ‘ap_map_http_request_error’ [-Wimplicit-function-declaration]
SG(sapi_headers).http_response_code = ap_map_http_request_error(ret, HTTP_REQUEST_TIME_OUT);
^ ap_map_http_request_error is not defined. according to https://fossies.org/diffs/httpd/2.2.29_vs_2.2.31/include/http_protocol.h-diff.html , seems this function is added recently ? in that case, we should take care compatibility for old versions. |
Thank you for mention about the compatibility issue. @laruence I pushed a new commit for fixing it. |
hmm, maybe a better way to do this is: #if apache's version is newer than 2.2.31 or 2.4.16
#define php_ap_map_http_request_error ap_map_http_request_error
#else
static int php_ap_map_http_request_error() {
}
#endif then later you could use php_ap_map_http_request_error without any extra checks |
Thank you for figure out the code problem, does this look better now? @laruence |
This change has caused some interesting behaviour differences in Drupal 8 testing against PHP 7. We're now getting 200s and "Error while attempting to read POST data" in our Apache logs files when we post invalid JSON to a server. See https://www.drupal.org/node/2840974#comment-11852288 for more. Not sure why this change is causing that. |
So it is easy to write a test for the behaviour change. curl -H "Content-Type: application/json" -X PATCH --data "al" http://localhost/test.php Where test.php is:
PHP versions before this patch: After this patch:
|
If the method is POST everything still works as expected but PATCH is broken. |
It does not even have to be invalid JSON - that's what the test the discovered this was testing but even:
is broken. |
@alexpott I think we perhaps need to create a new ticket for this regression, and then just point to this PR. It's quite possible the PHP maintainers are not seeing new comments here, just like we don't see new comments on "closed" issues on drupal.org. |
I'm seeing them ... please do open a ticket, put a link here, and in any subsequent PR's that are made to resolve it. |
@nikic @krakjoe If you're going to revert this do I need to file a bug on https://bugs.php.net/report.php? I'm more than happy to if that helps - but don't want to create more noise than necessary. |
I'll be doing whatever @weltling does, one or both of us will provide update here. |
I've reverted this in dev for now and reopened https://bugs.php.net/61471. @axot please lets use another PR for the improved patch. Thanks. |
@weltling Thank you for reverting the commit. |
php_handler does not process request error well.
Should we fix this?
https://bugs.php.net/bug.php?id=61471