tcdent/php-restclient

parse_response has problems with 100 Continue

Closed this issue · 3 comments

First, I love the class you created. It saved me a lot of time creating my own custom clients. I noticed a problem working with the AirWatch REST API. The API return headers such as "200 Continue" when data sets are abnormally large or truncated. So, you end up with two HTTP headers. The two headers are separated by line break.

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5

The result of this is that you never get the response parsed correctly. I did a bit of a hack to check for a 200 code and then skip it and the next line. I'm sure this could be done better.

public function parse_response($response){
    $headers = array();
    $http_ver = strtok($response, "\n");

    // Check for 100 Continue header followed by 200 OK header
    if (preg_match("/^HTTP\/[0-9]\.[0-9] 100 Continue/", $http_ver)) {
        $this->continue = true;
        // Skip blank line and get next http
        $line = strtok("\n");
        $http_ver = strtok("\n");
    }

    while($line = strtok("\n")){
        if(strlen(trim($line)) == 0) break;

        list($key, $value) = explode(':', $line, 2);
        $key = trim(strtolower(str_replace('-', '_', $key)));
        $value = trim($value);
        if(empty($headers[$key]))
            $headers[$key] = $value;
        elseif(is_array($headers[$key]))
            $headers[$key][] = $value;
        else
            $headers[$key] = array($headers[$key], $value);
    }

    $this->headers = (object) $headers;
    $this->response = trim(strtok(""));
}

Thanks for the kind words, Jeff.

It's definitely a problem, and the only reason it hasn't been officially fixed yet, is that I haven't put the time into coming up with a proper solution. I appreciate your effort, but (as you indicated) it's a little too rough to incorporate verbatim. I'll make it a priority to come up with a proper fix for this.

I'm thinking a while loop looking for 1-or-more HTTP response code lines before the headers is the proper way to go about it, FYI.

This was reported previously in #8.

OK, well I guess it wasn't that hard. Could you give this branch a try and let me know if it solves your problem? I'll merge it into master after we spend a little more time with it.

https://github.com/tcdent/php-restclient/tree/multistatus

This is resolved in the 0.1.5 release.