Remote file size without file upload

Is there any way to get the remote file size http: //my_url/my_file.txt without downloading the file?

+63
php curl
Apr 08 2018-10-18T00:
source share
13 answers

Found something about it here :

Here's the best way (which I found) to get the size of the deleted file. Note that HEAD requests do not receive the actual request volume, they simply retrieve the headers. Thus, a HEAD request for a resource, i.e. 100 MB, will occupy the same period of time as a HEAD request for a resource, which is 1 KB.

<?php /** * Returns the size of a file without downloading it, or -1 if the file * size could not be determined. * * @param $url - The location of the remote file to download. Cannot * be null or empty. * * @return The size of the file referenced by $url, or -1 if the size * could not be determined. */ function curl_get_file_size( $url ) { // Assume failure. $result = -1; $curl = curl_init( $url ); // Issue a HEAD request and follow any redirects. curl_setopt( $curl, CURLOPT_NOBODY, true ); curl_setopt( $curl, CURLOPT_HEADER, true ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true ); curl_setopt( $curl, CURLOPT_USERAGENT, get_user_agent_string() ); $data = curl_exec( $curl ); curl_close( $curl ); if( $data ) { $content_length = "unknown"; $status = "unknown"; if( preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches ) ) { $status = (int)$matches[1]; } if( preg_match( "/Content-Length: (\d+)/", $data, $matches ) ) { $content_length = (int)$matches[1]; } // http://en.wikipedia.org/wiki/List_of_HTTP_status_codes if( $status == 200 || ($status > 300 && $status <= 308) ) { $result = $content_length; } } return $result; } ?> 

Using:

 $file_size = curl_get_file_size( "http://stackoverflow.com/questions/2602612/php-remote-file-size-without-downloading-file" ); 
+89
Apr 08 '10 at
source share

Try this code

 function retrieve_remote_file_size($url){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HEADER, TRUE); curl_setopt($ch, CURLOPT_NOBODY, TRUE); $data = curl_exec($ch); $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); curl_close($ch); return $size; } 
+56
Nov 16 2018-11-11T00:
source share

As mentioned several times, a way to get information from the Content-Length response header field.

However, you should notice that

  • the server you are checking does not necessarily implement the HEAD (!) method
  • there is no need to manually process the HEAD request (which, again, may not even be supported) using fopen or similar or even to call the curl library when PHP get_headers() (remember: KISS )

Using get_headers() follows the KISS principle and works even if the server you are testing does not support the HEAD request.

So here is my version (trick: returns a human-readable format in a format ;-)):

Gist: https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d (curl and get_headers version)
get_headers () - Version:

 <?php /** * Get the file size of any remote resource (using get_headers()), * either in bytes or - default - as human-readable formatted string. * * @author Stephan Schmitz <eyecatchup@gmail.com> * @license MIT <http://eyecatchup.mit-license.org/> * @url <https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d> * * @param string $url Takes the remote object URL. * @param boolean $formatSize Whether to return size in bytes or formatted. * @param boolean $useHead Whether to use HEAD requests. If false, uses GET. * @return string Returns human-readable formatted size * or size in bytes (default: formatted). */ function getRemoteFilesize($url, $formatSize = true, $useHead = true) { if (false !== $useHead) { stream_context_set_default(array('http' => array('method' => 'HEAD'))); } $head = array_change_key_case(get_headers($url, 1)); // content-length of download (in bytes), read from Content-Length: field $clen = isset($head['content-length']) ? $head['content-length'] : 0; // cannot retrieve file size, return "-1" if (!$clen) { return -1; } if (!$formatSize) { return $clen; // return size in bytes } $size = $clen; switch ($clen) { case $clen < 1024: $size = $clen .' B'; break; case $clen < 1048576: $size = round($clen / 1024, 2) .' KiB'; break; case $clen < 1073741824: $size = round($clen / 1048576, 2) . ' MiB'; break; case $clen < 1099511627776: $size = round($clen / 1073741824, 2) . ' GiB'; break; } return $size; // return formatted size } 

Using:

 $url = 'http://download.tuxfamily.org/notepadplus/6.6.9/npp.6.6.9.Installer.exe'; echo getRemoteFilesize($url); // echoes "7.51 MiB" 



Note: The Content-Length header is optional. Thus, as a general solution, it is not bulletproof !




+26
Sep 17 '14 at 21:02
source share

Sure. Make a request for headers only and find the Content-Length header.

+14
Apr 08 '10 at
source share

I'm not sure, but could you not use the get_headers function for this?

 $url = 'http://example.com/dir/file.txt'; $headers = get_headers($url, true); if ( isset($headers['Content-Length']) ) { $size = 'file size:' . $headers['Content-Length']; } else { $size = 'file size: unknown'; } echo $size; 
+4
May 25 '14 at 10:25
source share

The simplest and most effective implementation:

 function remote_filesize($url, $fallback_to_download = false) { static $regex = '/^Content-Length: *+\K\d++$/im'; if (!$fp = @fopen($url, 'rb')) { return false; } if (isset($http_response_header) && preg_match($regex, implode("\n", $http_response_header), $matches)) { return (int)$matches[0]; } if (!$fallback_to_download) { return false; } return strlen(stream_get_contents($fp)); } 
+3
May 5 '14 at 7:49
source share

The php get_headers() function works for me to check the length of the content as

 $headers = get_headers('http://example.com/image.jpg', TRUE); $filesize = $headers['content-length']; 

Read more: PHP get_headers () function

+3
Apr 20 '17 at 12:59 on
source share

Since this question has already been marked as "php" and "curl", I assume that you know how to use Curl in PHP.

If you set curl_setopt(CURLOPT_NOBODY, TRUE) , you will make a HEAD request and perhaps check the "Content-Length" header of the response, which will only be the header.

+2
Apr 08 '10 at 18:59 on
source share

Try the following function to get the size of the deleted file

 function remote_file_size($url){ $head = ""; $url_p = parse_url($url); $host = $url_p["host"]; if(!preg_match("/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/",$host)){ $ip=gethostbyname($host); if(!preg_match("/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/",$ip)){ return -1; } } if(isset($url_p["port"])) $port = intval($url_p["port"]); else $port = 80; if(!$port) $port=80; $path = $url_p["path"]; $fp = fsockopen($host, $port, $errno, $errstr, 20); if(!$fp) { return false; } else { fputs($fp, "HEAD " . $url . " HTTP/1.1\r\n"); fputs($fp, "HOST: " . $host . "\r\n"); fputs($fp, "User-Agent: http://www.example.com/my_application\r\n"); fputs($fp, "Connection: close\r\n\r\n"); $headers = ""; while (!feof($fp)) { $headers .= fgets ($fp, 128); } } fclose ($fp); $return = -2; $arr_headers = explode("\n", $headers); foreach($arr_headers as $header) { $s1 = "HTTP/1.1"; $s2 = "Content-Length: "; $s3 = "Location: "; if(substr(strtolower ($header), 0, strlen($s1)) == strtolower($s1)) $status = substr($header, strlen($s1)); if(substr(strtolower ($header), 0, strlen($s2)) == strtolower($s2)) $size = substr($header, strlen($s2)); if(substr(strtolower ($header), 0, strlen($s3)) == strtolower($s3)) $newurl = substr($header, strlen($s3)); } if(intval($size) > 0) { $return=intval($size); } else { $return=$status; } if (intval($status)==302 && strlen($newurl) > 0) { $return = remote_file_size($newurl); } return $return; } 
+2
Jan 02 '13 at
source share

Most of the answers here use either CURL or are based on reading headers. But in some specific situations, you can use a lighter solution. Check out the filesize() docs on PHP.net . You will find a review there: β€œStarting with PHP 5.0.0, this function can also be used with some URL wrappers. Refer to Supported Protocols and Wrappers to determine which wrappers support the stat () family of functions.

So, if your server and PHP parser are configured correctly, you can simply use the filesize() function, load it with the full URL, pointing to the remote file, what size you want to get, and let PHP do all the magic.

+1
Sep 17 '13 at 9:54 on
source share

Here is another approach that will work with servers that do not support HEAD requests.

It uses cURL to request a content request with an HTTP range header requesting the first byte of the file.

If the server supports range requests (most media servers), then it will receive a response with the size of the resource.

If the server does not respond with a byte, it will look for the content length header to determine the length.

If the size is found in the header of the range or length of the content, the transfer is interrupted. If the size is not found and the function begins to read the response body, the transfer is aborted.

This may be an additional approach if the HEAD request causes the 405 method to not support the response.

 /** * Try to determine the size of a remote file by making an HTTP request for * a byte range, or look for the content-length header in the response. * The function aborts the transfer as soon as the size is found, or if no * length headers are returned, it aborts the transfer. * * @return int|null null if size could not be determined, or length of content */ function getRemoteFileSize($url) { $ch = curl_init($url); $headers = array( 'Range: bytes=0-1', 'Connection: close', ); $in_headers = true; $size = null; curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2450.0 Iron/46.0.2450.0'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_VERBOSE, 0); // set to 1 to debug curl_setopt($ch, CURLOPT_STDERR, fopen('php://output', 'r')); curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $line) use (&$in_headers, &$size) { $length = strlen($line); if (trim($line) == '') { $in_headers = false; } list($header, $content) = explode(':', $line, 2); $header = strtolower(trim($header)); if ($header == 'content-range') { // found a content-range header list($rng, $s) = explode('/', $content, 2); $size = (int)$s; return 0; // aborts transfer } else if ($header == 'content-length' && 206 != curl_getinfo($curl, CURLINFO_HTTP_CODE)) { // found content-length header and this is not a 206 Partial Content response (range response) $size = (int)$content; return 0; } else { // continue return $length; } }); curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) use ($in_headers) { if (!$in_headers) { // shouldn't be here unless we couldn't determine file size // abort transfer return 0; } // write function is also called when reading headers return strlen($data); }); $result = curl_exec($ch); $info = curl_getinfo($ch); return $size; } 

Using:

 $size = getRemoteFileSize('http://example.com/video.mp4'); if ($size === null) { echo "Could not determine file size from headers."; } else { echo "File size is {$size} bytes."; } 
+1
Nov 10 '15 at 17:42
source share

single line best solution:

 echo array_change_key_case(get_headers("http://.../file.txt",1))['content-length']; 

php too delicius

 function urlsize($url):int{ return array_change_key_case(get_headers($url,1))['content-length']; } echo urlsize("http://.../file.txt"); 
0
Dec 19 '17 at 10:17
source share

Try this: I use it and get a good result.

  function getRemoteFilesize($url) { $file_headers = @get_headers($url, 1); if($size =getSize($file_headers)){ return $size; } elseif($file_headers[0] == "HTTP/1.1 302 Found"){ if (isset($file_headers["Location"])) { $url = $file_headers["Location"][0]; if (strpos($url, "/_as/") !== false) { $url = substr($url, 0, strpos($url, "/_as/")); } $file_headers = @get_headers($url, 1); return getSize($file_headers); } } return false; } function getSize($file_headers){ if (!$file_headers || $file_headers[0] == "HTTP/1.1 404 Not Found" || $file_headers[0] == "HTTP/1.0 404 Not Found") { return false; } elseif ($file_headers[0] == "HTTP/1.0 200 OK" || $file_headers[0] == "HTTP/1.1 200 OK") { $clen=(isset($file_headers['Content-Length']))?$file_headers['Content-Length']:false; $size = $clen; if($clen) { switch ($clen) { case $clen < 1024: $size = $clen . ' B'; break; case $clen < 1048576: $size = round($clen / 1024, 2) . ' KiB'; break; case $clen < 1073741824: $size = round($clen / 1048576, 2) . ' MiB'; break; case $clen < 1099511627776: $size = round($clen / 1073741824, 2) . ' GiB'; break; } } return $size; } return false; } 

Now test like this:

 echo getRemoteFilesize('http://mandasoy.com/wp-content/themes/spacious/images/plain.png').PHP_EOL; echo getRemoteFilesize('http://bookfi.net/dl/201893/e96818').PHP_EOL; echo getRemoteFilesize('https://stackoverflow.com/questions/14679268/downloading-files-as-attachment-filesize-incorrect').PHP_EOL; 

Results:

24.82 KiB

912 KiB

101.85 KiB

0
Jun 11 '18 at 5:39
source share



All Articles