4

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 :

  1. POST /exports
    • return 201 with data
  2. 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.

Schnapse
  • 485
  • 1
  • 5
  • 19
  • 2
    I don't think that is how 102 should be used. It should only be used as interim response, meaning that the full response will come after x period of time. In your case I think you would need to send a different json and have the consuming application re-try after x period of time. – Tuim May 14 '18 at 08:19
  • @Tuim It's how it's implemented : create an export and then check every seconds if it's done. Easiest solution is to return 200 no matter what and check the export status in the response's body. But I was looking for the real reason / particularities of the 102 http status code. – Schnapse May 14 '18 at 08:24
  • 1
    I think this question/answer might help you along: https://softwareengineering.stackexchange.com/questions/316208/http-status-code-for-still-processing – Tuim May 14 '18 at 08:35
  • Try making the request via different client Postman, curl etc.. and see if it shows response header - in postman use log for this. – Kyslik May 14 '18 at 08:55
  • You are asking about the HTTP headers when there is not a single reference to the header() function in the code you've shown us? – symcbean May 14 '18 at 11:22
  • @symcbean I don't have to manually set response headers ; laravel/lumen framework automatically set them for me. For all others requests, I get the expected headers I listed. – Schnapse May 14 '18 at 11:56

1 Answers1

2

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
leiavoia
  • 533
  • 1
  • 6
  • 12