Given the following PHP 5.1.6 code being served through Apache 2.2.9:
<?php
header("HTTP/1.1 404 Not Found");
When I browse to this file (with any browser) I get a "connection reset" message. (Firefox says "The connection to the server was reset while the page was loading.", and Chrome says "The connection to staging.neopets.com was interrupted." It makes no difference whether there's any body after the header call.
httpd.conf has rewrite rules that force all requests to run through a front controller script. This is how it's worked for years. The front controller tries to route the request, and if it can't, it sets the response code to 404, shows some error copy, and exits. For whatever reason, today it decided to lose its mind and blow up whenever a
error.log shows nothing. access.log shows the requests being served as 404s:
192.168.0.2 - - [26/Jan/2012:12:03:11 -0800] "GET /text.php HTTP/1.1" 404 20 "-" "Mozilla/5.0 (X11; Linux i686; rv:8.0.1) Gecko/20100101 Firefox/8.0.1"
The Apache config has not been touched in months. All other header responses work properly (401, 403, 200, 302, etc.), everything else is totally normal, but for some reason if I have PHP make the call above, it resets the connection.
I even watched it with Wireshark and it sends back a whole bunch of RST,ACK packets after the request is sent.
Doing wget localhost/test.php (from the machine in question) works fine, but doing wget badhost/test.php (from another machine) shows a connection reset error as well. Maybe Apache is doing some kind of reverse IP lookup on remote requests for 404s and melting down?
EDIT: After further investigation, turns out it's some network problem where 404s between the hosting facility and our office are killed with a connection reset. So, closing because it's not something that anyone here can answer ;-) Thanks!
That header that you send from your PHP script is not what makes Apache display its 404 page. Apache displays a 404 page (and sends a 404 Header) when it can't find the requested file. Since this is not the case here (because test.php is found and executed), that 404 header has no sense. That is probably what got your browser(s) confused.
If you call this as part of some application error handling or something, what you should do instead is redirect the user to the application's custom "File not found" page.
Related
We have upgraded our hosting platform with latest tech stack which includes PHP updates from Version 7.0 to 7.3 and enabled SSL certification.
After the upgrade, one of our user authentication method has failed though, it was working till the hosting platform upgrade.
Here is copy of PHP code - codecheck.php,
<html>
<body>
<?php
$header = "Content-Type: application/json";
header($header);
$code = $_GET["code"];
$codelistFile = "./codelist.txt";
$codeList = file( $codelistFile, FILE_SKIP_EMPTY_LINES);
$codelistOutput = sprintf('%s%s', $code, "\r\n" );
file_put_contents( $codelistFile, $codelistOutput, FILE_APPEND);
?>
</body>
</html>
Here is result of codelist.txt before the platform upgrade (with PHP version 7.0)
65cafead50f6d205d66f90c74f1683344ca86c8cc60fc0370c278ecb880da5c8
6e85e436538335da64f6e9172bd4191686e591aa390cca69acb9346668a48bd5
Here is result of codelist.txt after the platform upgrade (with PHP version 7.3)
774cad9dd07761fe79db8baa9370a3dd84abca558c73c1f46b39e7c996a26d70?code=774cad9dd07761fe79db8baa9370a3dd84abca558c73c1f46b39e7c996a26d70
f10bb27fb82b0d539d3607012655012764c60794cc656aa6912eccc16d927a82?code=f10bb27fb82b0d539d3607012655012764c60794cc656aa6912eccc16d927a82
Here is value of code repeated along with 'code' text itself hence the value of 'code' does not match when it compared.
Here is what I can see in ssl_access log files, ssl_access.log-20190629:79.1.200.79 - - [29/Jun/2019:07:46:24 +0100] "GET /codelist.php?code=ae21250db8b20cac3b7016e6d36a63de5846d537f032ed841a3e5c9121202cf4?code=ae21250db8b20cac3b7016e6d36a63de5846d537f032ed841a3e5c9121202cf4 HTTP/1.1" 200 19 "-" "Registration"
From this log file, I can see all GET requests to server appending the data twice.
I would expect it would be something like,
example.com/?code=123456789
but not as
example.com/?code=123456789?code=123456789
I am very new to PHP and HTTPS stuff, please help to figure out the issue. Thank you.
Here is an update:
As suggested, the issue seems to be more with SSL re-writing,
Here is code from desktop app where the app will connect and check the code with the server,
C++:
CString RegistrationServer::Uri( CString page, CString code )
{
CString sServer;
sServer.Format("http://www.mywebsite,com/%s?code=%s", page, code);
//Here page=codecheck.php and code = 10;
return sServer;
}
Here is log when submitted through desktop app,
27.62.66.34 - - [30/Jun/2019:21:55:51 +0100] "GET /codecheck.php?code=10?code=10 HTTP/1.1" 200 - "-" "Hack-o-Matic ver 0.01"
I can simulate the same request through web browser as below,
https://www.mywebsite/codecheck.php?code=10
Here is log when submitted through web browser,
27.62.66.34 - - [30/Jun/2019:21:46:28 +0100] "GET /codecheck.php?code=10 HTTP/1.1" 200 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
You can see the difference in both the request is http vs https.
When the request is coming from desktop app, the code data is appended twice which uses http.
It appears that changing desktop app to have https will help fix the issue but that's something that we can't do anything with desktop app.
So we have to relay on fix from Server side but our hosting company doesn't seem to understand the problem exactly.
They keep analysing the issue since last 3 days and coming up some fixes like googleapi call fixes but that's not helping to fixing up our real issue.
I'm not sure if I'm missing some better phrases/terms to explain this issue to them better. Please let me know if there is better way to explain the issue to our hosting company.
If nothing working out, Can I ask them to remove SSL certification?
Another Update:
Here is response from our hosting company,
We have this referred to our engineers and they confirmed that this only happens when calling http and not https. You need to use https now since you have enabled SSL.
Latitude-E6540:~$ curl -I http://www.mywebsite.com/codecheck.php?code=10
HTTP/1.1 301 Moved Permanently
Server: nginx/1.15.8
Date: Mon, 01 Jul 2019 11:03:47 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.mywebsite.com/codecheck.php?code=10?code=10
Strict-Transport-Security: max-age=15768000
Our engineers made some tests and they were not able to replicate when they set to https.
Latitude-E6540:~$ curl -I https://www.mywebsite.com/codecheck.php?code=10
HTTP/1.1 200 OK
Server: nginx/1.15.8
Date: Mon, 01 Jul 2019 11:03:35 GMT
Content-Type: application/json
Connection: keep-alive
Strict-Transport-Security: max-age=15768000
Here is log from server,
213.171.217.184 - - [01/Jul/2019:12:03:35 +0100] "HEAD /usage7.php?code=10 HTTP/1.1" 200 - "-" "curl/7.58.0"
They confirmed that this looks to be something with your local software settings as this only seems to get in the case of "after submitting the requests through browser, HTTP GET data is not appended twice but when the same is submitted through their desktop software, the HTTP GET data is appended twice"
What I wanted to ask you is, from below curl output itself where I can see the code is appended twice when request is made with http, Does this having any clue to spot where the issue resides?
Location: https://www.mywebsite/codecheck.php?code=10?code=10
How to solve PHP upgrade errors:
Post-event, how to find, diagnose and fix errors apparently caused by PHP updates?
1) Check your scripts for PHP Errors.
2) Check changes to your php.ini file caused by updates.Depending on your system and upgrade method, the php.ini file may be adjusted or even a new default one. Read the Migration Notes to see if this may apply to you. You will need to review and explore what's changed. Also manually compare your reserved/backup php.ini with the current/new live one.
3) Read the PHP Migration notes for each version you have upgraded into and then out of(These are best done from oldest to newest).
4) Read the corresponding PHP Changelog(s) and search this text (it's loooong) for the functions you've found be failing in step (1).
For your specific instances; your code is of a very low quality (you are sending HTTP heders after you are sending HTML code) so the issue may well be caused by PHP upgrading an already existing error from E_WARNING to E_ERROR, or similar.
Low quality code is most easily fixed by turing on error_reporting(E_ALL); either in the scripts or in the php.ini and reading the resulting error logs.
Good Luck.
Update
Even with this SSL log, I can see the value for code twice and the same written to the file. I would expect it would be something like example.com/?code=123456789 but not as example.com/?code=123456789?code=123456789.
The sign you have two ? means you should be exploring the code that sets the code= value, please update your question with this information, how is code set?
Your issue may be with your HTTP Host routing, Apache, Nginx, etc., your HTTP Host is possibly double loading, first the HTTP_ page and then secondly redirecting on to the HTTPS page with the original query string appended, thus appending twice.
I think one or both of the above is where your problem lies.
Update 2:
Comment by Thi:
Here is what my hosting company responded, "as per our engineers the cause of the logs is de to the website making http (not https) calls to the google api for css and other things. They have advised that you need to ensure that any code that relates to http is switched to https." - There is below line in all of our html pages and have changed it to https but it didn't help <link href="fonts.googleapis.com/…" rel="stylesheet" type="text/css">
This relates to what I reference above about checking your server routing for HTTP and HTTPS protocols.
Solutons:
1) Update all your outgoing links to https:// (or simply //) so:
<link href="//fonts.googleapis.com/..." rel="stylesheet" type="text/css">
will always connect securely, if loaded securely.
2) Use Content Security Policy (CSP) Upgrade Insecure Requests flag to do just that; to force all http:// links within your website to be turned into https:// links by the client browser.
In your .htaccess, or equivilant file:
Content-Security-Policy: upgrade-insecure-requests;
However, insecure calls to 3rd party resources will NOT be the cause of your code block being appended to your URL twice.
I've built a dynamic website and modified the .htaccess file for static URLs and I need to create a 404 page for SEO.
header("HTTP/1.0 404 Not Found");
I'm using the above PHP header() function when there is no matching link in database, but when I check the server logs it seems like this does not work and gives HTTP 200 OK status code.
Here's the line from the server log:
[My IP] - - [12/Jun/2011:01:47:38 +0300] "GET /4k.html HTTP/1.1" 200 3284 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.91 Safari/534.30"
4k.html is the link which does not exist.
Am I missing something?
From what I understand, you are rewriting all files to a single PHP file so PHP can read it and do what it needs to do to serve a page. That means that Apache's handling of 404 pages is going to be, essentially, overridden. At this point it is up to your PHP file to serve a page or display a 404. As far as Apache knows, the request resulted in an HTTP code of 200, because it doesn't play any part after it triggers PHP to parse the script and give the output to the client that requested it.
In your PHP script, you will be doing checking to see if the page exists or not. If the page exists, show the page, else, give a 404 message. By putting header("HTTP/1.0 404 Not Found", true); in your PHP file at the point where you know it's a 404, it will send the 404 header to the client, and therefore it was done correctly. To verify it is being sent correctly, trigger a 404 (by putting in a bogus url) and view the request details in Chrome Developer tools, you should see under Response headers that you are being sent a 404, while your Apache logs display a 200.
There are some times when I'd like my site to trigger a 408-response (for when various pieces aren't responsive). (PHP 5.3.3 and Apache, both Windows and Linux machines)
I can use the following code and get the expected result in all browsers except Firefox:
<?php
// Access forbidden:
header('HTTP/1.1 408 Request Timeout',true,408);
echo 'hi';exit;
But Firefox just immediately sends the "The connection was reset" page, and Firebug shows it got the 408 message. Is this by design in Firefox, or is there some way around this?
The 408 response is the server telling the client that the client didn't send all the details for a request within the time that the server was willing to wait, and that the server has forcefully closed the connection.
So, yes, this is by design in Firefox.
Edit: Consider using the 503 Service Unavailable temporary error code instead, possibly with a Retry-After header. I've never tested to see if the Retry-After works.
So, in my .htaccess file I have this ErrorDocument lines:
ErrorDocument 500 http://www.example.com/500
Since my server runs multiple websites from the same core files, I just want to redirect all internal server errors to the same processing page. However, my problem is that it doesn't send any information about the page that cause the error, it redirects the page. I tried changing it to ErrorDocument 500 index.php?500 but that just causes a second internal server error when trying to locate the file. Any ideas on how I can successfully redirect it to my custom 500 error page and still acquire information about the page that caused the error in the first place?
In your ErrorDocument statement, you're giving a URL to a remote page. As a result, Apache sends the user a Location header, and the user goes off on their merry way.
Instead, change the URL to an absolute path to a local script that will handle the error:
ErrorDocument 500 /500.php
The script should be launched with a set of environment variables starting with REDIRECT_ that should contain the various paths and query strings involved in the error.
There is no way to both send the user elsewhere and also capture the information within ErrorDocument itself. On the other hand, your script can capture the information and then redirect the user, if you still want to handle it that way for some reason.
You could always look in the referrer field of the http request to determine on which URL the caller was before
Check your webserver's access log. There you will be able to see which request that is causing the 500 response code.
In Apache (using the default log format), a successful request (200 OK) could look like this:
127.0.0.1 - - [19/Jul/2010:18:25:54 +0200] "GET / HTTP/1.1" 200 663 "-" "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8pre) Gecko/20100718 Ubuntu/10.04 (lucid) Namoroka/3.6.8pre"
A request that results in a 500 could look like this:
127.0.0.1 - - [19/Jul/2010:18:24:37 +0200] "GET / HTTP/1.1" 500 631 "-" "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8pre) Gecko/20100718 Ubuntu/10.04 (lucid) Namoroka/3.6.8pre"
The response code is in the sixth column.
You can also check your PHP error log, which will contain all PHP errors assuming you've enabled error logging (you should).
Your apache server logs every Error occurs(Though it is configurable). You can able to open and manage this file using FileStream in your PHP website. See http://httpd.apache.org/docs/2.2/logs.html to see more about Apache log file. You can get a tutorial on .htaccess from http://www.freewebmasterhelp.com/tutorials/htaccess/.
To make your own processing, make a PHP file like error.php which will process your errors. You can redirect it using .htaccess file. After that if you want to go to a page you can do that by using header() method.
I'm having a problem implementing custom 404 error pages on my Windows/IIS/PHP webhost. Whenever I try to send the 404 status message in the header, no content is sent to the client and a blank page is displayed instead.
Here is a very simple script I'm using:
<?php
header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found');
var_dump(headers_list());
?>
On my dev machine the output (displayed in a browser) is
array(2) { [0]=> string(23) "X-Powered-By: PHP/5.2.6" [1]=> string(21) "Status: 404 Not Found" }
On my host there is no output. I can't seem to generate anything but a blank page regardless of what content is echoed by PHP, or included below as normal HTML, though PHP processing e.g. logging, database writes etc continue as normal.
Can anyone suggest what the problem might be or how to resolve it?
'blank page' smells like error_reporting(0) hiding the error messages you would get. Maybe there is some output before your headers and that raises an error. Check that.
If PHP is configured at your host to run through CGI, it may be impossible to generate 404 error pages in IIS (except by lying and returning 200 OK, which is a Bad Thing). Certainly I've been unable to persuade IIS 4-6.0 to allow my CGI 404 errors through to browsers.
You generally don't want PHP to run CGI anyway, there are other related problems as well as it being slow. On IIS, the PHP ISAPI extension should be preferred (though as I've not tried it I can't confirm it solves this specific problem).
What if you put text after the PHP tags?
Also, make sure your script isn't erroring out on your host, whether checking apache error logs, running php -l on your script or turning error_reporting on and display_errors on.
I have the same problem with PHP 5.2.6 on Linux. I find that the first 8109 bytes are not printed by the web server.
IE6 ignores custom error pages < 512 bytes in length. This could be an explanation for this problem, but probably you have tested in more than one browser anyway.
Check that your host allows you to change headers on the fly with PHP. My host doesn't allow me to set the 404 header through PHP, though other headers (301, content-type) are fine.
My advice is to not set the HTTP/1.1 404 header yourself and let the web server do it for you.
Traditionally, this is done through the Status header, which the web server should take and turn into an HTTP/1.0 or 1.1 404 Not Found header.
(Side Note: The Status header is not a real HTTP header and is used solely to communicate information from an app to the server itself.)