/** * Pass the object implementing the handlers * * @param gCurlHandlers $Handlers */ function setHandlers(gCurlHandlers $Handlers) { $Handlers->setGCurlReference($this); $this->Response->setHandlers($Handlers); }
/** * The function is called for each header line * * @param resource ch - Curl handler resource * @param string header_line - line of a header */ public function headersHandler($ch, $header_line) { //the length of the header should be returned $header_len = strlen($header_line); //first call, check if it's an HTTP response status line if ($this->flags ^ gCurl::FLAG_HTTP_OK) { $regexp = "~^HTTP/1\\..\\s(\\d{3})~"; if (!preg_match($regexp, $header_line, $found)) { //Non-HTTP Response Heade throw new gCurlException(110); } else { //ok, it's HTTP $this->flags |= gCurl::FLAG_HTTP_OK; //get response codes $this->headers['status-line'] = rtrim($header_line); $this->headers['status-code'] = $this->status_code = $found[1]; $this->headers['status-class'] = $this->status_class = $this->status_code[0]; $this->headers['len'] = 0; } } elseif ($header_len < 3 && ($header_line[0] == "\r" || $header_line[0] == "\n")) { //Call headers handler and assign the body handler //The content type response header can be ignored if (!empty($this->force_content_type)) { $this->headers['content-type'] = $this->content_type = $this->force_content_type; } //handlers are processed and defined here if ($this->gCurlHandlers) { //call headers handler $this->gCurlHandlers->headersHandler($this->headers); if ($this->cookies) { //call cookies handler $this->gCurlHandlers->cookiesHandler($this->cookies); } //if the body handler is defined - assign it to CURL if ($this->gCurlHandlers->bodyHandlerName) { $body_handler = array($this->gCurlHandlers, $this->gCurlHandlers->bodyHandlerName); if (!is_callable($body_handler)) { throw new gCurlException(20); } curl_setopt($this->ch, CURLOPT_WRITEFUNCTION, $body_handler); } } } elseif ($this->headers['len'] > 1 && ($header_line[0] == ' ' || $header_line[0] == "\t")) { $last_num = $this->headers['len']--; //create the new full header line $full_header = $this->headers[$last_num]['name'] . ': ' . $this->headers[$last_num]['value'] . ' ' . trim($header_line); // reprocess it $last_header_name = $this->headers[$last_num]['name']; $this->headers[$last_num]['value'] = null; $this->headers[$last_header_name]['len']--; //recursive call - reproduce the header $this->headersHandler($ch, $full_header); } else { //increase header counter $header_num = ++$this->headers['len']; //new header - parse it $header = explode(':', $header_line, 2); if (isset($header[1])) { //header is correct, has a value after the colon $name = strtolower(rtrim($header[0])); $value = trim($header[1]); //create the enumerated list of headers $this->headers[$header_num] = array('name' => $name, 'value' => $value); //create the associative array of headers } else { //it is an invalid header $name = 'invalid'; $value = rtrim($header_line); } //create the associative array for faster search //link the array to the headers value if (empty($this->headers[$name]['len'])) { $this->headers[$name] = array('len' => 1, 0 => $this->headers[$header_num]['value']); } else { $len = ++$this->headers[$name]['len']; $this->headers[$name][$len - 1] = $this->headers[$header_num]['value']; } //create shortcuts for the frequently used headers and parse cookies switch ($name) { case 'content-type': $this->headers['content-type'] = $value; $semicolon = strpos($value, ';'); $charset = ''; if ($semicolon) { $content_type = substr($value, 0, $semicolon); $rest = ltrim(substr($value, $semicolon + 1)); if (substr($rest, 0, 7) == 'charset') { $charset = substr($rest, 8); } } else { $content_type = $value; } $this->headers['ctype'] = $this->content_type = $content_type; $this->headers['charset'] = $charset; break; case 'last-modified': $this->headers['last-modified'] = $value; break; case 'content-length': $this->headers['content-length'] = $value; break; case 'content-disposition': $this->headers['content-disposition'] = $value; break; case 'set-cookie': $this->parseCookie($value); break; //redirect detected //redirect detected case 'location': $this->headers['location'] = $value; //body can be skipped curl_setopt($this->ch, CURLOPT_NOBODY, true); break; } } return $header_len; }