login about faq

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

asked Apr 07 at 17:17

emartinson's gravatar image

emartinson
148162032


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.

link

answered Apr 10 at 15:00

chilkat's gravatar image

chilkat ♦♦
12.5k317361456

I do not think that will work for 2 reasons. First is I need to calculate the ETag. The second is that I am creating the zip in memory and passing the zip data to a bindata object as the middle man for the http upload. Is there a way to use stream and the chunking feature of bindata?

(Apr 10 at 21:01) emartinson

Sounds like you might want to save the ZIP to temporary storage and hash & stream from there. There are methods for calculating hashes by passing chunks to the library. See the HashBeginBytes, HashMoreBytes and HashFinalEnc methods.

(Apr 11 at 10:45) jpbro ♦

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.GetBinary
The 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..

link

answered Apr 11 at 10:54

chilkat's gravatar image

chilkat ♦♦
12.5k317361456

I pulled out the post/response code to separate file and tired loading the file from the disk and I found that .LoadBodyFromFile also blows up but .StreamBodyFromFile does not. Using v9.5.0.66

(May 09 at 19:50) emartinson

Using the same code with the 9.5.0.67 preview, neither .LoadBodyFromFile or .StreamBodyFromFile failed. Also tried on the original application and the code form the question above no longer explodes.

(May 09 at 20:07) emartinson

Thanks Erik!

(May 11 at 21:47) chilkat ♦♦
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or __italic__
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×203
×15
×6

Asked: Apr 07 at 17:17

Seen: 294 times

Last updated: May 11 at 21:47

powered by OSQA