Что нового

Баг InetGet() и InetGetSize() с определением размера файла.

timsky

Осваивающий
Сообщения
93
Репутация
28
ОС: Windows 7 x64 En
AutoIt 3.3.4.0

InetGet() и InetGetSize() неправильно определяют размер файла, если файл больше:
1) 2Gb, то выдают отрицательное значение
2) 4Gb, то выдают положительное значение
От размера файла вычитается 4Gb.
Т.е. есть файл больше 4 гиг, то выдает > 0 и уже не понятно, как определить, правильный ли это размер! :blink:

Код:
Dim $aFiles[3]
$aFiles[0] = 'http://download.microsoft.com/download/1/f/0/1f07c259-7ff2-4902-9205-ad1dfb87ccab/VS2008SP1MSDNENUX1506188.iso'
$aFiles[1] = 'http://download.microsoft.com/download/F/0/D/F0D01B2E-E6DD-41E3-A814-138509AC0E46/RUSMSDNX1529236.iso'
$aFiles[2] = 'http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDK_EN_DVD.iso'

For $i = 0 To 2
 $size = InetGetSize($aFiles[$i])
 MsgBox(4096, @error, $aFiles[$i] & @CRLF & 'Return size: ' & $size & @CRLF & 'Real size: ' & $size + 4 * 1024 ^ 3)
Next


Только что столкнулся с тем, что у меня скрипт раз 20 скачал по первому линку файлик 2,3 гига.
Проверить, что выдает InetGet() по оконцании закачки файла > 4 гиг нет возможности, но InetGetSize() проверил и подозреваю, что то же самое.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
timsky [?]
у меня скрипт раз 20 скачал по первому линку файлик 2,3 гига
Этот файл столько и весит. Откуда информация что больше?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
timsky [?]
InetGet() и InetGetSize() неправильно определяют размер файла, если файл больше:
1) 2Gb, то выдают отрицательное значение
2) 4Gb, то выдают положительное значение
От размера файла вычитается 4Gb.

Это потому, что для значения размера файла используется тип DWORD. Не уверен, что этого нет в BugTracker. Нужно посмотреть...

Для многих функций Microsoft пофиксила это "недоразумение" только начиная с Windows Vista. Просто раньше даже в самом страшном сне никому не могло присниться, что по inet можно будет передавать файлы о 4GB!!!

:laugh:
 
Автор
timsky

timsky

Осваивающий
Сообщения
93
Репутация
28
CreatoR [?]
Откуда информация что больше?
АвтоИт говорит :smile:

Yashied
Ну я примерно так и думал. Только у меня распоследняя ОСь и нифига не пофиксили такую важную фичу :-X
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Тут дело не в ОСи, Microsoft просто ввел дополнительные функции, работающие с 64-битными числами. Вопрос в том какую функцию использует AutoIt для реализации InetGetSize(). Из соображений совместимости конечно же старую. Но возможно я и ошибаюсь, может быть здесь проблема в самом AutoIt.
 
Автор
timsky

timsky

Осваивающий
Сообщения
93
Репутация
28
Глянул, нет на багтрекере этого бага.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
timsky [?]
Ну так а как ты можешь быть уверен в том, что файл на самом деле больше чем он говорит?

Вот пример получающий заголовок файла:

Код:
$sURL = "http://download.microsoft.com/download/1/f/0/1f07c259-7ff2-4902-9205-ad1dfb87ccab/VS2008SP1MSDNENUX1506188.iso"

$sHost = StringRegExpReplace($sURL, ".*://(.*?)/.*", "\1")
$sPage = StringRegExpReplace($sURL, ".*://.*?(/.*)", "\1")

$sResponse = _HTTPGetResponse($sHost, $sPage)

$sRet = StringRegExpReplace($sResponse, "(?s).*Content-Length: (.*?)[\r\n].*", "\1")

MsgBox(64, "File Hedaer", $sResponse)
MsgBox(64, "Content-Lenght (Header)", $sRet)
MsgBox(64, "Content-Lenght (InetGetSize)", InetGetSize($sURL))

Func _HTTPGetResponse($sHost, $sPage)
	TCPStartup()
	
	Local $sName_To_IP = TCPNameToIP($sHost)
	Local $iSocket = TCPConnect($sName_To_IP, 80)
	
	If $iSocket = -1 Then
		TCPShutdown()
		Return SetError(1, 0, "")
	EndIf
	
	Local $sCommand = "HEAD " & $sPage & " HTTP/1.1" & @CRLF
	
	$sCommand &= "Host: " & $sHost & @CRLF
	$sCommand &= "User-Agent: AutoIt/" & @AutoItVersion & " (Windows; U; Windows NT 5.1; en-US; rv:1.8.1)" & @CRLF
	$sCommand &= "Referer: " & $sHost & @CRLF
	$sCommand &= "Connection: close" & @CRLF & @CRLF
	
	Local $BytesSent = TCPSend($iSocket, $sCommand)
	
	If $BytesSent = 0 Then
		TCPShutdown()
		Return SetError(2, @error, 0)
	EndIf
	
	Local $sRecv = "", $sCurrentRecv
	
	While 1
		$sCurrentRecv = TCPRecv($iSocket, 16)
		If @error <> 0 Then ExitLoop
		If $sCurrentRecv <> "" Then $sRecv &= $sCurrentRecv
	WEnd
	
	TCPCloseSocket($iSocket)
	TCPShutdown()
	
	Return $sRecv
EndFunc


В сравнений видно, что результат тот же :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Ограничение действительно присутствует. Вот этот файл весит ~4.3 GB, но

Код:
ConsoleWrite(InetGetSize('http://ftp.scientificlinux.org/linux/scientific/50/iso/x86_64/SL-5.0-051607-x86_64-DVD.iso') & @CR)


показывает только Lo DWORD.

:(

Я спрашивал на оф. форуме, и действительно, это "неприятное ограничение" в Autoit. По крайней мере это слова Valik'а.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
показывает только Lo DWORD
Не уверен что это значит, но у меня показывает вот что:

Код:
4605329408

Тоже самое показывают и все остальные инструменты для получения размера файла:

Код:
ConsoleWrite(_InetGetSizeEx('http://ftp.scientificlinux.org/linux/scientific/50/iso/x86_64/SL-5.0-051607-x86_64-DVD.iso') & @CR)

Func _InetGetSizeEx($sURL)
    TCPStartup()
    
	Local $sHost = StringRegExpReplace($sURL, ".*://(.*?)/.*", "\1")
	Local $sPage = StringRegExpReplace($sURL, ".*://.*?(/.*)", "\1")
	
    Local $sName_To_IP = TCPNameToIP($sHost)
    Local $iSocket = TCPConnect($sName_To_IP, 80)
    
    If $iSocket = -1 Then
        TCPShutdown()
        Return SetError(1, 0, "")
    EndIf
    
    Local $sCommand = "HEAD " & $sPage & " HTTP/1.1" & @CRLF
    
    $sCommand &= "Host: " & $sHost & @CRLF
    $sCommand &= "User-Agent: AutoIt/" & @AutoItVersion & " (Windows; U; Windows NT 5.1; en-US; rv:1.8.1)" & @CRLF
    $sCommand &= "Referer: " & $sHost & @CRLF
    $sCommand &= "Connection: close" & @CRLF & @CRLF
    
    Local $BytesSent = TCPSend($iSocket, $sCommand)
    
    If $BytesSent = 0 Then
        TCPShutdown()
        Return SetError(2, @error, 0)
    EndIf
    
    Local $sRecv = "", $sCurrentRecv
    
    While 1
        $sCurrentRecv = TCPRecv($iSocket, 16)
        If @error <> 0 Then ExitLoop
        If $sCurrentRecv <> "" Then $sRecv &= $sCurrentRecv
    WEnd
    
    TCPCloseSocket($iSocket)
    TCPShutdown()
	
    $sRecv = StringRegExpReplace($sRecv, "(?s).*Content-Length: (.*?)[\r\n].*", "\1")
	If @extended = 0 Then Return SetError(2, 0, "")
	
    Return $sRecv
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
У меня показывает 310,362,112

AutoIt 3.3.2.0

Код:
ConsoleWrite(InetGetSize('http://ftp.scientificlinux.org/linux/scientific/50/iso/x86_64/SL-5.0-051607-x86_64-DVD.iso') & @CR)


Твой пример показывает 4,605,329,408

:smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Что и требовалось доказать.

:smile:



Добавлено:
Сообщение автоматически объединено:

AutoIt 3.3.4.0 возвращает 0 и ошибку под номером 13 (как символично).

:shok:

Я так понимаю, что InetGetSize() лучше вообще не пользоваться.
 
Автор
timsky

timsky

Осваивающий
Сообщения
93
Репутация
28
В одной из последних беток вроде пофиксили. Я бетку не пробовал, но радует :smile:
 
Верх