Sharepoint through Microsoft Graph API - PDF Upload is Corrupted - pdf

I'm trying to upload a PDF binary to Sharepoint in both string and Buffer format:
GET /v1.0/sites/site_url/drives/drive_id/items/root:/test.pdf:/content
Content-Type: application/pdf
Authorization: Bearer x
body: < fileContents >
case 1: fileContents = {type: Buffer, content: <32 12 32>}
case 2: fileContents = '%PDF-1.7\n' +....
Both cases result in corrupted files within Sharepoint.
Successfully uploads from Postman when attaching a pdf as binary.
Is there a formatting step that i could be missing?
Thanks

Related

Parse multipart/form-data response in rust / reqwest

I'm relatively new to rust and using reqwest to fetch a PDF document from a REST API endpoint. The content-type of the response is multipart/form-data; boundary=bc1f6465-6738-4b46-9d9d-b9ae36afa8cb with two parts:
--bc1f6465-6738-4b46-9d9d-b9ae36afa8cb
Content-Disposition: form-data; name="metadata"
Content-Type: application/json
{"documentId":"QkNfRENfSUwwMDEsRTA1OEU3ODQtMDAwMC1DNzY5LTg1MjktMTRFRkI5RTBFNjRF"}
--bc1f6465-6738-4b46-9d9d-b9ae36afa8cb
Content-Disposition: form-data; name="document"; filename=document.pdf
Content-Type: application/pdf
%PDF-1.4
<binary content>
%%EOF
--bc1f6465-6738-4b46-9d9d-b9ae36afa8cb--
I want now to save the PDF document in the 2nd part as a valid PDF file on disk. But the multipart functionality within reqwest seems to create new multipart requests whereas I need to parse a multipart response.
My code to download the file:
use reqwest::{self, header::AUTHORIZATION};
fn main() {
let url = "https://example.com/rest/document/123";
let authorization_header = String::from("Bearer ") + access_token.as_str();
let res = client.get(url)
.header(AUTHORIZATION, &authorization_header)
.send()
.expect("Error calling API");
}
Any hint on how to process the multipart/form-data response is appreciated!

Spark Java - strange behavior when uploading files

In my project I want to try to upload files, here is the part of the code responsible for this:
MultipartConfigElement multipartConfigElement =
new MultipartConfigElement(
"/tmp_files",
avatarSize,
avatarSize,
1024
);
request.raw().setAttribute(
"org.eclipse.jetty.multipartConfig",
multipartConfigElement
);
Part uploadedFile = request.raw().getPart("file");
And a request to upload a file using Idea's http client:
POST http://localhost:8080/users/me/avatar
Content-Type: multipart/form-data; boundary=abcd
Authorization: Bearer {{authToken}}
--abcd
Content-Disposition: form-data; name="file"; filename="test.png"
< /Users/user1/resources/test.png
--abcd--
where test.png is a regular picture.
But when I try to load in this code place:
Part uploadedFile = request.raw().getPart("file");
I get an error:
java.nio.file.NoSuchFileException: /tmp_files/MultiPart11851484240893602177
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218)
at java.base/java.nio.file.Files.newByteChannel(Files.java:375)
at java.base/java.nio.file.Files.createFile(Files.java:652)
It can be assumed that this error is due to the fact that there are no write permissions to the root of the file system (I'm testing on mac os, under the user).
But if i try to upload another file - which is just a zip file then everything works.
POST http://{{host}}/users/me/avatar
Content-Type: multipart/form-data; boundary=abcd
Authorization: Bearer {{authToken}}
--abcd
Content-Disposition: form-data; name="file"; filename="file123.zip"
< /Users/18493151/develop/icandev/api-gateway/src/main/resources/file123.zip
--abcd--
and no exception in this line:
Part uploadedFile = request.raw().getPart("file");
Why is this happening? Why does the result depend on the file type?
sparkjava version 2.9.4

Pdf file uploaded using JMeter but the content is missing in that pdf file means file gets corrupted

I need to upload a pdf file through backend API using JMeter. So for that, I passed a multipart API request. To upload the file I am using BeanShell Preprocessor.
FileInputStream in = new FileInputStream("C:\\Users\\XYZ\\Downloads\\PT_003.pdf");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int i; (i = in.read(buffer)) != -1; ) {
bos.write(buffer, 0, i);
}
in.close();
byte[] binarydata = bos.toByteArray();
bos.close();
vars.put("binarydata", new String(binarydata));
Multipart Request Body :
--AaC07x
Content-Type: application/json; charset=utf-8
{
"token":"a6b8J000000055JQPU",
"flow":"Development"
}
--AaC07x
content-disposition: form-data; name="File"; filename="PT_003.pdf"
Content-Type: application/pdf
Content-Transfer-Encoding: bytecode
${binarydata}
--AaC07x--
Header Manager:-
Content-Type multipart/related;boundary="AaC07x"
File uploaded but content in that pdf file is missing means when I tried to open the uploaded pdf file it's blank/corrupted.
So can you please anyone help me to fix that issue??
It looks like your byte array to string conversion is the problem. Moreover as per JMeter 5.5 you cannot simply send a byte array using HTTP Request sampler as given you put everything into "Body Data" tab it will be treated as a String
Since JMeter 3.1 you should avoid using Beanshell, the recommended scripting language is Groovy
If you have problems coming up with a proper request definition you can just record it using HTTP(S) Test Script Recorder, just make sure that your PT_003.pdf is in JMeter's "bin" folder during both recording and replay

Posting PDF file with form-data: corrupted file?

I'm trying to upload a pdf file with form-data to a server. The upload works but the file gets corrupted for some reason (I can't open the uploaded version). Here's my code:
post_url = 'https://myposturl'
headers = {
'Content-Type':'multipart/form-data; charset=UTF-8; boundary=MyBoundary'
}
with open('./myfile.pdf', 'rb') as f:
body = f'--MyBoundary\r\nContent-Disposition: form-data; name="file"; filename="myfile.pdf"\r\nContent-Type: application/pdf\r\n\r\n{f.read()}\r\n--MyBoundary--\r\n'
res = s.post(post_url, headers = headers, data = body)
I thought it was coming from the \r\n, I tried a replace('\n', '\r\n') on the f.read() output but it didn't work.
Also, when using https://httpbin.org to check the POST request, I get \\\\r\\\\n for each new line in the pdf binary data. I'm wondering if this is normal, maybe that could help.
Thank you in advance for your suggestions.
With requests it can be done a bit easier.
import requests
post_url = 'https://myposturl'
files = {'file': open('./myfile.pdf', 'rb')}
r = requests.post(post_url, files=files)
More docs.
The reason you get corrupted file is probably because you're setting headers and body manually. requests usually sets theses things implicitly, so you should not break this concept and follow official guides.

Sending binary data using multipart/form-data from a worker with IE11

I'm trying to send a multipart/form-data from a worker with IE. I've already done it with Chrome, Firefox, Safari using formData objects (not supported IE, I need a manual one)
The binary data I'm sending is a crypto-js encrypted data. With formData objects I do:
var enc = new Buffer(encrypted.ciphertext.toString(CryptoJS.enc.Base64), 'base64');
formData.append("userFile" , new Blob([finalEncrypted], {type: 'application/octet-binary'}), 'encrypted')
this works fine generating a multipart like this(missed some parts of it):
request headers:
Accept:*/*
Accept-Encoding:gzip, deflate
Cache-Control:no-cache
Connection:keep-alive
Content-Length:30194
Content-Type:multipart/form-data; boundary=WebKitFormBoundary0.gjepwugw5cy58kt9
body:
--WebKitFormBoundary0.gjepwugw5cy58kt9
Content-Disposition: form-data; name="userFile"; filename="encrypted"
Content-Type: binary
all binary data
--WebKitFormBoundary0.cpe3c80eodgc766r--
With the manual multipart/form-data:
IE11 doesn't accept readAsBinaryString(deprecated)
I would like to avoid sending base64 encoded data(readAsDataURL)(33% payload)
The binary data I'm sending is a crypto-js encrypted data.
I'm trying:
finalEncrypted = new Buffer(encrypted.ciphertext.toString(CryptoJS.enc.Base64), 'base64');
then in my manual multipart I tried to convert the buffer to a binary string:
item.toString('binary')
the multipart result looks looks this:
--WebKitFormBoundary642013568702052
Content-Disposition: form-data; name="userfile"; filename="encrypted"
Content-Type: binary
all binary data
ÐçÀôpRö3§]g7,UOÂmR¤¼ÚS"Ê÷UcíMÆÎÚà/,hy¼øsËÂú#WcGvºÆÞ²i¨¬Ç~÷®}éá?'é·J]þ3«áEÁÞ,4üBçðºÇª bUÈú4
T\Ãõ=òEnýR _[1J\O-ïǹ C¨\Ûøü^%éÓÁóJNÓï¹LsXâx>\aÁV×Þ^÷·{|­'
On the .NET server we check the hash calculated on client versus calculated on server. Server reply that hashes doesn't match. This makes me think that I'm not sending the file correctly.
It looks like you did not yet get a solution, at least you did not post it here if you had one.
On my end I use jQuery which handles the low level nitty gritty of the actual post.
It may be that you are doing one small thing wrong and IE fails on it. Since you do not show what you used with FormData. It is rather difficult to see whether you had a mistake in there.
// step 1. setup POST data
var data = new FormData();
data.append("some_variable_name", "value_for_that_variable");
data.append("some_blob_var_name", my_blob);
data.append("some_file_var_name", my_file);
// step 2. options
var ajax_options =
{
method: "POST",
processData: false,
data: data,
contentType: false,
error: function(jqxhr, result_status, error_msg)
{
// react on errors
},
success: function(data, result_status, jqxhr)
{
// react on success
},
complete: function(jqxhr, result_status)
{
// react on completion (after error/success callbacks)
},
dataType: "xml" // server is expected to return XML only
};
// step 3. send
jQuery.ajax(uri, ajax_options);
Step 1.
Create a FormData object and fills the form data, that includes variables and files. You may even add blobs (JavaScript objects, will be transformed to JSON if I'm correct.)
Step 2.
Create an ajax_options object to your liking. Although here I show your the method, processData, data, contentType as they must be in case you want to send a FormData. At least, that works for me... It may be possible to change some of those values.
The dataType should be set to whatever type you expect in return.
Step 3.
Send the request using the ajax() function from the jQuery library. It will build the proper header and results as required for the client's browser.