Been having some difficulty with an attachment issue on my site. At the moment our iOS app is pointing at an API endpoint for attachments, and sending a request similar to this:
POST /api/v2/attachments HTTP/1.1
--Boundary+0xAbCdEfGbOuNdArY
Content-Disposition: form-data; name="attachment"; filename="attachment.jpg"
Content-Type: image/jpeg
...image data...
--Boundary+0xAbCdEfGbOuNdArY--
Now, the request succeeds and the image is in fact uploaded, but it's turning out to be an invalid image because the boundary data is written to file. It basically looks like this:
file = Tempfile.new('attachment')
attachment_data = request.body.read
attachment_data.force_encoding('UTF-8')
file << attachment_data
attachment.asset = file
attachment.save!
Obviously request.body.read is including the entire request, Boundaries and all. We do actually have a stripping method that runs through each line of the file and strips out non-image data, but that's obviously not performant at all.
In an ideal world, we would just be getting the image data itself and using that to populate the tempfile, but I'm afraid I'm completely stumped about the best way to go about that.
Thoughts welcome. Thank you!
Related
I have a COBOL batch program where I am able to send mail notification to an ID once my job is complete however, I also want to add an attachment in the mail of the processed file.
The following code attaches another mail as an attachment.
HELO SANTAANA
MAIL FROM:<abc#somting.com>
RCPT TO:<abc#something.com>
DATA
From: LandT P2P - LO <abc#something.com>
To: abc#something.com
Subject: File processed - Price_Change_10-27-15 07-08-44
MIME-VERSION: 1.0
CONTENT-TYPE: MULTIPART/MIXED;name="Price_Change_10-27-15.csv"
CONTENT-DISPOSITION: ATTACHMENT;
FILENAME="Price_Change_10-27-15 07-08-44.csv"
Note: I have also tried using SMTP and still does not work
Here is the sample of the mail i receive on running this code.
If you are generating the text of the email from within your Cobol program, which it sounds like, you would need to append another section, specify the Content-Type and Content-Disposition, filename and encoding, and then follow it with the properly encoded data, similar to this:
Content-Type: application/xml; name="Price_Change_10-27-15 07-08-44"
Content-Disposition: attachment; filename="Price_Change_10-27-15 07-08-44"
Content-Transfer-Encoding: base64
UEsDBBQABgAIAAAAIQDfrfoCnAEAAEcGAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAAC
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
... and so on ...
I did notice that you had the content of those tags in upper case, that might be a problem. RFC1341 specifies those as "multipart/mixed" and "attachment" and so on. It is possible that your lack of mixed case is messing you up.
CONTENT-TYPE: MULTIPART/MIXED;name="Price_Change_10-27-15.csv"
CONTENT-DISPOSITION: ATTACHMENT;
FILENAME
Even easier than generating your own, have you looked into the excellent XMITIP package by Lyonel B. Dyck, it manages all that for you and you write a few config arms to control it, and you can easily call it from a Cobol program just like any other Rexx. Or you could add it to the end of your job stream as a separate step and make the task really easy.
I'm trying to post a jpeg file to a locally developed web service via Fiddler. This would be simple enough, but I also need to include some data alongside the file and can’t quite nail the syntax that fiddler wants. If I click the upload file button and select a file to upload, it replaces my POST body with:
---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="PantheraLeo.jpg"
Content-Type: image/jpeg
<#INCLUDE *C:\temp\PantheraLeo.jpg*#>
---------------------------acebdf13572468—
Now I want to add some additional data:
user=1&album=2&photo=[OUTPUT FROM FILE UPLOAD]
I’ve tried putting this at the start of the body, but when my Node app receives the request, I’m getting a user parameter, an album parameter but no photo.
Any ideas on how I could format this request to get both parameters and the photo uploaded as the photo parameter?
I've also been looking to do something similar myself and stumbled on your question. I've just managed to achieve what I needed after a bit of messing about with Fiddler. Try this:
---------------------------acebdf13572468
Content-Disposition: form-data; name="model"
MyModelInfo
---------------------------acebdf13572468
Content-Disposition: form-data; model="test123"; filename="123.gif"
Content-Type: image/gif
<#INCLUDE *Z:\Downloads\123.gif*#>
---------------------------acebdf13572468--
It would seem that you link the form data being sent up in your request body to the 'acebdf13572468' boundary in the POST info. Provide the Content-Disposition with a key name (in my case 'model') and then the following line represents your actual value for this key. (In my case "MyModelInfo".
Using the above request body I was able to POST up a file as well as some accompanying POST data to my API.
The accepted answer works well. But be warned the extra line after MyModelInfo comes through into the string. Also when copying and pasting in and out of fiddler some lines were corrupted breaking the file.
Note I have named the file param "file" in the fiddler body and in the receiving API function.
This works for me:
---------------------------acebdf13572468
Content-Disposition: form-data; name="PARAM1"
Some text with a line before but not after
---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; filename="filename.jpg"
Content-Type: image/jpeg
<#INCLUDE *C:\local\filename.jpg*#>
---------------------------acebdf13572468--
The data can be received in .net core 2 like this:
[HttpPost]
[Route("AddImage")]
public async System.Threading.Tasks.Task<IActionResult> AddImageAsync(IFormFile file)
{
//f is the same as file
//var f = Request.Form.Files.Count > 0 ? Request.Form.Files[0] : null;
//useful to check the keys
//var additionalProperties = Request.Form.Keys;
if (file != null)
{
try
{
if (Request.Form.TryGetValue("PARAM1", out StringValues p1))
{
var txt = p1.ToString():
Hello this is my first post on this site.
Now i encountered a strange problem with MIME. I am working on writing emlx mail files.
(objective c, cocoa)
now i have no problem with showing images in mails. the problems is that half of my .doc and pdf attachments don't show in the message.
An formatting example.
MessageLength in Bytes(i.e 8556)
From: some#email
To: some#email2
Subject: mailsubject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="somerandomgeneratedstring"
--somerandomgeneratedstring
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Body Text(not html body)
--somerandomgeneratedstring
Content-Type: application/msword; name="somefile.doc"
Content-Disposition: attachment; filename="somefile.doc"
Content-Transfer-Encoding: base64
[base64 encoded data]
--somerandomgeneratedstring--
PlistStructure
The text body is always displayed properly. The problem is that some text file attachments like .doc and pdf are not displayed, i run the same code for multiple text files and some work and some do not i have no clue why. all pictures work.
The thing i don't get is if i use the same data that wont work for MIME and write is as a file to my desktop the file is displayed properly.
Is there something i am missing ? Is there something i have to take care of when encoding such files in base64 ? if so why do some files work and others dont ?(source is in binary format, i encode is using nsdata base64encoding in Xcode)
I have gone trough the mime documentation multiple times and i cant seem so find a solution.
Can anyone please give me some tips or suggestions ?
EDIT: omg i forgot about this, The problem was that i had a problem with the first line, length in bytes, after i fixed that it worked. Sorry for wasting time :(
You need to get rid of the blank line between the top-level MIME-Version and Content-Type headers. MIME headers and body are separated by a blank line, so your Content-Type is effectively ignored as a header and treated as body content instead.
From: some#email
To: some#email2
Subject: mailsubject
MIME-Version: 1.0
<-- get rid of this blank line
Content-Type: multipart/mixed; boundary="somerandomgeneratedstring"
Update: since this problem is not a factor anymore, the only remaining factor you have not shown yet is the actual base64 data. It is likely malformed in some way that is preventing proper decoding. Everything else you have shown is accurate.
I'm trying out http requests to download a pdf file from google docs using google document list API and OAuth 1.0. I'm not using any external api for oauth or google docs.
Following the documentation, I obtained download URL for the pdf which works fine when placed in a browser.
According to documentation I should send a request that looks like this:
GET https://doc-04-20-docs.googleusercontent.com/docs/secure/m7an0emtau/WJm12345/YzI2Y2ExYWVm?h=16655626&e=download&gd=true
However, the download URL has something funny going on with the paremeters, it looks like this:
https://doc-00-00-docs.googleusercontent.com/docs/securesc/5ud8e...tMzQ?h=15287211447292764666&\;e=download&\;gd=true
(in the url '&\;' is actually without '\' but I put it here in the post to avoid escaping it as '&').
So what is the case here; do I have 3 parameters h,e,gd or do I have one parameter h with value 15287211447292764666&ae=download&gd=true, or maybe I have the following 3 param-value pairs: h = 15287211447292764666, amp;e = download, amp;gd = true (which I think is the case and it seems like a bug)?
In order to form a proper http request I need to know exectly what are the parameters names and values, however the download URL I have is confusing. Moreover, if the params names are h,amp;e and amp;gd, is the request containing those params valid for obtaining file content (if not it seems like a bug).
I didn't have problems downloading and uploading documents (msword docs) and my scope for downloading a file is correct.
I experimented with different requests a lot. When I treat the 3 parameters (h,e,gd) separetaly I get Unauthorized 401. If I assume that I have only one parameter - h with value 15287211447292764666&ae=download&gd=true I get 500 Internal Server Error (google api states: 'An unexpected error has occurred in the API.','If the problem persists, please post in the forum.').
If I don't put any paremeters at all or I put 3 parameters -h,amp;e,amp;gd, I get 302 Found. I tried following the redirections sending more requests but I still couldn't get the actual pdf content. I also experimented in OAuth Playground and it seems it's not working as it's supposed to neither. Sending get request in OAuth with the download URL responds with 302 Found instead of responding with the PDF content.
What is going on here? How can I obtain the pdf content in a response? Please help.
I have experimented same issue with oAuth2 (error 401).
Solved by inserting the oAuth2 token in request header and not in URL.
I have replaced &access_token=<token> in the URL by setRequestHeader("Authorization", "Bearer <token>" )
We have a function in our Rails code that accepts a JSON POST body:
contacts = ActiveSupport::JSON.decode(request.raw_post.gsub("+", ""))
(I'm aware that I can get this from params["_json"] as well, but we have extremely large (MBs) POST bodies that do not get put into params["_json"] for some reason (and + throws errors too).
Since the JSON is usually sent from a mobile client, it's important to us to optimize the upload size. We want to switch to having the POST body gzipped.
However, no matter what we do, we get the same error with no line number:
MultiJson::DecodeError (743: unexpected token at ''):
We have tried:
gzipped_contacts = Zlib::GzipReader.new(StringIO.new(request.raw_post)).read
contacts = ActiveSupport::JSON.decode(gzipped_contacts.gsub("+", ""))
This:
gzipped_contacts = ActiveSupport::Gzip.decompress(request.raw_post)
contacts = ActiveSupport::JSON.decode(gzipped_contacts.gsub("+", ""))
And the solution found here: Rails: how to unzip a compressed xml request body?
I'm pretty sure this is not occurring at the controller level because I can't log anything there, so it needs to be done in the middleware or at the server (but I can't find anything for Nginx that lets us deflate). Please assist!
Ok, turns out the iPhone client was sending the wrong headers. So the solution for anyone encountering this is to see the advice here:
Rails: how to unzip a compressed xml request body?
And verify that you are sending Content-Type: gzip/json.