Skip to content
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

Headers functions do nothing in CLI SAPI #12304

Open
joanhey opened this issue Sep 26, 2023 · 4 comments
Open

Headers functions do nothing in CLI SAPI #12304

joanhey opened this issue Sep 26, 2023 · 4 comments

Comments

@joanhey
Copy link
Contributor

joanhey commented Sep 26, 2023

Description

It seems an stupid issue, but please read.
Related to #12303
The following code:

<?php
header('Custom: xxx');
print_r(headers_list());`

Resulted in this output:

Array
(
)

But I expected this output instead:

Array
(
    [0] => Custon: xxx
)

We know that the CLI SAPI don't send headers, and for that it's OK that the sapi_cli_send_headers() do nothing.
https://github.com/php/php-src/blob/master/sapi/cli/php_cli.c#L395-L405

But all the other header(), header_remove(), headers_list() that depend from sapi_cli_header_handler()
https://github.com/php/php-src/blob/master/sapi/cli/php_cli.c#L389-L392
can work normally from CLI using the fallback. Only the headers_sent() need to be always false.
https://github.com/php/php-src/blob/master/sapi/cli/php_cli.c#L446-L448

Related to #12303
https://3v4l.org/Wub2V

Actual behavior
https://3v4l.org/vZtmZ
Yes, it's curious that the setcookie() return true.
And the http_response_code() also work from CLI, we only need to set the initial value, but not the headers.

First because other php functions use it internally, like setcookie, session, ...

But it's more important to use php files without changes from CLI.
Basic example:

<?php
header_remove();
http_response_code(200);

ob_start();

include 'file.php';

$body = ob_get_clean();

$headers = create_status(http_response_code());

$headers .= implode("\r\n", headers_list()) . "\r\n";

$headers .= 'Content-Length: ' . strlen($body);

send_to_socket($headers, $body);

So we can use any PHP file from CLI and send it to any socket.
Actually we need to create custom functions to manage the headers, and change the normal php files.
But with the headers_list() and http_response_code() we can create all the http message.

BC: Nothing
That functions now do nothing from CLI.
If accepted it'll be good to be added to all php supported versions.

PHP Version

All

Operating System

All

@MaxSem
Copy link
Contributor

MaxSem commented Oct 8, 2023

Personally, I would rather prefer that all HTTP functionality not applicable in CLI threw exceptions instead of quietly not working. Same for vice versa: CLI functions in HTTP SAPIs.

@iluuu1994 iluuu1994 added Feature and removed Bug labels Oct 18, 2023
@nggit
Copy link

nggit commented Oct 24, 2023

Alternatively I hope that header functions can be removed completely in the CLI so that users can create a custom header() function. Or at least give a way to override it. header_register_callback doesn't seem to work.

@joanhey
Copy link
Contributor Author

joanhey commented Oct 24, 2023

You can override it, in PHP8.0. Like I do in my project https://github.com/joanhey/AdapterMan.

But later you need an spiral of changes: setcookie, Session, http_response_code, ...

We can use the same normal php headers handler, only the send headers handler need to do nothing. And we can create any output using the headers_list(). Also it will respect the user session handlers.
In the Adapterman project exist the php-session branch, and all the php code is gone if the php headers handler work.

In reality all the php-src session tests are using the CLI SAPI.
https://github.com/php/php-src/tree/master/ext/session/tests.
Only to test the header creation, use the CGI SAPI, and they only check the headers_list() that we can do also with CLI.

--CGI--
--FILE--
<?php
session_name("foo");
session_id('bar');
session_start();
foreach (headers_list() as $header) {
if (preg_match('/^Set-Cookie: foo=bar; expires=(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2[0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] GMT; Max-Age=3600; path=\\/$/', $header)) {
echo "Success", PHP_EOL;
exit;

We need later only a small change in the session, to clean the session_id.

With that small change, we can use headers, setcookie and sessions from CLI, without write a line of code.

@nggit
Copy link

nggit commented Oct 24, 2023

For now I ended up using php-cgi /path/to/script.php. And it looks like there is no need to worry about header() / headers_list()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants