Recent versions of Win10 ship tar.exe utility which for compressed archives depends on stdcall build of libarchive open-source library which is shipped disguised under the name of archiveint.dll in C:\Windows\SysWOW64 (the 32-bit version we need).
Here is a .bas module with a single public Ungzip function which accepts a compressed byte-array and on successful decompression returns True:
Thus provided function can be used to decompress gzip response as returned by ServerXMLHTTP or WinHttpRequest object like this:
cheers,
</wqw>
Here is a .bas module with a single public Ungzip function which accepts a compressed byte-array and on successful decompression returns True:
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function archive_read_new Lib "archiveint" Alias "_archive_read_new@0" () As Long
Private Declare Function archive_read_free Lib "archiveint" Alias "_archive_read_free@4" (ByVal hArchive As Long) As Long
Private Declare Function archive_read_support_filter_gzip Lib "archiveint" Alias "_archive_read_support_filter_gzip@4" (ByVal hArchive As Long) As Long
Private Declare Function archive_read_support_format_raw Lib "archiveint" Alias "_archive_read_support_format_raw@4" (ByVal hArchive As Long) As Long
Private Declare Function archive_read_open_memory Lib "archiveint" Alias "_archive_read_open_memory@12" (ByVal hArchive As Long, pBuffer As Any, ByVal lSize As Long) As Long
Private Declare Function archive_read_next_header Lib "archiveint" Alias "_archive_read_next_header@8" (ByVal hArchive As Long, pHeader As Long) As Long
Private Declare Function archive_read_data Lib "archiveint" Alias "_archive_read_data@12" (ByVal hArchive As Long, pBuffer As Any, ByVal lSize As Long) As Long
Public Function Ungzip(baInput() As Byte, baOutput() As Byte) As Boolean
Const BUFF_SIZE As Long = 65536
Dim baBuffer(0 To BUFF_SIZE - 1) As Byte
Dim hArchive As Long
Dim lSize As Long
Dim lResult As Long
Dim lOutSize As Long
hArchive = archive_read_new()
If hArchive = 0 Then
GoTo QH
End If
lResult = archive_read_support_filter_gzip(hArchive)
If lResult <> 0 Then
GoTo QH
End If
lResult = archive_read_support_format_raw(hArchive)
If lResult <> 0 Then
GoTo QH
End If
lResult = archive_read_open_memory(hArchive, baInput(0), UBound(baInput) + 1)
If lResult <> 0 Then
GoTo QH
End If
lResult = archive_read_next_header(hArchive, 0)
If lResult <> 0 Then
GoTo QH
End If
baOutput = vbNullString
Do
lSize = archive_read_data(hArchive, baBuffer(0), UBound(baBuffer) + 1)
If lSize = 0 Then
Exit Do
End If
ReDim Preserve baOutput(0 To lOutSize + lSize - 1) As Byte
Call CopyMemory(baOutput(lOutSize), baBuffer(0), lSize)
lOutSize = lOutSize + lSize
Loop
'--- success
Ungzip = True
QH:
If hArchive <> 0 Then
Call archive_read_free(hArchive)
End If
End Function
Code:
Option Explicit
Private Sub Form_Load()
Dim baUncompressed() As Byte
With New MSXML2.ServerXMLHTTP
.Open "GET", "https://www.google.com/", False
'--- note: changing this request header is important because original Mozilla/4.0 User-Agent string
'--- prevents web servers from compressing response with gzip (or deflate)
.SetRequestHeader "User-Agent", "Mozilla/5.0"
.SetRequestHeader "Accept-Encoding", "gzip"
.Send
If .GetResponseHeader("Content-Encoding") <> "gzip" Then
Debug.Print "Response not gzipped"
Exit Sub
End If
If Not Ungzip(.ResponseBody, baUncompressed) Then
Debug.Print "Ungzip failed"
Exit Sub
End If
'--- note: response might be utf-8 encoded
Debug.Print StrConv(baUncompressed, vbUnicode)
End With
End Sub
</wqw>