/** * Perform a HTTP HEAD or GET request. * * If $file_path is a writable filename, this will do a GET request and write * the file to that path. * * @since 2.5.0 * * @param string $url URL to fetch. * @param string|bool $file_path Optional. File path to write request to. * @param int $red (private) The number of Redirects followed, Upon 5 being hit, returns false. * @return bool|string False on failure and string of headers if HEAD request. */ function nxt_get_http($url, $file_path = false, $red = 1) { @set_time_limit(60); if ($red > 5) { return false; } $options = array(); $options['redirection'] = 5; if (false == $file_path) { $options['method'] = 'HEAD'; } else { $options['method'] = 'GET'; } $response = nxt_remote_request($url, $options); if (is_nxt_error($response)) { return false; } $headers = nxt_remote_retrieve_headers($response); $headers['response'] = nxt_remote_retrieve_response_code($response); // nxt_HTTP no longer follows redirects for HEAD requests. if ('HEAD' == $options['method'] && in_array($headers['response'], array(301, 302)) && isset($headers['location'])) { return nxt_get_http($headers['location'], $file_path, ++$red); } if (false == $file_path) { return $headers; } // GET request - write it to the supplied filename $out_fp = fopen($file_path, 'w'); if (!$out_fp) { return $headers; } fwrite($out_fp, nxt_remote_retrieve_body($response)); fclose($out_fp); clearstatcache(); return $headers; }
/** * Attempt to download a remote file attachment * * @param string $url URL of item to fetch * @param array $post Attachment details * @return array|nxt_Error Local file location details on success, nxt_Error otherwise */ function fetch_remote_file($url, $post) { // extract the file name and extension from the url $file_name = basename($url); // get placeholder file in the upload dir with a unique, sanitized filename $upload = nxt_upload_bits($file_name, 0, '', $post['upload_date']); if ($upload['error']) { return new nxt_Error('upload_dir_error', $upload['error']); } // fetch the remote url and write it to the placeholder file $headers = nxt_get_http($url, $upload['file']); // request failed if (!$headers) { @unlink($upload['file']); return new nxt_Error('import_file_error', __('Remote server did not respond', 'nxtclass-importer')); } // make sure the fetch was successful if ($headers['response'] != '200') { @unlink($upload['file']); return new nxt_Error('import_file_error', sprintf(__('Remote server returned error response %1$d %2$s', 'nxtclass-importer'), esc_html($headers['response']), get_status_header_desc($headers['response']))); } $filesize = filesize($upload['file']); if (isset($headers['content-length']) && $filesize != $headers['content-length']) { @unlink($upload['file']); return new nxt_Error('import_file_error', __('Remote file is incorrect size', 'nxtclass-importer')); } if (0 == $filesize) { @unlink($upload['file']); return new nxt_Error('import_file_error', __('Zero size file downloaded', 'nxtclass-importer')); } $max_size = (int) $this->max_attachment_size(); if (!empty($max_size) && $filesize > $max_size) { @unlink($upload['file']); return new nxt_Error('import_file_error', sprintf(__('Remote file is too large, limit is %s', 'nxtclass-importer'), size_format($max_size))); } // keep track of the old and new urls so we can substitute them later $this->url_remap[$url] = $upload['url']; $this->url_remap[$post['guid']] = $upload['url']; // r13735, really needed? // keep track of the destination if the remote url is redirected somewhere else if (isset($headers['x-final-location']) && $headers['x-final-location'] != $url) { $this->url_remap[$headers['x-final-location']] = $upload['url']; } return $upload; }