diff options
| author | Lars Ingebrigtsen | 2016-10-13 21:39:29 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2016-10-13 21:39:34 +0200 |
| commit | a6e0188dffc394698d9ffbef50401f14a31c8722 (patch) | |
| tree | 2ef283ac8f57c0daa7ecadcee02ca99f76f8f845 | |
| parent | 4c620c20d4cfd15e6c54fc10c1000dabc01064f7 (diff) | |
| download | emacs-a6e0188dffc394698d9ffbef50401f14a31c8722.tar.gz emacs-a6e0188dffc394698d9ffbef50401f14a31c8722.zip | |
Fix problem with submitting binary data via HTTP forms
* lisp/gnus/mm-url.el (mm-url-encode-multipart-form-data):
Document the parameters, clean up the code, and make uploading
binary data really work (which it didn't if the binary bits
were in the last part of the data).
| -rw-r--r-- | lisp/gnus/mm-url.el | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/lisp/gnus/mm-url.el b/lisp/gnus/mm-url.el index cbea134b544..d5debdb3704 100644 --- a/lisp/gnus/mm-url.el +++ b/lisp/gnus/mm-url.el | |||
| @@ -402,43 +402,52 @@ spaces. Die Die Die." | |||
| 402 | 402 | ||
| 403 | (autoload 'mml-compute-boundary "mml") | 403 | (autoload 'mml-compute-boundary "mml") |
| 404 | 404 | ||
| 405 | (defun mm-url-encode-multipart-form-data (pairs &optional boundary) | 405 | (defun mm-url-encode-multipart-form-data (data &optional boundary) |
| 406 | "Return PAIRS encoded in multipart/form-data." | 406 | "Return DATA encoded in multipart/form-data. |
| 407 | DATA is a list where the elements can have the following form: | ||
| 408 | (\"NAME\" . \"VALUE\") | ||
| 409 | (\"submit\") | ||
| 410 | (\"file\" . ((\"name\" . \"NAME\") | ||
| 411 | (\"filename\" . \"FILENAME\") | ||
| 412 | (\"content-type\" . \"CONTENT-TYPE\") | ||
| 413 | (\"filedata\" . \"FILEDATA\"))) | ||
| 414 | Lowercase names above are literals and uppercase can | ||
| 415 | be various values." | ||
| 407 | ;; RFC1867 | 416 | ;; RFC1867 |
| 408 | ;; Get a good boundary | 417 | ;; Get a good boundary |
| 409 | (unless boundary | 418 | (unless boundary |
| 410 | (setq boundary (mml-compute-boundary '()))) | 419 | (setq boundary (mml-compute-boundary '()))) |
| 411 | (concat | 420 | (with-temp-buffer |
| 412 | ;; Start with the boundary | 421 | (set-buffer-multibyte nil) |
| 413 | "--" boundary "\r\n" | 422 | (cl-loop for (name . value) in data |
| 414 | ;; Create name value pairs | 423 | do (insert "--" boundary "\r\n") |
| 415 | (mapconcat | 424 | (cond |
| 416 | 'identity | 425 | ((equal name "file") |
| 417 | ;; Delete any returned items that are empty | 426 | (insert (format "Content-Disposition: form-data; name=%S; filename=%S\r\n" |
| 418 | (delq nil | 427 | (or (cdr (assoc "name" value)) name) |
| 419 | (mapcar (lambda (data) | 428 | (cdr (assoc "filename" value)))) |
| 420 | (cond ((equal (car data) "file") | 429 | (insert "Content-Transfer-Encoding: binary\r\n") |
| 421 | ;; For each pair | 430 | (insert (format "Content-Type: %s\r\n\r\n" |
| 422 | (format | 431 | (or (cdr (assoc "content-type" value)) |
| 423 | ;; Encode the name | 432 | "text/plain"))) |
| 424 | "Content-Disposition: form-data; name=%S; filename=%S\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Transfer-Encoding: binary\r\n\r\n%s" | 433 | (let ((filedata (cdr (assoc "filedata" value)))) |
| 425 | (cdr (assoc "name" (cdr data))) (cdr (assoc "filename" (cdr data))) | 434 | (cond |
| 426 | (cond ((stringp (cdr (assoc "filedata" (cdr data)))) | 435 | ((stringp filedata) |
| 427 | (cdr (assoc "filedata" (cdr data)))) | 436 | (insert filedata)) |
| 428 | ((integerp (cdr (assoc "filedata" (cdr data)))) | 437 | ;; How can this possibly be useful? |
| 429 | (number-to-string (cdr (assoc "filedata" (cdr data)))))))) | 438 | ((integerp filedata) |
| 430 | ((equal (car data) "submit") | 439 | (insert (number-to-string filedata)))))) |
| 431 | "Content-Disposition: form-data; name=\"submit\"\r\n\r\nSubmit\r\n") | 440 | ((equal name "submit") |
| 432 | (t | 441 | (insert |
| 433 | (format | 442 | "Content-Disposition: form-data; name=\"submit\"\r\n\r\nSubmit\r\n")) |
| 434 | "Content-Disposition: form-data;name=%S\r\n\r\n%s\r\n" | 443 | (t |
| 435 | (car data) (concat (mm-url-form-encode-xwfu (cdr data))) | 444 | (insert (format "Content-Disposition: form-data; name=%S\r\n\r\n" |
| 436 | )))) | 445 | name)) |
| 437 | pairs)) | 446 | (insert value))) |
| 438 | ;; use the boundary as a separator | 447 | (unless (bolp) |
| 439 | (concat "\r\n--" boundary "\r\n")) | 448 | (insert "\r\n"))) |
| 440 | ;; put a boundary at the end. | 449 | (insert "--" boundary "--\r\n") |
| 441 | "--" boundary "--\r\n")) | 450 | (buffer-string))) |
| 442 | 451 | ||
| 443 | (defun mm-url-remove-markup () | 452 | (defun mm-url-remove-markup () |
| 444 | "Remove all HTML markup, leaving just plain text." | 453 | "Remove all HTML markup, leaving just plain text." |