Solved

Problem posting multipart/form-data to server

Posted on 2008-10-27
7
822 Views
Last Modified: 2011-10-19
I am working on a project written in VB6 where I need to upload a PDF to a server over HTTP.  The file must be posted as multipart/form-data.  For some reason, when the file gets transmitted, it is getting corrupted.  I have verified that the binary data is correct immediately before I post to the server.  After I post, some of the binary data is different and the PDF will not display properly.  I am using ServerXMLHTTP to post the file.  I have included my code, the original PDF (PDF-Before.pdf), the form data that I am posting (PostData-Before.txt), the form data that gets received by the server (PostData-After.txt), and the resulting PDF file (PDF-After.pdf).  If I compare the before and after files using WinDiff, there are a few sections that are different in the binary data.  It is always the same parts that are different.  I would greatly appreciate your assistance with this.  
Dim objHTTP As ServerXMLHTTP40

Set objHTTP = New MSXML2.ServerXMLHTTP40

Call objHTTP.Open("POST", strURL, False)

Call objHTTP.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------7d83cf5800be")

Call objHTTP.Send(strBody)

Open in new window

PDF-Before.pdf
PDF-After.pdf
PostData-Before.txt
PostData-After.txt
0
Comment
Question by:tlconsulting
  • 4
  • 3
7 Comments
 
LVL 10

Expert Comment

by:c0ldfyr3
ID: 22820443
How are you opening the pdf file? As a string??
0
 

Author Comment

by:tlconsulting
ID: 22823541
The code I am using to retrieve the binary data from the PDF is below.  I verified that I can write the PDF back to a file from the string, as shown in the commented out code, and the PDF is not corrupt at that point.  It only gets corrupt after is is posted over HTTP.
Function GetBinaryFile(strFileName As String) As String

    Dim strFile As String

    Dim nFile

    

    ' Grap the file

    nFile = FreeFile

    Open strFileName For Binary Access Read As #nFile

    strFile = String(LOF(nFile), " ")

    Get #nFile, , strFile

    Close #nFile

    

    GetBinaryFile = strFile

    

    'nFile = FreeFile

    'Open "c:\temp\stream.pdf" For Binary Access Write As #nFile

    'Put #nFile, , strFile

    'Close #nFile

    

End Function

Open in new window

0
 
LVL 10

Assisted Solution

by:c0ldfyr3
c0ldfyr3 earned 400 total points
ID: 22823604
Can you try this please. Change your variable strBody to be as below...
Dim strBody()                       As Byte
 

strBody = GetBinaryFile("C:\Path\To\PDF.pdf")

Dim objHTTP As ServerXMLHTTP40

Set objHTTP = New MSXML2.ServerXMLHTTP40

Call objHTTP.Open("POST", strURL, False)

Call objHTTP.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------7d83cf5800be")

Call objHTTP.Send(strBody)
 

'******************************************************************'
 

Function GetBinaryFile(strFileName As String) As Byte()

    Dim strFile()                   As Byte

    Dim nFile                       As Long

    nFile = FreeFile

    Open strFileName For Binary Access Read As #nFile

        ReDim strFile(1 To LOF(nFile))

        Get #nFile, , strFile

    Close #nFile

    

    GetBinaryFile = strFile

End Function

Open in new window

0
VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

 

Author Comment

by:tlconsulting
ID: 22823829
The post data must be formatted as shown in PostData-Before.txt.  I can't just post the raw binary data.  I have a separate function that does the formatting as shown below.  Since the rest of the data is string data, how would I incorporate the byte array?

bound = "---------------------------7d83cf5800be"

boundSeparator = "--" & bound & vbCrLf

boundFooter = "--" & bound & "--" & vbCrLf
 

strBody = boundSeparator
 

strBody = strBody & "Content-Disposition: form-data; name=""" & "ID" & """" & vbCrLf & vbCrLf & gstrFNCUserNameXML

strBody = strBody & vbCrLf & boundSeparator
 

strBody = strBody & "Content-Disposition: form-data; name=""" & "PASSWORD" & """" & vbCrLf & vbCrLf & gstrFNCPasswordXML

strBody = strBody & vbCrLf & boundSeparator
 

strBody = strBody & "Content-Disposition: form-data; name=""" & "PORT_ID" & """" & vbCrLf & vbCrLf & strECNClientId

strBody = strBody & vbCrLf & boundSeparator
 

strBody = strBody & "Content-Disposition: form-data; name=""" & "FOLDER" & """" & vbCrLf & vbCrLf & strTransactionId

strBody = strBody & vbCrLf & boundSeparator
 

strBody = strBody & "Content-Disposition: form-data; name=""" & "INVOICE_NUM" & """" & vbCrLf & vbCrLf & lngOrderId

strBody = strBody & vbCrLf & boundSeparator
 

strBody = strBody & "Content-Disposition: form-data; name=""" & "TOTAL_FEE" & """" & vbCrLf & vbCrLf & curFee

strBody = strBody & vbCrLf & boundSeparator
 

strFileContent = GetBinaryFile(strSavePath & "\" & strFileName)

strBody = strBody & "Content-Disposition: form-data; name=""" & "FILE_REPORT" & """; filename=""" & strSavePath & "\" & strFileName & """" & vbCrLf & _

	"Content-Type: application/pdf" & vbCrLf & vbCrLf & strFileContent & vbCrLf

		

strBody = strBody & boundFooter

Open in new window

0
 
LVL 10

Assisted Solution

by:c0ldfyr3
c0ldfyr3 earned 400 total points
ID: 22823868
Can you post all of that down as far as the two vbCrLf before strFileContent and then the bytearray, I'm not familiar with that XML HTTP but it probably accepts a variant?

Call objHTTP.Send(strBody) 'Post Data
Call objHTTP.Send(bBytes) 'Byte Array
Call objHTTP.Send(boundFooter) 'Footer
0
 

Author Comment

by:tlconsulting
ID: 22824022
The send method can only be called once on the object.  It throws an error if it is called more than once.  
0
 

Accepted Solution

by:
tlconsulting earned 0 total points
ID: 22825879
I got it working!  I had to convert the entire string to a byte array first.  Thanks c0ldfyr3, your posts are what gave me the idea to try this.  The working code is posted below.  
Dim objHTTP As ServerXMLHTTP40

Dim b() As Byte

Set objHTTP = New MSXML2.ServerXMLHTTP40

Call objHTTP.Open("POST", strURL, False)

Call objHTTP.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------7d83cf5800be")

b = StrConv(strBody, vbFromUnicode)

Call objHTTP.Send(b)

Open in new window

0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
HTTP to HTTPS redirect is not working 1 47
Run code from text file in vb 1 56
HTTP POST packets in broadcast 5 47
Help me. 3 43
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now