Why/when does one has to use CRLF's at the end of header in PHP?
Here is one example (it's not necessarily correct):
header("method: POST\r\n");
header('Host: '.get_option('transact_url')."\r\n");
header('Content-type: application/x-www-form-urlencoded');
header('Content-length: '.strlen($transaction)."\r\n");
header($transaction."\r\n\r\n");
header("Connection: close\r\n\r\n");
header("Location: ".$key_client_url."\r\n");
You should never do manual line-breaks inside of header(). The current implementation removes line-breaks so you're safe, but this could change in future (although there's no reason why it should be changed).
If it's PHP, this code is nonsense.
header() function is used to send answer headers, while some of these headers are request ones.
You can see this code because one who wrote it has no clue.
Got my log-in's all mixed, so I'm posting, although this a comment for halfdan. Feel free to correct it, if someone can.
link
I saw that in the link and nobody mentioned about what you've just told me, so I thought it has something to do with Linux line-endings. Granted, it was the only time I saw "\r\n" in header().
Halfdan is correct.
Here is the explanation.
The request line and headers must all end with CRLF (that is, a carriage return followed by a line feed). The empty line must consist of only and no other whitespace.
Request = Request-Line ; Section 5.1
*(( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 4.3
source: w3c.org - Hypertext Transfer Protocol -- HTTP/1.1
There was a way to add \r\n to header in php 4, which was vulnerability that could be exploited, using CRLF injection attacks see PHP HTTP Header Multiple Vulnerabilities.
Related
In order to complete the handshaking for Websockets in ssl, the socket must be read in blocking mode. Using stream sockets, communication is done from the php backend with the (javascript) client using fwrite() and fgets(). In blocking mode, fgets() will wait until the next line comes in, and grab one line. Once the socket connection is made, the client sends the PHP some headers so that the handshake can be completed. The problem is, I can't think of a way to find where the end of the headers are, since the order depends on the browser being used.
I used this work around for chrome (since the sec-websocket-extensions line is the last header sent)
stream_set_blocking($lsSocketNew, true);
$lcHeader = "";
while($lcLine = fgets($lsSocketNew)){
$lcHeader .= $lcLine;
if(strstr($lcLine, "Sec-WebSocket-Extensions")){
break;
}
}
but this doesn't work in other browsers like firefox, where this header is the first one sent. :P
(I think fread() is supposed to do what I am looking for -- in blocking mode it is supposed to get "everything" on the socket when it comes in... but when I tried fread instead, it was returning a blank string. :P stream_get_contents() was the same )
Although I can't give you a PHP advice, there is a couple of things that you may want to consider:
I. What kind of "everything" are you looking for? There are no message borders in TCP so "everything in the stream" is equivalent to "random ordered amount of data". Unfortunately, you aren't going to magically read all HTTP headers and stop there.
II. Given point I, you have to find something that separates HTTP headers from an HTTP body. This is actually rather simple, because the headers end with a blank line. So, just read the data until you receive CRLF CRLF*. In PHP you will most probably see CRLF as \n, though this can depend on the OS.
III. If you're implementing websockets, using fgets is questionable, because the rest of the protocol (after HTTP handshake) is binary. You may want to use dedicated PHP's sockets module and socket_recv instead of fread. I can't say how these two functions differ, but socket_* functions are just a wrapper around BSD sockets which are implemented in a wide variety of languages. Since they're mostly language agnostic, you will find more support and tutorials in the internet.
* Per the HTTP standard:
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
Function session_start used in PHP CLI print the next warning: session_start(): Cannot send session cookie - headers already sent by (output started at /home/robi/p/test.php:1) in /home/robi/p/test.php on line 2 why?
I want to log all the client entries in a variable and check this out to see if i get forgery from a specific remote address by comparing the time user last entry and current entry time! Am I doing it wrong?
here is my code:
<?php
session_start();
$client_entry = time();
$_SESSION["entries"][] = $client_entry;
$entries = $_SESSION["entries"];
$check_out = array_filter(
$entries,
function($value) use($client_entry) {
return ($value >= ($client_entry + (1 * 0.6)));
}
);
Your problem is, apart from that it makes no sense to use sessions in CLI, that output has already started prior to session_start();.
As I see in your code, you code begins directly with session_start();, I believe you have some characters before <?php. Make sure <?php is on the very first line of your file (so also no empty lines above it), and that there is nothing (such as a white space) in front of it.
This should fix this problem you are having.
The error comes from the very first line, so you should try to convert your file to utf-8 without BOM.
Quoting Wikipedia's article:
The byte order mark (BOM) is a Unicode character used to signal the endianness (byte order) of a text file or stream.
That character is sent to the output stream, so you can't redefine headers (session_start sets up a cookie in the headers).
when I am using include() with my wordpress plugin which says an error as follows.
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /var/www/wordpress3/wp-content/plugins/new/listAllItems.php:10) in /var/www/wordpress3/wp-content/themes/thesis_16/lib/functions/document.php on line 3
listallitems.php's 10 th line says
`
include_once("../../../wp-config.php");
include_once("../../../wp-load.php");
....`
How can I avoid this error.
As explained before, this is due to some text which was already sent to the browser before your session_start() statement. Check if you haven't includes spaces/characters in your script or in one of the scripts your are including.
THis could also be an encoding problem, i.e. your file is encoded in UTF-8 with BOM but your webserver is configured in another charset, so the BOM is treated as extra characters (but this problem has indeed be answered a lot of times).
This is just a quick-fix, not the right solution.
Put an "#" symbol before the command, like this...
#session_start();
That will suppress any warnings or errors. You can do that with any PHP command. But it's not a good idea in general, because you are only putting a band-aid on the issue, and not resolving the root cause, which in your case is that the session_start() is getting called after something has been output to the buffer.
I have just added in my script :
if(!session_start()){
session_start();
}
All warnings gone.
Usually this error appears when there is output before session start function. sometimes even blank space or small character, file encoding problems.
I'm trying to debug a plugin-bloated Wordpress installation; so I've added a very simple homebrew logger that records all the callbacks, which are basically listed in a single, ultimately 250+ row multidimensional array in Wordpress (I can't use print_r() because I need to catch them right before they are called).
My logger line is $logger->log("\t" . $callback . "\n");
The logger produces a dandy text file in normal situations, but at two points during this particular task it is adding something which causes my log file to no longer be encoded properly. Gedit (I'm on Ubuntu) won't open the file, claiming to not understand the encoding. In vim, the culprit corrupt callback (which I could not find in the debugger, looking at the array) is about in the middle and printed as ^#lambda_546 and at the end of file there's this cute guy ^M. The ^M and ^# are blue in my vim, which has no color theme set for .txt files. I don't know what it means.
I tried adding an is_string($callback) condition, but I get the same results.
Any ideas?
^# is a NUL character (\0) and ^M is a CR (\r). No idea why they're being generated though. You'd have to muck through the source and database to find out. geany should be able to open the file easily enough though.
Seems these cute guys are a result of your callback formatting for windows.
Mystery over. One of the callbacks was an anonymous function. Investigating the PHP create_function documentation, I saw that a commenter had noted that the created function has a name like so: chr(0) . lambda_n. Thanks PHP.
As for the \r. Well, that is more embarrassing. My logger reused some older code that I previously written which did end lines in \r\n.
Im working with PHP 4.3.11 and when I execute a header always responds with an error like this
Warning: Cannot modify header information - headers already sent by (output started at d:\folder\file.php:1) in d:\folder\file.php on line 2
Warning: Cannot modify header information - headers already sent by (output started at d:\folder\file.php:1) in d:\folder\file.php on line 3
Current PHP version: 4.3.11
the code I used to generate this error was
<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
echo 'Current PHP version: ' . phpversion();
// prints e.g. '2.0' or nothing if the extension isn't enabled
echo phpversion('tidy');
?>
It has no spaces nor newlines before or after the php tags, and the same code in a 5.x version returns just the php version as expected.
Any clue?
Thanks in advance
Edit:
Solved!: I've opened the file with western european encoding and deleted the BOM and it worked. Thanks all for your help!
Do you have a UTF BOM at the start of the file?
Make sure that there are no empty lines and invisible characters (such as the UTF BOM) before the PHP block so that <?php is really the first in the file.
if your file does not contain anything else but php code it is recommended to skip the php closing tag to avoid empty spaces issue at the end of the file
The error you're getting means that your entire script (other files included) are sending some output before the header() function is called.
You should revise all your files and see if any of them is outputting something (with echo() or print()), or if you missed some empty spaces after the last closing tag ?>
it's unlikely, but there's the possibility to define auto_prepend_file in the php.ini (probably .htaccess too).
http://at2.php.net/manual/en/ini.core.php - this acts like a require() at the beginning of every script. you can check this by looking at the phpinfo(); output.
but i too think the problem is the utf-8 BOM.