PDM
PDM

Reputation: 11

Interpreting content of the HTTP responsebody. Confronted with som unexpected prefix data

I am trying to download a PDF file (URL is provided to me) from within VBA code. I am creating an WinHTTPReq object (MSXML6.XMLHTTP60). I set the content-type to application/pdf

Everything works however for some reason the file that I write (I am writing the responsebody result to a file) contains a 12 byte kind of header ( the middle 4 are the real file length of the PDF)

These bytes are not present if I click on the URL and download the PDF from a browser.

I tried playing around with content-type a bit without avail. I googled to understand this 12 byte prefix better without result.

Private Function DownloadFileFromURL(sURL As String, sOutputFileSpec) As Boolean
  Dim WinHttpReq As New MSXML2.XMLHTTP60
  Dim iFileHandle As Integer
  Dim s As String

  WinHttpReq.Open "GET", sURL, False
  WinHttpReq.setRequestHeader "Content-Type", "application/pdf"
  WinHttpReq.send

  If WinHttpReq.Status = 200 Then
    iFileHandle = FreeFile()
    Open sOutputFileSpec For Binary Access Write As iFileHandle
    Put #iFileHandle, 1, WinHttpReq.responseBody

    Close iFileHandle
    DownloadFileFromURL = True
  Else
    DownloadFileFromURL = False
  End If
End Function
 od -x Test.pdf 
0000000      2011    0001    f39a    0016    0000    0000    5025    4644
0000020      312d    342e    250d    e3e2    d3cf    0a0d    3437    3020
0000040      6f20    6a62    3c0a    2f3c    694c    656e    7261    7a69

I don't know the reason for the 2011 0001 f39a 0016 0000 0000... (btw 0x0016f39a is the length of the PDF file (without the 12 bytes). After this the file really starts 5025 4644 (= %PDF)

Upvotes: 1

Views: 570

Answers (1)

Seva Alekseyev
Seva Alekseyev

Reputation: 61398

The 12 byte prefix comes from VBA's Put command. The declared type of ResponseBody is Variant, and Put has logic to annotate the variant type before writing out the Variant contents.

You need to copy the content into a byte array before writing out. It would go:

If WinHttpReq.Status = 200 Then
    Dim Body() As Byte
    ReDim Body(UBound(WinHttpReq.responseBody)) As Byte
    Body = WinHttpReq.responseBody

    iFileHandle = FreeFile()
    Open sOutputFileSpec For Binary Access Write As iFileHandle
    Put #iFileHandle, 1, Body

    Close iFileHandle

Upvotes: 0

Related Questions