question

LanceM-0566 avatar image
0 Votes"
LanceM-0566 asked MichaelHan-MSFT commented

Sharepoint API docx upload not working

Hi there,

I understand that PHP is not the direction of this forum, but I am hoping to find some clues to solving my problem here.

I am using PHP to make a rest api call to sharepoint 2019, and it is working successfully for .pdf and .txt file types, but not .doc and .docx types. I am receiving errors such as:

"Word found unreadable content in {filename}.docx". Do you want to recover the contents of this document? If you trust the source of this document, click yes."

If I click yes it opens the file and it seems to work.

Below is a raw output of the request I am making. I think I am having issues with my file encoding, but am not sure what is required for .docx to successfully make it to the sharepoint server

POST {sharepointsite}/_api/web/lists/getbytitle('{documentlibary}')/rootfolder/files/add(url='{filename}.docx',overwrite=true)
HTTP/1.1
Host: {redacted}
Accept: application/json; odata=verbose
Cache-Control: no-cache
X-RequestDigest: {redacted}
Authorization: {redacted}
Connection: Keep-Alive
Request-Id: {redacted}
Content-Type: multipart/form-data; boundary=----------637571310612295910
Content-Length: 12184

------------637571310612295910
Content-Disposition: form-data; name="uploaded_file"; filename="{filename}.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document

{body data}

office-sharepoint-server-customization
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

LanceM-0566 avatar image
0 Votes"
LanceM-0566 answered MichaelHan-MSFT commented

Well after much experimentation and searching I figured out the answer for this problem. The biggest culprit is indeed the content type. If you use the following code:

$data = array(
'uploaded_file' => curl_file_create($local_file['tmp_name'], $local_file['type'], $fileName)
);
/// redacted for space
CURLOPT_POSTFIELDS=> $data,
curl will automatically strip out any content-type you give it and supply its own. you get the following headers:

Content-Type: multipart/form-data; boundary=----------637571310612295910
Content-Length: 12184

------------637571310612295910
Content-Disposition: form-data; name="uploaded_file"; filename="{filename}.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document

Sharepoint does not like this at all. So, you need to send binary data, not multipart/form-data. This can be achieved like so:

$uploadFile = file_get_contents($local_file['tmp_name']);
$curl = curl_init();

         curl_setopt_array($curl, array(
           CURLOPT_URL => $client_upload_url,
           CURLOPT_RETURNTRANSFER => true,
           CURLOPT_ENCODING => "",
           CURLOPT_MAXREDIRS => 10,
           CURLOPT_TIMEOUT => 30,
           CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_NONE ,
           CURLOPT_CUSTOMREQUEST => "POST",
         CURLOPT_POSTFIELDS=> $uploadFile, //<-- where the magic happens

           CURLOPT_HTTPHEADER => array(
             "Accept: application/json;odata=verbose",
             "cache-control: no-cache",
             "X-RequestDigest: " . $digest_value,
             "Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document",//

             "Authorization: {values}
           ),
         ));

This will net you a result like follows

Accept: application/json; odata=verbose
Cache-Control: no-cache
X-RequestDigest:{redacted}
Authorization: {redacted}
Connection: Keep-Alive
Request-Id: |1bf3eca4-45702011fc30c20b.2.
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Length: 11947

{raw body here, not multipart/formdata}

moral of the story is file_get_contents will get you the binary data as a string. Which you can dump directly in the CURLOPT_POSTFIELDS.

The inspiration for this was astonishingly from a post from 2008 found here

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@LanceM-0566,

Glad that you found the solution. Thanks for your sharing. You could accept your answer via the "Accept Answer" button, it would be helpful to others who have similar issues in the future.

0 Votes 0 ·