/**
  * Return array contains the response of the given URL.
  * array[code] => HTTP status code
  * array[headers] => HTTP headers
  * array[headers] => Entity body
  * Throw exception if error.
  *
  * @param  string  $url
  * @param  array   $headers
  * @param  array   $post
  * @return array
  */
 private function getHttpResponse($url, $headers = array(), $post = array())
 {
     $url = str_replace('&', '&', trim($url));
     $req = new HTTP_Request($url, array('allowRedirects' => true, 'maxRedirects' => 5));
     /*
      * @see HTTP_Request_Listener_Extended
      */
     $listener = new HTTP_Request_Listener_Extended();
     $req->attach($listener);
     if (!isset($headers['user-agent'])) {
         $headers['user-agent'] = $this->httpUserAgent;
     }
     foreach ($headers as $key => $value) {
         if (!empty($value)) {
             $req->addHeader($key, $value);
         }
     }
     if (!empty($post)) {
         $req->setMethod('POST');
         foreach ($post as $key => $value) {
             $req->addPostData($key, $value);
         }
     }
     $result = $req->sendRequest();
     $is_error = false;
     if (PEAR::isError($result)) {
         $is_error = true;
         $error_message = $result->getMessage();
         /*
          * $error_message could be empty if the error was raised
          * when fsockopen() returns false in Net_Socket::connect()
          */
         if (empty($error_message)) {
             $error_message = "Failed connecting to the server.";
             /*
              * HTTP_Request raises 'Malformed response' error
              * if request path is empty (e.g. http://www.example.com).
              * This bug still exists in its automatic redirection mechanism
              * in CVS rev. 1.55 (latest as of May 18, 2007).
              */
         } elseif ($error_message == 'Malformed response.') {
             $url = $req->getURL(null);
             if (false !== ($urls = @parse_url($url)) and !isset($urls['path'])) {
                 $req->setURL($url);
                 $result = $req->sendRequest();
                 if (PEAR::isError($result)) {
                     $error_message = $result->getMessage();
                     if (empty($error_message)) {
                         $error_message = "Failed connecting to the server.";
                     }
                 } else {
                     $is_error = false;
                 }
             }
         }
     }
     if ($is_error) {
         throw new Exception($error_message);
     }
     return array('url' => $req->getUrl(null), 'code' => $req->getResponseCode(), 'headers' => $req->getResponseHeader(), 'body' => $req->getResponseBody());
 }
 function download_incomplete_files($tmp_dir)
 {
     foreach ($this->to_download as $dl) {
         // work out the url and final path
         $output_fn = $dl['full_path'] . '.r' . $this->target_revision;
         $url = $this->url_join($this->state->get_repository_root(), $dl['href']);
         $this->out("Downloading {$url} to {$output_fn}");
         // make sure the file isn't already there
         if (file_exists($output_fn) && md5_file($output_fn) == $dl['checksum']) {
             $this->out("Looks like we've already got it - good!");
             continue;
         }
         // looks like we'll have to download the file.  see if we
         // can write to the target location...
         if (!$this->can_write_to($output_fn)) {
             throw new Subversion_Failure("I don't have permission to write to {$output_fn}.  <br/>Try: <code>chmod 777 " . basename($output_fn) . "</code>");
         }
         // likewise for the temp file
         $tmp_fn = tempnam($tmp_dir, "svn.download.tmp");
         $this->out("(using {$tmp_fn} as a temporary filename)");
         // and do the download
         $req = new HTTP_Request($url);
         $f = fopen($tmp_fn, "wb");
         if (!$f) {
             throw new Subversion_Failure("Unable to open file {$tmp_fn}");
         }
         $req->attach(new Subversion_FileListener($f));
         $req->sendRequest(FALSE);
         fclose($f);
         clearstatcache();
         // got it!  check checksum
         if (md5_file($tmp_fn) != $dl['checksum']) {
             throw new Subversion_Failure("checksum of downloaded file {$url} does not match checksum in xml");
         }
         // and move it to the final location
         if (!rename($tmp_fn, $output_fn)) {
             unlink($tmp_fn);
             throw new Subversion_Failure("Unable to save downloaded file as {$output_fn}");
         }
     }
 }