1. Jeff Wayt
  2. PowerBuilder
  3. Wednesday, 3 October 2018 22:04 PM UTC

I'm trying to imbed a binary zip file as an attachment in a post to a RESTful service using the httpclient in Appeon 2017 R3. I read the file into a blob and then have to convert it into a string for the body, so it looks like:
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="attachment"; filename="emanif_3552785JJK.zip"
Content-Type: application/x-zip-compressed

(binary string for zip goes here)
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Powerbuilder code then looks like:

    ls_raw += CRLF+'Content-Disposition: form-data; name="attachment"; filename="'+ ls_fname_in_zip+'"'+ &
            CRLF+'Content-Type: application/x-zip-compressed; charset=utf-8' + &
            CRLF+CRLF+ &
            String(iblb_data, EncodingUTF8!) + &
            CRLF+'--'+CS_BOUNDARY_FORM+'--'+CRLF

When the service parses this out, it extracts the string as a zip and tries to extract the file in the zip. Then it replies the zip file is corrupt. If I do not use EncodingUTF8!, it tells me it needs a zip file, not recognizing it.

I suspect that the string function is dropping the first characters. The help file says, "If the file is an ANSI or UTF-8 file and is read into a blob, FileReadEx saves the contents of the file with no conversion. The BOM is not written to the blob in text mode, but it is written to the blob in stream mode.

If the blob has a byte-order mark (BOM), String filters it out automatically."

So I'm thinking the string I use may be missing the BOM and I need to supply it. When I do, it no longer sees it as a proper file.

What am I missing?

Accepted Answer
Brad Mettee Accepted Answer Pending Moderation
  1. Friday, 5 October 2018 14:23 PM UTC
  2. PowerBuilder
  3. # Permalink

Looking at the code, a couple things look like they might be causing issues.

1. Charset on the application/x-zip-compressed line does not appear on an upload I've been testing with (and watching using MS NetMon tool). Try removing it entirely.

2. Applying UTF-8 encoding to a zip file on blobedit will likely corrupt the zip data. Remove the encoding type parameter (it's optional).

Here's a sample upload with 3 data fields and a zip file

Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydDoNGjcXBjKMewps

------WebKitFormBoundarydDoNGjcXBjKMewps
Content-Disposition: form-data; name="name"

fulldump.zip
------WebKitFormBoundarydDoNGjcXBjKMewps
Content-Disposition: form-data; name="action"

upload-attachment
------WebKitFormBoundarydDoNGjcXBjKMewps
Content-Disposition: form-data; name="_data_key"

583b293f01
------WebKitFormBoundarydDoNGjcXBjKMewps
Content-Disposition: form-data; name="async-upload"; filename="testdump.zip"
Content-Type: application/x-zip-compressed




------WebKitFormBoundarydDoNGjcXBjKMewps--

Hope this helps.

Comment
  1. Jeff Wayt
  2. Saturday, 6 October 2018 21:02 PM UTC
Brad, this does help! I removed the charset UTF-8 from the section header and it worked!!! :D
  1. Helpful
  1. Jeff Wayt
  2. Saturday, 6 October 2018 21:03 PM UTC
Thank you.
  1. Helpful
There are no comments made yet.
René Ullrich Accepted Answer Pending Moderation
  1. Thursday, 4 October 2018 05:19 AM UTC
  2. PowerBuilder
  3. # 1

I think you should build a blob instead of a string to send (lblob_raw). So you don't have any conversion issues from blob to string.

Comment
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Thursday, 4 October 2018 13:19 PM UTC
  2. PowerBuilder
  3. # 2
Comment
There are no comments made yet.
Jeff Wayt Accepted Answer Pending Moderation
  1. Thursday, 4 October 2018 14:01 PM UTC
  2. PowerBuilder
  3. # 3

Chris, thanks for the reply.
This is what I expected to do initially. I discussed this with the service programmer on the server-end, and he said they thought about it and decided to stay with binary. Let's say he's wrong and I want to base64 it. Do I need to advertise the encoding so the server will know to decode it on its end?

I hope to see you at Elevate this year!

Comment
  1. Chris Pollach @Appeon
  2. Thursday, 4 October 2018 15:03 PM UTC
Hi Jeff;



If you are using the HTTP transport protocol ... all binary transmissions must adhere to Base64 otherwise HTTP would not be able to handle the data stream. It should be obvious to the service developer that any binary data included in a an XML or JSON schema would be in that format and thus, decoding would be necessary. An exception to that for example would be if you decided to use FTP instead (or straight TCP/IP for that matter).



Yes, I will be there at the Elevate 2018 conference. I have 9 presentations to do plus help with the Key note. ;-)



Regards ... Chris
  1. Helpful
  1. Jeff Wayt
  2. Thursday, 4 October 2018 20:52 PM UTC
A bit of research seems to say BASE64 hasn't been needed in HTTP for some time. SMTP, yes; HTTP no. Also, others are POSTing with binary attachments. I tried declaring Content-Transfer-Encoding: BINARY in the boundary header to be gentlemanly, but it doesn't help. The stringified blob parses okay, but their server complains the zip is corrupt. :(
  1. Helpful
There are no comments made yet.
Jeff Wayt Accepted Answer Pending Moderation
  1. Thursday, 4 October 2018 15:25 PM UTC
  2. PowerBuilder
  3. # 4

Rene, thanks for your reply. I thought it was a great suggestion.
To use a blob, my mix of strings and blobs requires BlobEdit. The first time I use it I get a NULL in the returned unsigned long:

ulong     ll_length
string    is_body, ls_raw, ls_fname_in_zip
blob      lblob_body, iblb_data //zip file read into blob

// Prepare strings and append them to the blob
ls_raw = CRLF+'--'+CS_BOUNDARY_FORM+CRLF+&
            'Content-Disposition: form-data; name="manifest"'+CRLF+CRLF+ &
            is_body + &
            CRLF+'--'+CS_BOUNDARY_FORM
lblob_body = Blob(ls_raw, EncodingUTF8!)
ll_length = LEN(ls_raw) + 2    //both blob and string measure 1602 characters. Help says add 2 for strings.

ls_fname_in_zip = "my_PDF.ZIP"
ls_raw = CRLF+'Content-Disposition: form-data; name="attachment"; filename="'+ ls_fname_in_zip+'"'+ &
        CRLF+'Content-Type: application/x-zip-compressed; charset=utf-8' + &
        CRLF+CRLF
ll_length = BlobEdit ( lblob_body, ll_length, ls_raw , EncodingUTF8! )
// ll_length is NULL !?!
ll_length = BlobEdit ( lblob_body, ll_length, iblb_data, EncodingUTF8! )
[...]

Comment
  1. René Ullrich
  2. Friday, 5 October 2018 05:24 AM UTC
Hi Jeff,

if you use BlobEdit you need a blob that have enough space to copy the data. The return value will be NULL as in you case if there is not enough space in the blob.

This should work:

lblob_body = lblob_body + Blob (ls_raw, EcodingUTF8!) + iblb_data
  1. Helpful
  1. Jeff Wayt
  2. Friday, 5 October 2018 10:49 AM UTC
Rene, I hit upon this simple concatenation of blobs, too. These zips were small, ~50K, nowhere near any size limit. Sending the resulting blob in the body did worse than the string, the server complaining it was malformed.



This really feels like "Green Eggs and Ham."
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.