Join/attach file to message

Have a great idea for extending Zimbra? Share ideas, ask questions, contribute, and get feedback.
Post Reply
sfa
Posts: 2
Joined: Wed Jun 17, 2020 6:47 pm

Join/attach file to message

Post by sfa »

Hello !

I use Zimbra and PHP (JSON syntax). I can read and send messages. Now I need to send tiny attachments.

I try to embed a text/plain file "myfile.txt" containing "File contents" in a multipart message :

Code: Select all

$request = [
    'Header' => [...],
    'Body' => [
        'SendMsgRequest' => [
            '_jsns' => 'urn:zimbraMail',
            'm' => [
                'e' => $addresses,
                'su' => 'TEST-1',
                'mp' => [
                    'part' => '',
                    'ct' => 'multipart/mixed',
                    'mp' => [
                        [
                            'part' => '1',
                            'body' => '1',
                            'ct' => 'text/plain',
                            'content' => ['_content' => 'Hi!'],
                        ],
                        [
                            'part' => '2',
                            'body' => '0',
                            'ct' => 'text/plain',
                            'name' => 'myfile.txt',
                            'cd' => 'attachment',
                            'filename' => 'myfile.txt',
                            's' => 13,
                            'content' => ['_content' => 'File contents'],
                        ],
                    ],
                ],
            ],
        ],
    ],
];
The obtained message is :

Code: Select all

Hi!
File contents
And following header :

Code: Select all

...
Subject: TEST-1
MIME-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="=_e03072ec-cdb8-443b-aa24-7208cd8fa9af"
X-Mailer: Zimbra 8.8.12_GA_3803 (ZCS/8.8.12_GA_3803)
Thread-Index: TeB6i6zeScSySN7rfX+5ZnWNokVzGQ==
Thread-Topic: TEST-1

--=_e03072ec-cdb8-443b-aa24-7208cd8fa9af
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

Hi!
--=_e03072ec-cdb8-443b-aa24-7208cd8fa9af
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

File contents
--=_e03072ec-cdb8-443b-aa24-7208cd8fa9af--
How can I join small files with my message ?

Thx
sfa
Posts: 2
Joined: Wed Jun 17, 2020 6:47 pm

Re: Join/attach file to message

Post by sfa »

I failed to attach a file "manually" in the mail.

I had to firstly get a csrfToken hard-coded in webmail page line ~42

Code: Select all

window.csrfToken = "0_98......";
And use it

Code: Select all

X-Zimbra-Csrf-Token: $csrf_token
while I upload files to https://zimbra.domain.com/service/upload?fmt=raw, get the returning attachment-ids, then include them in the message with <attach>

Resuting request :

Code: Select all

$request = [
    'Header' => [
        'context' => [
            '_jsns' => 'urn:zimbra',
            'authToken' => ['_content' => $this->session],
        ],
    ],
    'Body' => [
        'SendMsgRequest' => [
            '_jsns' => 'urn:zimbraMail',
            'm' => [
                'e' => $addresses,
                'su' => $subject,
                'mp' => [
                    'ct' => 'text/plain',
                    'content' => ['_content' => $body],
                ],
                'attach' => ['aid' => implode(',', $aids)],
            ],
        ],
    ],
];
Thats works, but I may do better, tell me. Thx



PS : the file ZimbraServer/docs/file-upload.txt [ https://github.com/Grynn/zimbra-mirror/ ... upload.txt ] helped me :
FileUploadServlet is used to transfer content from a client to the server. Uses include:

* Uploading attachments (dhtml app)
* SendMsg (mapi connector)
* AddMsg (migration wizard)

The file upload servlet is an http client that supports RFC 1867, form-based file upload in html.
The RFC is available here: http://www.ietf.org/rfc/rfc1867.txt

The default url to the file upload servlet is http://server:port/service/upload.
By default this url maps to com.zimbra.cs.service.FileUploadServlet (see web.xml
in the tomcat WEB-INF directory for your URL/servlet mapping).

For authentication, you must specify your auth token in a cookie. Normally, the servlet reads
the token from cookie "ZM_AUTH_TOKEN"; but if "?admin=1" is specified as a URI query parameter
the servlet will look at cookie "ZM_ADMIN_AUTH_TOKEN".

If you were to submit an html form to upload to the zimbra server, it would look like this:

<html>
<body>
<form method=POST ENCTYPE="multipart/form-data" ACTION="http://localhost:7070/service/upload" METHOD=POST>
<input type="file" name="call_it_whatever" />
<input type="hidden" name="requestId" value="client_token" />
<input type="submit" value="ship it" />
</form>
</body>


The name of the file parameter is of no consequence. The requestId is an client token
which the server will echo back with the response. The response will map the client token
to a server token. The response looks something like this:

<html><head></head><body onload="window.parent._uploadManager.loaded(200,'client_token','server_token');"></body></html>

Future requests referring to the contents of the upload must refer to the server token.
For example, the client can use the server token as an attachment-id in a call to SendMsg.

You can instruct the server to send back non html/javascript by adding fmt=raw to the target url.
The raw output looks like this:

200,'client_token','server_token'

You can also instruct the server to send back detailed structured javascript by adding fmt=extended to the target url.
The extended output looks like this:

<html><head></head><body onload="window.parent._uploadManager.loaded(200,'client_token',[{"aid":"server_token","filename":"image.jpeg","ct":"image/jpeg"}]);"></body></html>

You can combine these options (fmt=raw,extended) and get the structured JS data without the surrounding HTML.
The raw,extended output looks like this:

200,'client_token',[{"aid":"server_token","filename":"image.jpeg","ct":"image/jpeg"}]


To see the different responses, cut and paste this html and give it a shot:

<html>
<body>
Get Raw Results:
<form method=POST ENCTYPE="multipart/form-data" ACTION="http://localhost:7070/service/upload?fmt=raw" METHOD=POST>
<input type="file" name="the_attachment" />
<input type="hidden" name="requestId" value="my_first_attachment" />
<input type="submit" value="ship it" />
</form>
<p>
Get Html/Javascript Results:
<form method=POST ENCTYPE="multipart/form-data" ACTION="http://localhost:7070/service/upload" METHOD=POST>
<input type="file" name="the_attachment" />
<input type="hidden" name="requestId" value="my_first_attachment" />
<input type="submit" value="ship it" />
</form>
<p>
Get Extended Javascript Results:
<form method=POST ENCTYPE="multipart/form-data" ACTION="http://localhost:7070/service/upload?fmt=extended" METHOD=POST>
<input type="file" name="the_attachment" />
<input type="hidden" name="requestId" value="my_first_attachment" />
<input type="submit" value="ship it" />
</form>
</body>



A request at the http level looks something like this:


POST /service/upload HTTP/1.1
Cookie: ZM_AUTH_TOKEN=0_6029...
Content-Type: multipart/form-data; boundary=SKhAvar1nat0rt3mp
Host: localhost:7070
Content-Length: 338
Connection: Keep-Alive
Cache-Control: no-cache
Pragma: no-cache

--SKhAvar1nat0rt3mp
Content-Disposition: form-data; name="requestId"

lsrpc32-client-id
--SKhAvar1nat0rt3mp
Content-Disposition: form-data; name="lsms32uc"; filename="bla.bla"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary

...binary stuff goes here...
--SKhAvar1nat0rt3mp--


And the response looks like this:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 153
Date: Wed, 22 Jun 2005 01:35:08 GMT
Server: Apache-Coyote/1.1

<html><head></head><body onload="window.parent._uploadManager.loaded(200,'lsrpc32-client-id','ddca28ef-e2bd-11d9-a5e5-c7a05d86b154');">
Post Reply