function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
HirenHiren 

RESTful Call out, base64Encode of file corrupted

Hi,

I am doing a RESTful call out (Mime infact, POST). My schedule job will periodically send files/attachments to the client's (.NET) server. I am able to send any plain text data to them correctly but when I send an base64Encoded attachement using EncodingUtil.base64Encode(). Their application is not able to decode it, it says the image/document is corrupted. 

 

I also noted that for an image of 103kb, the base64 encoded string is just 73kb. Base64 is suppose to be larger than the original size correct? So, am I missing something here?

 

Another thing I noticed is that the documentation for EncodingUtil.base64Encode() says it Converts a Blob to an unencoded String representing its normal form. (check here for documentation). What does it mean 'unencoded'. Is that the issue? how to resolve this then?

SuperfellSuperfell

What's your code look like?

HirenHiren

There are several triggers and custom objects involved so difficult to paste the whole code here but  even a simple 

 

EncodingUtil.base64Encode(cv.versionData);

 

(where cv is a ContentVersion record), does not return a valid base64 string.

 

EDIT: I have tested with 3 images till now, it return valid base64 string for 1, but not for the other 2.

SuperfellSuperfell

really need to see how you get the conventVersion record, and how you setup the http request object.

 

Also, you do know that there's no need to base64 encode it, you can send binary data over http. (unless this is a requirement for the server)

HirenHiren

It errors out saying 'BLOB is not a valid UTF-8 string' if I send it without encoding it.
--------
My code is something like this, Note this code is absolutely not compilable. I have modified it to be more readable and to protect the confidentialty of a client

string blobData;
String dataToSend='MIME-Version: 1.0 Content-Type: multipart/mixed; boundary=xxxxxxBOUNDARYxxxxxxx --xxxxxxBOUNDARYxxxxxxx Content-Type: application/[privateType]Content-Disposition: attachment;filename=a04d0000002s1spAAA;name=file; <meta-document version="1.8"> [XML DOC] </meta-document> --xxxxxxBOUNDARYxxxxxxx Content-Type: base64 Content-Disposition: attachment;filename=a04d0000002s1spAAA/068d0000000Fa2VAAS;name=file; ';

 

List<FeedItem> posts = [Select Type__c, Title, SystemModstamp, RelatedRecord__c, RelatedRecordId__c, Parent_Object__c, ParentObjectType__c, ParentId__c, OwnerId, Name, LinkUrl__c, LastModifiedDate, LastModifiedById, IsDeleted, Inserted_By__c, Id, GroupName__c, Id, Created_By__c, CreatedDate__c, CreatedDate, CreatedById, ContentType__c, ContentSize__c, ContentFileName__c, ContentDescription__c, CommentCount__c, Chatter_Record__c, Body__c From FeedItem where sentToclient__c = false order by LastModifiedDate desc];

 

for(FeedItem post: posts)
{
//WebServiceUtils is a private library
if(WebServiceUtils.HasAttachmentLessThan3MB(post))
{
ContentDocument cad = [select ContentSize,VersionId from ContentDocument where RelatedToId__c = :post.Id];
ContentVersion cv = [select versionData from contentVersion where Id = :cad.VersionId__c];
blobData = EncodingUtil.base64Encode(cv.versionData);
break;
}
}


dataToSend+=blobData;

Cookie tempCookie = ApexPages.currentPage().getCookies().get('testProjectCookie');
HttpRequest req = new HttpRequest();
Http http = new Http();
HTTPResponse res;
req.setMethod('POST');
req.setHeader('Accept', '*/*');
req.setHeader('Content-Type', dataType);
req.setEndpoint(url + '?oauth_token=' + tempToken);
req.setBody(dataToSend);

 

res = http.send(req); 

 

 

Does it make sense?

 

Best,

Hiren

 

SudoNhimSudoNhim

Currently dealing with this exact problem, to narrow it down I will provide the details at my end:

 

  • Problem occurs when sending a PNG image encoded in Base64 from a javascript page back to my Python webserver
  • Problem occurs on every image that exceeds 73 KB, to see the effect check out the gallery at http://sudonhim.net (more complex images are only partially there)
  • Problem is server-side (recieving)
  • Interestingly, when the server is running on Windows the data is clipped at a few hundred KB, wheras on linux running exactly the same packages the data is clipped to 73 KB
  • Moving the framework to a different server makes no difference (site is using the bottle microframework, switching from bottle's to server to CherryPyServer made no difference)

I am using the Base64 decoder in Python's string library.

Only just discovered this problem, will update if I find more info/solution.

Seeing as you posted a week ago, if you have since found the solution, could you please share?

 

Thanks

 

EDIT: Problem solved, turned out to be a bug within bottle (the web microframework) - the fix was to use an older version  change the memory limit for requests. In bottle this meant setting bottle.BaseRequest.MEMFILE_LIMIT to a much higher value after import.

HirenHiren

What was the bug in your case?

 

In my case it resolved itself.  I tested it again after 2-3 days and everything started working and has been working since then.

SudoNhimSudoNhim

The bug in my case was actually with the older version of the software.

 

As the web framework was intended for small, generic applications; by default there was a low limit on the amount of memory that a request was allowed to take up (102400 bytes). This was to stop erroneous or malicious requests from using large amounts of memory. The idea was that if anybody needed more memory than this, they could monkeypatch the BaseRequest class to increase this limit. (I don't know why hitting the limit truncuates it rather than raising an error).

However.

In the older version there was a bug that meant that this limit wasn't actually enforced on requests for form data, hence why my code only broke with the new version.

 

The correct action was to use the latest version, but adjust the internal request memory limit.