Response headers missing with http status code 102 - php

I'm currently developing a REST API in which I need to return a 102 HTTP status code (processing) while I'm generating an export.
Workflow :
POST /exports
return 201 with data
GET /exports/id
return 102 with data if the export is processing
return 200 with data if the export is completed
When I try to retrieve export data while it's processing, there are no response headers: response headers are missing with 102 HTTP status code. If I change the status code with 2xx for instance, it's working fine. I can't figure out. Is there anything specific with the 102 HTTP status code? When I say response headers are missing I mean: Chrome > Developer tools > Network Tab > Click on request > Headers tab > Only showing "General" and "Request Headers" (same with FF & Postman).
Used Technologies :
Ubuntu 18.04 LTS
PHP 7.2 (latest release)
laravel/lumen 5.6.21
Apache 2.4.29
Controller Code :
/**
* Return export by id
*
* #param int $id
* #return \Illuminate\Http\JsonResponse
*
* #throws AuthorizationException
* #throws ModelNotFoundException
*/
public function getItem(int $id)
{
if($export = Export::find($id))
{
$this->authorize(__FUNCTION__, $export);
if($export->status != Export::STATUS_COMPLETED)
{
return response()->json($export, 102);
}
return response()->json($export);
}
throw new ModelNotFoundException();
}
Expected Request Headers :
Access-Control-Allow-Origin
Cache-Control
Connection
Content-Length
Content-Type
Date
Proxy-Connection
Server
Vary
EDIT
I should have mentioned that it worked on my previous config :
Ubuntu 17.10 LTS
PHP 7.1 (latest release)
laravel/lumen 5.6.16
Apache 2.4.27
I haven't found in any release notes what could have impacted the request answer.

Use HTTP 202 Accepted instead.
See: https://softwareengineering.stackexchange.com/questions/316208/http-status-code-for-still-processing
Explained:
RFC 2518 says "The server MUST send a final response after the request has been completed", and this is interpreted to mean that your server needs to send an final response code in addition to the initial HTTP 102. Not doing so creates timeout problems for clients waiting for a final response but not getting one. Firefox will choke, Chrome will time out and convert it into HTTP 200 OK. cURL will inform that there is unread content.
So use HTTP 102 Processing only as a hint to clients that, "Okay, but this might take a minute...", after which you follow up with a final code and response body.
If it is a long running process that you want to periodically poll, use HTTP 202 Accepted and close the response.
It's also worth noting that http_response_code() does not handle HTTP 102.
Bad Example:
<?php header('HTTP/1.1 102 Processing'); exit; ?>
Good Example:
<?php
header('HTTP/1.1 102 Processing'); // let client know it might take a while
sleep(2); // do stuff that takes a while
header('HTTP/1.1 200 OK'); // counterintuitive, but works

Related

PHP + Curl: Connection closure while negotiation auth (HTTP 1.0?)

I have a problem between CURL and PHP. I tried to connect to an Exchange 2010 Server via EWS. The connection to the server works fine in command line using CURL but not with PHP Curl extension.
I attached an image with the debug information. On the left you see command line output, on the right PHP verbose output. When the PHP Curl Extension throws an error "Connection closure while negotiation auth (HTTP 1.0?)" the command line continues with a third HTTP request with results in an HTTP/1.1 302 Found:
Some additional information:
I use this library for CURL-Requests: https://github.com/jamesiarmes/php-ntlm/blob/master/src/SoapClient.php
we have about 80 exchange servers where there is no problem. Only with this server there is a problem. Our customer told about a software called "Sophos" used as a proxy for the webserver
CURLOPT_HTTPAUTH is CURLAUTH_NTLM
PHP Version 7.3.1 / 7.3.9 also tested
cURL Information 7.63.0 / 7.52.1 also tested
Does anybody know why the PHP Curl Extension closes the connection before the third request? Is this a bug of the extension, can I use a constant of PHP Curl to avoid that or is there another solution?
The connection is closed because the server says so. See your screenshot, one line above where the "What is the problem here?" points.
HTTP/1.1 401 Unauthorized
[...]
Connection: close
Content-Type: application/x-asmx
And probably the server closes the connection afterwards.
So that is not an action, but a result. The message is emitted in Curl_http_readwrite_headers:
#if defined(USE_NTLM)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
(conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
((data->req.httpcode == 407) &&
(conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
#endif
#if defined(USE_SPNEGO)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
(conn->http_negotiate_state == GSS_AUTHRECV)) ||
((data->req.httpcode == 407) &&
(conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
Presumably from the first block (NTLM), but these are the two occurrences, and they are next to each other anyway.
Fun fact: the same function only a lot later checks for the presence of a Connection: close header, so having the mystical flag conn->bits.close set probably means that the server dropped the connection already and it was detected on socket-level.
Side remark: the two sides of the comparison show very dissimilar interactions. On the left there is a practically empty GET request (Host, Authorization, User-Agent and Accept headers are provided), while on the right side there is a lot more complicated POST request (same headers plus Method, SOAPAction, an empty content with Expect for continuation).
I have faced such like this problem by using SoapClient
and Microsoft Exchange 2010 Server, and the trick was by changing the header array option 'Expect: 100-continue'
to 'Expect: 200-ok'
protected function buildHeaders($action)
{
return array(
'Method: POST',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP-CURL',
'Content-Type: text/xml; charset=utf-8',
"SOAPAction: \"$action\"",
'Expect: 200-ok',
);
}
The 100 (Continue) status code indicates that the initial part of a request has been received and has not yet been rejected by the server.
The 200 (OK) status code indicats that the request has succeeded. The meaning of a success varies depending on the HTTP method.
You can also check this out HTTP status codes
I wish this could help

php http post response for web hook

I'm trying to create a web hook notification. The documentation of the service i want to use requires that i specify a URL where POST requests can be performed. This URL will receive the following object, in json format, and must respond with a Status Code between 200-299.
{
"type": "ping"
}
I don't know how to proceed making my server on localhost respond with a 200 status code. http_response_code(200) works well on live server but nothing seem to be happening on localhost.
Is there any way i can make it work with localhost?
I've included the link to the documentation here (i hope it's not against the rule).
I am thinking that you wouldn't have to send them the response. The webhook would know about the response. If it reached your URL successfully, it would be a 200 OK right off the bat. If the API is requesting a response back then I imagine that you would have to call it back somehow. Is this a well-known API? Any documentation?
The response code is in the response header, not in the content.
PHP defaults to a response code of 200, so if you don't mess with it at all, you should be good.
If you want to set a different response code (202 for example), just call:
http_response_code(202);
Or set the full header yourself:
header('HTTP/1.1 202 Accepted');
Proper way to explicitly set 200 (or any other) status code with http_response_code function is just as following (don't echo or json_encode it):
http_response_code(200);
It should force webserver to use 200 status code in it's response. However, webserver could possibly ignore it. To check what response code your webserver sends, use telnet or any REST tool like Postman

How to not send a response body

I'm trying to send a header response back from our api with a http status code 201 Created and a Location:header.
No matter what I do I get a response body too, something that I don't want.
If I return an empty string (return "";), restler will put the string '""' in the response body. If I return null or do not return anything at all restler will put the string 'null' in the response body.
How do I tell Restler to not send anything but headers?
UPDATE :-
With the latest release of Restler 3 RC4. Returning null sends empty body for the response
This behaviour can be changed by setting
Defaults::$emptyBodyForNullResponse = false;
You can use #status comment to set the response code to 201
and #header comment for setting the location header
For older versions use the technique described below
From your api method, set both status and location header using header function followed by die or exit
header("HTTP/1.0 201 Created");
header('Location: http://api.example.com/item/45');
die();
This is a very valid use case that demands better way of doing this, We will soon update this answer with those solutions
Thanks for contributing to Restler :)

Return a HTTP 200 Code to the POST client?

I have a server sending POST to me. I need to reply with HTTP 200 OK.
Server needs kind of like a "Go Ahead!" prompt before it executes another action.
It requires a HTTP 200 response.
EDIT
I've tried the header(), but the server for some reason won't read it?
The 200 code is a standard response to a successful request... Even echoing out an empty json string would result in a 200 OK status.
echo json_encode(array());
If all you want to do is signal to your client that some process was completed, you can just echo back a custom status message or even a blank object like I demonstrated above.
If you want to actually manually send the 200 header you can do so like this -
header('Status: 200');
Make sure that this header is send before you have any output from the server.
This function call does the job:
http_response_code(200);
See: http://php.net/manual/en/function.http-response-code.php
This function call can be thrown anywhere in the server code -- the order of when this function is called does not seem to matter.

When using Ajax with PHP, which of the following are necessary to verify success?

Which of the following answers are correct ?
HTTP ready state of TRUE
HTTP ready state of 4
HTTP status code < 400
HTTP status of 200
Data present in the response
both HTTP status of 200 and HTTP ready state of TRUE
In all my apps, I require only ready state 4 for success, which means as little as: the request is done and the response (if any) is available.
But like Madmartigan very wisely commented: define your version of success.
Usually, an HTTP ready state of 4 and HTTP status code of 200 is needed in order to guarantee that data has been successfully transferred back to your program.

Categories