/** * Executes a request. * This is a pretty generic PHP function for the most part. The only parts that are specific to Picasa * is the errors that are thrown. PHP doesn't have a built in function that does this very well (although there are packages * for it that can be installed), so this manually sets the HTTP headers and parses the whole response. * * @access protected * @static * @param string $host The destination address to send the request to. It should not include a protocol. * @param string $path The path on the host to send the request to. It should start with a "/" * @param string $data Any data that should be sent along with the request. If there is no data, leave it as null. * @param string $request The type of request to perform. Most common are GET, POST, PUT, and DELETE. The type of * request to use for each Picasa function is defined in Picasa's official documentation. * @param array $specialHeaders An array of strings of headers that should be sent with the request. The headers that are * always sent are Host, Content-Type, and Content-Length. The most common type of special * header is an authorization header from Google. Note that even if there is only one special header, * it still must be in an array. Also note that each line in the array should end in "\r\n" and * should be set in the array with double quotes, not single quotes, because "\r\n" is interpreted * differently by PHP if single quotes are used. Optional, the default is null. * @param string $type The type of content that will is being sent through the request. Optional, the default is * "application/x-www-form-urlencoded". * @param string $protocol The protocol to use when sending the request. Secure requests should use "ssl://". Note that * the protocol must end in "://" unless it's an empty string. For HTTP, this parameter can be left * as an empty string. Optional, the default is an empty string. * @param int $port The port number to send the request to. Different protocols have different port numbers. HTTP protocol * uses port 80 and SSL uses port 443. Optional, the default is 80. * @return string The entire response, including headers, that was recieved from the host. * @throws {@link Picasa_Exception} If a response of "200" or "201" is not recieved. In this case, the entire contents of the response, * including headers, is set to the $response field of the exception and the error supplied by * Picasa is set as the exceptions message. The idea is that the calling method can search the * response for a specific return code (for instance, a File Not Found or Forbidden error) and throw * a more specific exception. The caller can also search the response for values that are specific * to its request, such as a Captcha URL. */ protected static function do_request($host, $path, $data, $request, $specialHeaders = null, $type = "application/x-www-form-urlencoded", $protocol = "", $port = "80") { $contentlen = strlen($data); $req = "{$request} {$path} HTTP/1.1\r\nHost: {$host}\r\nContent-Type: {$type}\r\nContent-Length: {$contentlen}\r\n"; if (is_array($specialHeaders)) { foreach ($specialHeaders as $header) { $req .= $header; } } $req .= "Connection: close\r\n\r\n"; if ($data != null) { $req .= $data; } Picasa_Logger::getLogger()->logIfEnabled("Request to do: " . $request); $fp = fsockopen($protocol . $host, $port, $errno, $errstr); if (!$fp) { throw new Picasa_Exception($errstr); } fputs($fp, $req); $buf = ""; if (!feof($fp)) { $buf = @fgets($fp); } Picasa_Logger::getLogger()->logIfEnabled("Buffer returned: " . $buf); // If either a 200 or 201 response is not found, there was a problem so throw an exception if (preg_match("/200 /i", $buf) || preg_match("/201 /i", $buf)) { while (!feof($fp)) { $buf .= @fgets($fp); } fclose($fp); return $buf; } else { /* In the response returned from Picasa, it is really hard to pull out the error message. * Its location is two lines below the "Connection: Close" line. So that message is pulled * out, if possible, and set as the Exception's message. Also, the entire buffer is sent. * This way, the caller can throw it's own message by looking for its own response code. */ $expMessage = "An unknown error has occured while sending a {$request} request."; $break = false; $tmpBuf = ""; while (!feof($fp)) { $tmpBuf = @fgets($fp); $buf .= $tmpBuf; if (strcmp($tmpBuf, "Connection: Close\r\n") == 0) { for ($i = 0; !feof($fp); $i++) { if ($i == 2) { $expMessage = @fgets($fp); $buf .= $expMessage; $break = true; } else { $buf .= @fgets($fp); } } } } if (!$break) { $msg = Picasa::getResponseValue($buf, "Error"); if ($msg != null) { $expMessage = $msg; } } throw new Picasa_Exception($expMessage, $buf, $host . $path); } }