How to remove header content-type in apache ?
The following code does not work
header_remove('content-type');
Try
<?php
header('Content-Type:');
This completely removed the Content-Type header from the response. Like you, using header_remove() didn't do a thing and Hereblur's answer left me with Content-Type: none in the response.
It depends on what php.ini directives you have, and what PHP you use (CLI, CGI, ...).
This answer is based on PHP 5.4, running in CGI.
Note in php.ini:
default_mimetype = text/html
That's the default value, that PHP sends as:
Content-Type: text/html
If you want to get rid of it, you have to remove the default value by creating the header again, then you can remove the header:
<?php
header('Content-Type: text/html');
header_remove('Content-Type');
Try this.
header("content-type: none");
I don't know why, but it's worked for me.
I cannot find any reference mentioned about this. but it's simply removed the content-type from header for me. It' may be apache's bug or PHP's bug. So try it and use it with careful.
Related
I use "ob_gzhandler" function for compressing contents. this is my codes:
<?php
ob_start("ob_gzhandler");
?>
<html>
<body>
<p>This should be a compressed page.</p>
</body>
</html>
don't throw any errors, but compressing operation not working!
in "inspect element" isn't "content-encoding : gzip" phrase!
my system information :
Apache/2.4.23 (Win64) PHP/5.6.25 - Port defined for Apache: 80
Php documentation says, that ob_gzhandler requires zlibextension to be installed, so make sure it is true:
if (extension_loaded('zlib')){
echo "zlib installed";
}
If it's installed, you can use ob_gzhandler and content will be compressed. The problem is you don't see HTTP header Content-Encoding: gzip in response headers. This header is not set by your web server, but you can set it from php, by means of header() function:
header('Content-Encoding: gzip');
So, combining these two step you have a solution:
if (extension_loaded('zlib') && !ini_get('zlib.output_compression')){
header('Content-Encoding: gzip');
ob_start('ob_gzhandler');
}
I also check .iniconfiguration. If zlib.output_compression is On, all output will be compressed, so ob_gzhandler is redundant.
This code is valid, but it's not what php sould be used for. Compressing output and setting headers is web server responsibility. Please, read relevant answer, about configuring .htaccess file, so Apache will do a compression and set correct response headers for you.
Gotcha 1
ob_start(ob_gzhandler) needs zero preoutput.
(Assert <? is the very first byte of your file.)
Gotcha 2
ob_start(ob_gzhandler) needs zlib.output_compression_level be between -1 and 9.
First ensure that PHP is correctly configured (no restart of any kind required); verified with PHP 7.3.10:
php.ini
zlib.output_compression = On
zlib.output_compression_level = 9
Secondly there are some weird bits. Don't try to manually set the Content-Encoding header, for some reason that seems to break pages. This code must start before any output (including spaces/tabs) is sent to the client:
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && stristr($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip'))
{
ob_start('ob_gzhandler');
//header('Content-Encoding: gzip');
}
Lastly you must ensure to properly handle "closing" the compression - if it is active:
if (ob_get_level() > 0) {ob_end_flush();}
I tried all of the above and had to change the last ending bit, hopefully this will save someone's sanity.
In the Apache config, one can set the following directive to cause the httpd to always send a UTF-8 character encoding header for text/html and text/plain MIME types:
AddDefaultCharset utf-8
I would like to be able to detect in my PHP scripts whether or not this header is being sent, so that I can send the same header using the header() function if it hasn't been sent.
How can I detect this?
There's apache_response_headers(), though it'll only report on headers that are already "in play". If your charset header is added after the fact, you'd never see it.
Information provided by deceze in the comments on the initial question negated a need for an answer. However, for the sake of completeness, I would say that it appears that there isn't an obvious way to detect if headers have been sent by Apache from within PHP... but, given the above information, I can't think of a reason why you'd need to.
When I try to upload files using HTTP post with header Content-Type: multipart/form-data; boundary=-----NPRequestBoundary----- everything works as expected but trying to use Content-Type: multipart/form-data; boundary=-----NPRequestBoundary-----; charset=UTF-8 cause completely blank $_FILES array.
Is it a problem with PHP or web server? As I know this form of Content-Type is valid.
Because the Content-Type is multipart/form-data, this means it is built up from parts, and every part can have its own Content-Type. The charset parameter is only used with text/plain content-type. So it is meanless with a multipart/form-data content-type.
Bug was fixed in SVN rev. #316373 (5.3.9 release covers it).
I've found dirty workaround for this problem. For me it's ofc temporary bcs it doesn't work under litespeed (I used reverse proxy to apache to avoid this problem).
<Location "/upload.php">
RequestHeader set Content-Type "multipart/form-data; boundary=-----NPRequestBoundary-----"
</Location>
It will force webserver to replace content-type header. For now I'm sure - this is a PHP bug (someone assumed that charset will occur before boundary=)
I have some issues with a PHP file that is not working properly. The Content-type does not get recieved by any browser at all. Firebug interprets the file as text/html instead of css. Here's the file :
<?php
header('Content-Type: text/css; charset=UTF-8');
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'On');
/* CSS goes on from here */
I tested to put a row with echo 'TEST'; before the header line, and was expecting to see the classic "headers already sent" error, but nothing appears!
Normal .css-files are working like a charm however.
What can I do to sort this out?
UPDATE:
Did change default_mimetype = "text/html" to default_mimetype = "text/css" in php.ini and all pages got immediately interpreted as css, so there's must be a way to just send css headers for this file :)
The full file from demand of John:
<?php
header('Content-Type: text/css; charset=UTF-8');
echo 'body {background-color: #000000; }';
?>
UPDATE #2:
Adding ini_set('default_mimetype', 'text/css'); to the PHP file fixes this file, but it doesn't solve the issue that causes this fault...
UPDATE #3:
Tested adding AddType text/css .css to both .htaccess and Apache config. Still no luck. Also tested to send headers separated from charset: header('Content-Type: text/css'); - Still no luck...
UPDATE #4:
Have reinstalled Apache+PHP at the server to see if the problem goes away, but no. Same old, same old...
Check your php.ini file for the output_buffering setting. If it's not set to "off" than PHP is automatically doing output buffering for you. Set that to off and echo something before the header command, and you should see the "classic error".
You shouldn't use the closing ?>. I know this is a controversial suggestion, but too many times people add a return and/or space after it, which gets output to the browser (before the header). There are very few cases where it not using it would cause a problem.
Make sure your file editor doesn't save a BOM in your PHP file.
Try to move error_reporting / ini_set to make them the firsts PHP statements (before header() call). This way you will see all errors (if any). Don't forget to put that OFF in production!
Silly remark, but make sure this file is interpreted as PHP (extension is .php or if not an .htaccess tell the server to interpret as PHP).
Everything else is fine with your code. If it still doesn't work, check your server logs. Maybe something else crashes the execution of this PHP file (invalid MIME or else)...
the reason is because the header function works only if it is the first one to be called!
If you put an echo before, the content type automatically becomes text/html
try to print a CSS code after the header to test if it actually works.
Read this page for more infos
EDIT: did you change your post ? :-)
This is usually caused by a fatal error (ie, syntax error) that causes the script to abort before any of the code is execute (before display_errors can be set through ini_set() at runtime). Try changing display_errors in the php config file (php.ini).
Maybe the function header() is disabled in your configuration?
Test:
print ini_get('disable_functions');
It may be worth checking with curl to see what headers are actually being sent.
Try this from a command line and check for the "text/css":
curl -I http://example.com
Depending on the browser's request headers, PHP could also be sending the output gzipped using output buffering. In the PHP file, try this to check for ob_gzhandler.
print_r(ob_list_handlers());
If it's enabled, check in for zlib.output_compression in your php.ini or Apache configuration.
I found the full file is indented.
<?php
header('Content-Type: text/css; charset=UTF-8');
echo 'body {background-color: #000000; }';
?>
Because the indentation on line 1 outputted 4 spaces, therefore, the header will not work.
This sounds like your webserver is interpreting the script as a normal file. Does it have a .php extension and do other .php files work as expected?
Looks perfectly ok and the line with the echo should definitely generate a warning. Could it be that you're editing the wrong file?
You can try Content-Style-Type: text/css
See the below from the here
<META http-equiv="Content-Style-Type" content="text/css">
The default style sheet language may also be set with
HTTP headers. The above META
declaration is equivalent to the HTTP
header:
Content-Style-Type: text/css
Edit:
At the link , it's mentionned to add AddType text/css .css in the apache config file.
Maybe you can give it a try
Edit2
Look up for 'css' at this link. Someone had the same problem as you. Try sending the header without the charset
I recently had a hair-threatening
problem with Firefox and XHTML 1.0
transitional.
It worked fine with other browsers,
and also with HTML 4.1.
To cut a long story short,
PHP-generated JS and CSS files were
still being reported by the headers as
text/html, while in the HTML they were
text/css and application/javascript;
Firefox having been told the page was
XHTML 1.0 became anal-retentive and
refused to style the page. (I think
the JS still worked but I fixed it
anyway.)
Solution:
header('Content-type: text/css'); and
header('Content-type:
application/javascript');
Edit 3
There was a post about some forms not submitting any data because of an utility called AVG Linkscanner. Since you have reinstalled Apache + php and I assume you didn't reinstall the OS, so you can maybe investigate on this/try by turning some utilities/plugs-ins off.
Wild guess : open your file with something which would display any BOM. If you see some strange characters before <?php you have your problem. Check your current editor options to save UTF-8 file and make it save them without BOM.
Maybe there are issues with caching.
Try this:
header('Content-type: text/css');
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
echo 'body {background-color: #000000; }';
Works for me on an out of the box XAMPP installation and firefox - firebug reports correct content type.
output_buffering = Off in php.ini was the reason for me why it keeps sending Content-Type = text/html. Setting it to 1 solves it.
In my case, I struggled for hours with my code header('text/javascript');, wondering why the response MIME type wasn't being sent. The correct PHP code is header('Content-type: text/javascript');. There is no proper error detection for this programming error in PHP, Apache, the browsers, or the Web Developer Tools.
I know in PHP, it sends the X-Powered-By header to have the PHP version.
I also know by appending some checksums, you can get access to PHP's credits, and some random images (more info here).
I also know in php.ini you can turn expose_php = off.
But here is something I have done on a few sites, and that is use
header('X-Powered-By: Alex');
When I view the headers, I can see that it is now 'Alex' instead of the PHP version. My question is, will this send the previous PHP header first (before it reaches my header(), and is it detectable by any sniffer program? Or are headers 'collected' by PHP, before being sent back to the browser?
By the way, this is not for security by obscurity, just curious how headers work in PHP.
You can set expose_php = Off in your php.ini if you don't want it to send X-Powered-By header.
PHP first compiles everything (including which headers have which values ) and then start the output, not vice-versa.
PHP is also detectable with its own easter eggs, you can read about this topic here : PHP Easter Eggs
See Apache Tips & Tricks: Hide PHP version (X-Powered-By)
Ups… As we can see PHP adds its own
banner:
X-Powered-By: PHP/5.1.2-1+b1…
Let’s see how we can disable it. In
order to prevent PHP from exposing the
fact that it is installed on the
server, by adding its signature to the
web server header we need to locate in
php.ini the variable expose_php and turn it off.
By default expose_php is set to On.
In your php.ini (based on your Linux
distribution this can be found in
various places, like /etc/php.ini,
/etc/php5/apache2/php.ini, etc.)
locate the line containing expose_php
On and set it to Off:
expose_php = Off
After making this change PHP will no
longer add it’s signature to the web
server header. Doing this, will
not make your server more secure… it will just prevent remote hosts to
easily see that you have PHP installed
on the system and what version you are
running.
In PHP, headers aren't sent until PHP encounters its first output statement.
This includes anything before the first <?php.
This is also why setcookie sends throws a warning if you try to use it after something has been output:
Warning: Cannot modify header
information - headers already sent by
(output started at
/path/to/php/file.php:100) in
/path/to/php/file.php on line 150
Note that none of this applies if output buffering is in use, as the output will not be sent until the appropriate output buffering command is run.
To get rid of the X-Powered-By header without having access to php.ini, simply add an empty header.
<?php header('X-Powered-By:'); ?>
This overwrites the default X-Powered-By header with an empty value an though most clients and applications act like this header was not sent at all.
As noticed before, this must be inserted into the code before any output is sent.
And to answer your question:
Only your X-Powered-By header will be sent because it gets replaced by your header with the same name. So it can't be detected by a 'sniffer'.
Headers are "collected" by PHP before being sent back to the browser, so that you can override things like the status header. The way to test it is go to a command prompt, and type:
telnet www.yoursite.com 80
GET /index.php HTTP/1.1
[ENTER]
[ENTER]
And you'll see the headers that are sent in the response (replace /index.php with the URL of your PHP page after the domain.)
To hide X-Powered-By: PHP/7.x.x , if you are using Share Hosting then add the following code in .htaccess file
Header always unset X-Powered-By
Header unset X-Powered-By
Then reload the browser or clear the cache using the LiteSpeed Cache plugin: https://en.wordpress.org/plugins/litespeed-cache/
My question is, will this send the previous PHP header first (before it reaches my header(), and is it detectable by any sniffer program? Or are headers 'collected' by PHP, before being sent back to the browser?
No, it does not send the previous PHP header first. Headers are either sent or not sent (in complete, as one batch) in PHP. By default your headerDocs call replaces a previous header with the same name (unless you specify something different with the second parameter).
Note: If PHP would not collect the headers, it would not be able to replace one.
As it does not sent it earlier, it is not detectable with a sniffer program.
So yes, headers are collected by PHP and are send the moment "the real" output starts (HTTP response body).
See as well headers_sentDocs.
PHP has a built-in function to remove headers: header_remove().
To remove the X-Powered-By header, you can use:
<?php
header_remove(
name: 'X-Powered-By'
);
As you can see, you only have to pass the header name as a string as parameter, and you are done.
Note that name parameter is parsed not case-sensitive, so you are fine calling it with x-powered-by as well.
Since PHP 8.0.0 when calling the function without the name parameter, all previously set headers will be unset.