Question:
I tested this on two computers with the latest Chilkat v9.5.0.66. When I try and post a zip 132mb zip file with .SynchronousRequest, a fatal error occurs and the application crashes. I am able to post smaller zip and pdf files so know that the code works. The exact error is "Run-time error '-2147417851 (80010105)'"
Matt, I have sent an email to Chilkat support with a link to the zip.
Code to upload * Error Occurs on .SynchronousRequest call
Do
oHttp.CloseAllConnections
Set oResp = oHttp.SynchronousRequest(rackDomain, 443, 1, oReq)
o("ErrorText") = oHttp.LastErrorText
If Not (oResp Is Nothing) Then
Process_Http = True
o("Status_Code") = oResp.StatusCode
o("Status_Line") = oResp.StatusLine
o("Resp_Body") = oResp.BodyStr
o("X-Trans-Id") = oResp.GetHeaderField("X-Trans-Id")
o("http_last_path") = oReq.Path
o("http_etag") = oResp.GetHeaderField("ETag")
Set oResp = Nothing
Exit Do
End If
I = I + 1
If I = 3 Then Exit Do
Sleep 200
Loop
Code to create the request object
With oReq
.httpVerb = "PUT"
.ContentType = o("http_content_type")
.Path = rackPath & "/" & o("ContainerName") & "/" & o("RecordID") & o("FileExt")
If Len(o("FileName")) > 0 Then
.Path = rackPath & "/" & o("ContainerName") & "/" & o("FileName")
End If
.AddHeader "X-Auth-Token", rackToken
.AddHeader "Content-Length", oBinDat.numBytes
.AddHeader "ETag", oCrypt.HashBytesENC(oBinDat.GetBinary)
If o("Module") = ModuleType.Issuance Then
.AddHeader "X-Object-Meta-ArchiveID", o("RecordID")
If Not IsNull(UsageID) Then .AddHeader "X-Object-Meta-UsageID", UsageID
End If
.LoadBodyFromBytes oBinDat.GetBinary
End With
Crypt Settings
With oCrypt
.HashAlgorithm = "md5"
.EncodingMode = "hex"
End With
Thanks Erik,
I suspect an out-of-memory condition. The following line of code would copy the data in it's entirety in memory, which would double the size held in memory:
.LoadBodyFromBytes oBinDat.GetBinary
Does the .zip file being uploaded reside as a file in the filesystem? If so, then you can just point the HttpRequest object to the file, and when Chilkat uploads, it will stream the file data directly from the file. This way, the file can be any size with no memory usage impact.
Instead of calling LoadBodyFromBytes, you would do this:
success = .StreamBodyFromFile("c:/some/path/to/the.zip")
The StreamBodyFromFile method is simply noting the path of the file that will be opened and streamed through the HTTP/HTTPS connection when the upload actually occurs.
Thanks Erik,
The solution is to avoid all places where the file's binary data is moved across the COM boundary from Chilkat to your app. In other words, when you do something like this:
.LoadBodyFromBytes oBinDat.GetBinaryThe file data (132MB) is copied to a Variant and moves across the COM boundary to your app. The "explosion" ;) is likely due to the size.
What we want to do is to keep the data within Chilkat, i.e. within the native C++ code so that it never really needs to be marshaled to your app. This would be done via the BinData object.
The first step is to get the file data in a BinData object. (Maybe you've already done that?) Once accomplished, I can see two places where the code needs to be changed so we can keep the data from crossing over to the application.
1) Instead of calling oCrypt.HashBytesENC, call oCrypt.HashBdENC (where you pass it the BinData object) This is better because instead of marshaling 132MB from your app to the C++ code, you're just passing a reference to an object where the data is already contained. This makes it faster AND it prevents the temporary doubling of memory requirements.
2) I'll need to add a method to the HttpRequest object named LoadBodyfromBd (or perhaps UseBodyFromBd) so that the contents of the BinData are used for the request body. This would replace the call to LoadBodyFromBytes.
I think these changes will resolve the problem. I'll post when I have a new ActiveX build ready with this new method..