Detecting 413 (or other HTTP Status) in PHP - php

I Send Data to a webserver with POST or PUT method (server is FreeBSD, Apache httpd, php72).
I want to detect a 413 (too large) in my PHP script. But var_dump(http_response_code()); gives 200 even i uploaded data was too large (Apache httpd answers with it's 413 page, and my script gets executed as well).
var_dump($_SERVER); does also not show anything with 413.
How can i detect http status like 413 or any other in my script? and is it possible to let my script output the error-message, not apache?
my php-script looks like this
<?php
header('Content-Type: application/octet-stream');
echo ">---- output from php-script begins here\n";
if (http_response_code() != 200) { # <---- this does not work, always 200, how to detect http status code 413 from apache httpd?
echo ">---- not ok\n";
}
else {
echo ">---- ok\n";
}
?>
i use this command to upload a file
curl --head --silent --show-error --upload-file test-big-file.txt "my-domain.com/upload.php"
HTTP/1.1 413 Request Entity Too Large
Date: Thu, 09 Apr 2020 12:08:46 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>413 Request Entity Too Large</title>
</head><body>
<h1>Request Entity Too Large</h1>
The requested resource does not allow request data with PUT requests, or the amount of data provided in
the request exceeds the capacity limit.
</body></html>
>---- output from php-script begins here
>---- ok
it does not make much sense to me that apache is prepending some error-message to my php-script-output. either user should get an error message or the output of my script. but not both at the same time.
if i clould detect this 413 in php i could just output some meaningful message and exit the script.
SOLUTION
i found out that if i use https:// for uploading the file apache does not call my php-script if file was too big.
only if i use http:// apache does this strange thing showing the error-document AND executing the php-script. i have absolutly no clue why this is. however... because i want to use https anyways... problem for me is gone.
here is an example output to see the diffrence in http and https in my case (CustomErrorDocument is emtpy, so no error output besides the header is shown here, in the final version, there will be an error-document of course)
curl --head --silent --show-error --upload-file test-big-file.txt "https://my-domain.com/test.php"
HTTP/2 413
date: Thu, 09 Apr 2020 17:22:23 GMT
server: Apache
content-type: text/html; charset=UTF-8
curl --head --silent --show-error --upload-file test-big-file.txt "http://my-domain.com/test.php"
HTTP/1.1 413 Request Entity Too Large
Date: Thu, 09 Apr 2020 17:22:28 GMT
Server: Apache
Upgrade: h2,h2c
Connection: Upgrade, close
Content-Type: text/html; charset=UTF-8
--> here is the output of the script that should not be executed <--
the line "--> here is the output of the script that should not be executed <--" is missing in the https call... it's only present in http call. strange...
notice: use of https gets an HTTP/2 response instead of HTTP/1.1
however, must be a misconfiguration from my web-hoster or a bug in HTTP/1.1 processing in apache. so problem solved by forcing everything to HTTPS
and usage of ErrorDocument in .htacces to show own document on error as suggested by #ÁlvaroGonzález fixed it for me (users trying to use http will get an 301 Moved Permanently error with correct https-link). works for me.
thanks

Related

ESP01-Apache server send data with Post to .php file

So basically I am trying to send data to a textfile in raspberrypi(apache server) from my ESP01 using AT-Commands.
I am trying to use POST method of apache for same.
Here is my PHP code:
`<?php
$tempF=$_POST["temp"];
$file='testfile.text';
$myfile=($file,"w+");
fwrite($myfile,$tempF);
fclose($myfile);
?>`
Here is the data I send through AT Command (AT+CIPSEND)
`POST /TEMP/post.php HTTP/1.1\r\nHost: 192.168.0.138:80\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length:9 \r\n\r\ntemp=1234`
So when I send this AT command, I assume that php file should be executed and data from 'temp' variable should be written to the text file. However there is no such output visible nor any errors displayed.
Here is simple map of how paths are placed
root folder:/var/www/html
inside it -> TEMP(folder), index.html
inside TEMP -> post.php, testfile.txt
I have already tried following :
Replace the $tempF variable with text and execute PHP on raspberrypi. So I conclude that there is no issue in php code since it worked great.
Enabled php mod and simple php index file works too.
3)Tried changing all possible pathways.
4)Give complete permissions to all files to read, write and execute in root folder. i.e index.html, post.php and testfile.txt
Screenshot of my at commands
P.S.
I am new to PHP and POST method of HTTP/1.1
Thanks☻
EDIT 1: As from Juraj's comment I realised that when you send \r\n through serial monitor it actually sends \n and so I tried the conventional method while entering Post Command as follows:
POST /TEMP/post.php HTTP/1.1
Host: 192.168.0.138:80
Content-Type: application/x-www-form-urlencoded
Content-Length:9
temp=1234
And I recieved following Error:
+IPD,187:HTTP/1.0 500 Internal Server Error
Date: Fri, 06 Aug 2021 13:06:57 GMT
Server: Apache/2.4.38 (Raspbian)
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8
Update:
While searching for same, I found reqbin.com which helps to test POST/GET methods too and I still got same error 500.
Note:My timeout currently is 120000ms and all files are given full permissions.

`PUT` error in curl while uploading the xml file on http link

I want to upload a single .xml file on the http link.
For that now I am using curl to upload .xml file.
below is the curl command for uploading the file.
curl -i -X PUT -H "Content-Type: application/xml; charset=utf-8" -d #"/Desktop/upload_file.xml" http://website.name/
when I do this then there is error as below:
`HTTP/1.1 405 Method Not Allowed
Date: Sat, 25 Jul 2015 04:40:00 GMT
Server: Apache
Allow: GET,HEAD,POST,OPTIONS
Content-Length: 240
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method PUT is not allowed for the URL index.html.</p>
</body></html>`
So what is the main error/problem here? What does it mean requested method PUT is not allowed for the URL?
Is it error with website link or server configuration? or error with curl command which I passed?
Please give any solution or correction for it.
In simple word How can I upload a single .xml file on the website (http) in LINUX by use of C language?
Thank you in advance.
Regards
Jaymin D
This means Put method is not enabled on server.many server providers does not allow many methods by default for security purpose.
I hope this questions will give you your answer.
https://serverfault.com/questions/438183/how-to-enable-all-http-methods-in-an-apache-http-server
How to enable and use HTTP PUT and DELETE with Apache2 and PHP?

Request timeout with 200 and refresh header

I have a simple php script running on Ubuntu 14, Apache 2.4.7 and PHP 5.5.9. Every once and a while the request seems to stall, and after about 40 secs (normally < 100ms), it responds with an empty page, 200 OK and a Refresh header to the same URL. I think it's happening more often, if there hasn't been a recent request to the script for a while.
Response:
HTTP/1.1 200 OK
Content-Type: text/html
Pragma: no-cache
Refresh: 1; URL=http://xxx.xxx.xxx.xxx/script.php?t=1407272586793
Connection: Close
Script content:
<?php
//# Provide server time
header('Access-Control-Allow-Origin: *');
echo '{"time":"'. gmdate("Y-m-d H:i:s") .' +0000"}';
There doesn't seem to be a record of the request in either the Apache access or error logs.
I'm not sure how to find at what point this is stalling. Has anyone experienced this before, or have any suggestion on how I might debug this further?

cURL default GET request isn't recognized by PHP

I'm trying to create a simple Web service that has to return various HTTP codes depending on some conditions, mainly the existence of files related to the specific resources requested via URI. However, i'm stuck on a really strange behaviour i keep getting when I try to generate a 404 header via PHP.
The first snippet, that works, is as follows:
$isNotFound = TRUE;
if ($isNotFound) header('HTTP/1.1 404 Not Found');
Using a simple command-line cURL to request the URI behind which this script runs, I get:
$ curl -LI http://www.example.com/
HTTP/1.1 404 Not Found
Date: Wed, 18 Sep 2013 20:57.25 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Vary: Accept-Encoding
Connection: clse
Content-Type: text/html
Now, the second take is like this:
$isNotFound = FALSE;
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$isNotFound = TRUE;
}
if ($isNotFound === TRUE) {
header('HTTP/1.1 404 Not Found');
}
Running cURL again, this time I get this:
$ curl -LI http://www.example.com/
HTTP/1.1 200 OK
Date: ...
The header is the same as the former, except for the code. To check the obvious, I also printed the value of $isNotFound just before the last if, and it was indeed evaluated to TRUE, so the header call with the 404 code should be executed. I also added an exit() inside the last if, and another header() at the end of the script, giving other codes in response (like 302), and the result is always that the header inside the if is ignored.
I managed to make the second script work by explicitly specifying the request method as GET in the cURL call:
$ curl -X GET -LI http://www.example.com/
HTTP/1.1 404 Not Found
Date: ...
I also had the doubt that cURL wasn't using GET as the default method, but printing the $_SERVER array showed that the request method was indeed GET.
So, what is the reason of this strange behaviour? Is cURL's fault when using the implicit GET method, or is something happening inside PHP? Or maybe i'm so tired that i'm missing something trivial?
Thank you guys, and sorry for the long post.
Next time read the manual:
-I, --head
(HTTP/FTP/FILE) Fetch the HTTP-header only! HTTP-servers feature the
command HEAD which this uses to get nothing but the header of a
document. When used on an FTP or FILE file, curl displays the
file size and last modification time only.
(or your webserver log files, or your TCP stream)

Test if X-Sendfile header is working

I am looking for a way to confirm if X-Sendfile is properly handling requests handed back to the webserver by a script (PHP). Images are being served correctly but I thought I would see the header in curl requests.
$ curl -I http://blog2.stageserver.net/wp-includes/ms-files.php?file=/2011/05/amos-lee-feature.jpg
HTTP/1.1 200 OK
Date: Wed, 04 Jan 2012 17:19:45 GMT
Server: Cherokee/1.2.100 (Arch Linux)
ETag: "4dd2e306=9da0"
Last-Modified: Tue, 17 May 2011 21:05:10 GMT
Content-Type: image/jpeg
Content-Length: 40352
X-Powered-By: PHP/5.3.8
Content-Disposition: inline; filename="amos-lee-feature.jpg"
Configuration
Cherokee 1.2.100 with PHP-FPM 5.3.8 in FastCGI:
cherokee.conf: vserver!20!rule!500!handler!xsendfile = 1
(Set by vServer > Behavior > Extensions php > Handler: Allow X-Sendfile [check Enabled])
Wordpress Network / WPMU 3.3.1:
define('WPMU_SENDFILE',true); is set in the wp-config.php the following just before wp-settings.php is included. This will trigger the following code to be executed in WP's wp-includes/ms-files.php:50 serves up files for a particular blog:
header( 'X-Sendfile: ' . $file );
exit;
I have confirmed that the above snippet is executing by adding an additional header for disposition right before the exit(); call. That Content-Disposition is present with curl results above and not originally in the ms-files.php code. The code that was added is:
header('Content-Disposition: inline; filename="'.basename($file).'"');
Research
I have:
Rebooted php-fpm / cherokee daemons after making configuration changes.
Tried several tricks in the comments over at php.net/readfile and replaced the simple header in ms-files.php with more complete code from examples.
php.net/manual/en/function.readfile.php
www.jasny.net/articles/how-i-php-x-sendfile/
*codeutopia.net/blog/2009/03/06/sending-files-better-apache-mod_xsendfile-and-php/*
Confirmed [cherokee support][5] and tested [with and without][6] compression even though I don't think it would apply since my images are serving correctly. I also found a suspiciously similar problem from a lighttpd post.
*cherokee-project.com/doc/other_goodies.html*
code.google.com/p/cherokee/issues/detail?id=1228
webdevrefinery.com/forums/topic/4761-x-sendfile/
Found a blurb here on SO that may indicate the header gets stripped
stackoverflow.com/questions/7296642/django-understanding-x-sendfile
Tested that the headers above are consistent from curl, wget, Firefox, Chrome, and web-sniffer.net.
Found out that I can't post more than 2 links yet due to lack of reputation.
Questions
Will X-Sendfile be present in the headers when it is working correctly or is it stripped out?
Can the access logs be used to determine if X-Sendfile is working?
I am looking for general troubleshooting tips or information here, not necessarily specific to PHP / Cherokee.
Update
I have found a suitable way to confirm X-Sendfile or X-Accel-Redirect in a test or sandbox environment: Disable X-Sendfile and check the headers.
With Allow X-Sendfile disabled in Cherokee:
$ curl -I http://blog2.stageserver.net/wp-includes/ms-files.php?file=/2011/05/amos-lee-feature.jpg
HTTP/1.1 200 OK
Date: Fri, 06 Jan 2012 15:34:49 GMT
Server: Cherokee/1.2.101 (Ubuntu)
X-Powered-By: PHP/5.3.6-13ubuntu3.3
Content-Type: image/jpeg
X-Sendfile: /srv/http/wordpress/wp-content/blogs.dir/2/files/2011/05/amos-lee-feature.jpg
Content-Length: 40352
The image will not load in browsers but you can see that the header is present. After re-enabling Allow X-Sendfile the image loads and you can be confident that X-Sendfile is working.
According to the source on github X-Sendfile headers will be stripped.
If I'm skimming the file correctly, it's only logging success if it's been compiled in debug mode.
You could check memory usage of sending large files with and without xsendfile.
They are being stripped, simply because having them present will prevent one of the reasons to use it, namely having the file served without the recepient knowing the location of the file being served.

Categories