This allows us to do multipart with attachments without nested encoding.
void dav_put_message(struct http_transaction *h, struct ctdlsession *c, char *euid, long old_msgnum) {
char buf[1024];
char *content_type = NULL;
+ char *content_transfer_encoding = NULL;
int n;
long new_msgnum;
char new_euid[1024];
// This section
content_type = header_val(h, "Content-type");
- ctdl_printf(c, "Content-type: %s\r", (content_type ? content_type : "application/octet-stream"));
- ctdl_write(c, HKEY("\r\n"));
- ctdl_write(c, h->request_body, h->request_body_length);
+ content_transfer_encoding = header_val(h, "Content-transfer-encoding");
+
+ // If the content is already encoded, pass it along as-is
+ if (!IsEmptyStr(content_transfer_encoding)) {
+ ctdl_printf(c, "Content-type: %s\r", (content_type ? content_type : "application/octet-stream"));
+ ctdl_write(c, HKEY("\r\n"));
+ ctdl_write(c, h->request_body, h->request_body_length);
+ }
+
+ // But if it's raw, we ought to encode it so it's MIME-friendly.
+ else {
+ ctdl_printf(c, "Content-type: %s\r", (content_type ? content_type : "application/octet-stream"));
+ ctdl_printf(c, "Content-transfer-encoding: quoted-printable\r");
+ ctdl_write(c, HKEY("\r\n"));
+ h->request_body[h->request_body_length] = 0; // make doubly sure it's null terminated.
+
+ // Adapted from https://www.w3.org/Tools/Mail-Transcode/mail-transcode.c
+ char *s = h->request_body;
+ char strconv[8];
+ int strconv_len;
+ int n;
+ for (n = 0; *s; s++) {
+ if (n >= 73 && *s != 10 && *s != 13) {
+ ctdl_write(c, HKEY("=\r\n"));
+ n = 0;
+ }
+ if (*s == 10 || *s == 13) {
+ ctdl_write(c, s, 1);
+ n = 0;
+ }
+ else if (*s<32 || *s==61 || *s>126) {
+ strconv_len = sprintf(strconv, "=%02X", (unsigned char)*s);
+ ctdl_write(c, strconv, strconv_len);
+ n += strconv_len;
+ }
+ else if (*s != 32 || (*(s+1) != 10 && *(s+1) != 13)) {
+ ctdl_write(c, s, 1);
+ n++;
+ }
+ else {
+ ctdl_write(c, "=20", 3);
+ n += 3;
+ }
+ }
+ }
+
if (h->request_body[h->request_body_length] != '\n') {
ctdl_write(c, HKEY("\r\n"));
}
// disclosure are subject to the GNU General Public License v3.
-// Function to encode data in quoted-printable format
-// Written by Theriault and Brett Zamir [https://locutus.io/php/quoted_printable_encode/]
-function quoted_printable_encode(str) {
- const hexChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
- const RFC2045Encode1IN = / \r\n|\r\n|[^!-<>-~ ]/gm
- const RFC2045Encode1OUT = function (sMatch) {
- // Encode space before CRLF sequence to prevent spaces from being stripped
- // Keep hard line breaks intact; CRLF sequences
- if (sMatch.length > 1) {
- return sMatch.replace(' ', '=20');
- }
- // Encode matching character
- const chr = sMatch.charCodeAt(0);
- return '=' + hexChars[((chr >>> 4) & 15)] + hexChars[(chr & 15)];
- }
- // Split lines to 75 characters; the reason it's 75 and not 76 is because softline breaks are
- // preceeded by an equal sign; which would be the 76th character. However, if the last line/string
- // was exactly 76 characters, then a softline would not be needed. PHP currently softbreaks
- // anyway; so this function replicates PHP.
- const RFC2045Encode2IN = /.{1,72}(?!\r\n)[^=]{0,3}/g
- const RFC2045Encode2OUT = function (sMatch) {
- if (sMatch.substr(sMatch.length - 2) === '\r\n') {
- return sMatch;
- }
- return sMatch + '=\r\n';
- }
- str = str.replace(RFC2045Encode1IN, RFC2045Encode1OUT).replace(RFC2045Encode2IN, RFC2045Encode2OUT);
- // Strip last softline break
- return str.substr(0, str.length - 3)
-}
+// // (We don't need this anymore because we encode on the server side)
+// // Function to encode data in quoted-printable format
+// // Written by Theriault and Brett Zamir [https://locutus.io/php/quoted_printable_encode/]
+// function quoted_printable_encode(str) {
+// const hexChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
+// const RFC2045Encode1IN = / \r\n|\r\n|[^!-<>-~ ]/gm
+// const RFC2045Encode1OUT = function (sMatch) {
+// // Encode space before CRLF sequence to prevent spaces from being stripped
+// // Keep hard line breaks intact; CRLF sequences
+// if (sMatch.length > 1) {
+// return sMatch.replace(' ', '=20');
+// }
+// // Encode matching character
+// const chr = sMatch.charCodeAt(0);
+// return '=' + hexChars[((chr >>> 4) & 15)] + hexChars[(chr & 15)];
+// }
+// // Split lines to 75 characters; the reason it's 75 and not 76 is because softline breaks are
+// // preceeded by an equal sign; which would be the 76th character. However, if the last line/string
+// // was exactly 76 characters, then a softline would not be needed. PHP currently softbreaks
+// // anyway; so this function replicates PHP.
+// const RFC2045Encode2IN = /.{1,72}(?!\r\n)[^=]{0,3}/g
+// const RFC2045Encode2OUT = function (sMatch) {
+// if (sMatch.substr(sMatch.length - 2) === '\r\n') {
+// return sMatch;
+// }
+// return sMatch + '=\r\n';
+// }
+// str = str.replace(RFC2045Encode1IN, RFC2045Encode1OUT).replace(RFC2045Encode2IN, RFC2045Encode2OUT);
+// // Strip last softline break
+// return str.substr(0, str.length - 3)
+// }
// generate a random string -- mainly used for generating one-time-use div names
+ "/dummy_name_for_new_message"
+ "?wefw=" + wefw
+ "&subj=" + subj
- boundary = randomString();
- body_text =
- "--" + boundary + "\r\n"
- + "Content-type: text/html\r\n"
- + "Content-transfer-encoding: quoted-printable\r\n"
- + "\r\n"
- + quoted_printable_encode(
- "<html><body>" + document.getElementById("ctdl-editor-body").innerHTML + "</body></html>"
- ) + "\r\n"
- + "--" + boundary + "--\r\n"
- ;
+ body_text = "<html><body>" + document.getElementById("ctdl-editor-body").innerHTML + "</body></html>\r\n";
var request = new XMLHttpRequest();
request.open("PUT", url, true);
- request.setRequestHeader("Content-type", "multipart/mixed; boundary=\"" + boundary + "\"");
+ request.setRequestHeader("Content-type", "text/html");
request.onreadystatechange = function() {
if (request.readyState == 4) {
document.body.style.cursor = "default";
}
}
}
- boundary = randomString();
- body_text =
- "--" + boundary + "\r\n"
- + "Content-type: text/html\r\n"
- + "Content-transfer-encoding: quoted-printable\r\n"
- + "\r\n"
- + quoted_printable_encode(
- "<html><body>" + document.getElementById("ctdl-editor-body").innerHTML + "</body></html>"
- ) + "\r\n"
- + "--" + boundary + "--\r\n"
- ;
+ body_text = "<html><body>" + document.getElementById("ctdl-editor-body").innerHTML + "</body></html>\r\n";
var request = new XMLHttpRequest();
request.open("PUT", url, true);
- request.setRequestHeader("Content-type", "multipart/mixed; boundary=\"" + boundary + "\"");
+ request.setRequestHeader("Content-type", "text/html");
request.onreadystatechange = function() {
if (request.readyState == 4) {
document.body.style.cursor = "default";