unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Christian Barthel <bch@online.de>
To: help-gnu-emacs@gnu.org
Subject: url-retrieve-synchronously with binary multipart/form-data
Date: Wed, 27 Mar 2024 16:23:18 +0100	[thread overview]
Message-ID: <87zfujhf6h.fsf@shell.onfire.org> (raw)

Hello, I’d like to send a multipart/form-data HTTP POST request with
‘url-retrieve-synchronously’ which should be equivlent to this cURL
request:

#+begin_src shell
  curl -X POST \
       -H "Content-Type: multipart/form-data" \
       --form file="@/tmp/x.png" \
       http://127.0.0.1:8898/
#+end_src

My current elisp function:

#+begin_src elisp
  (defun xtest/http-post-multipart-boundary ()
    "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")

  (defun xtest/http-post (url data extra-headers)
    (let ((url-request-method        "POST")
          (url-request-data          data)
          (url-request-extra-headers extra-headers))
      (let (header
            data
            status)
        (with-current-buffer
            (url-retrieve-synchronously url)
          (setq status url-http-response-status)
          (goto-char (point-min))
          (if (search-forward-regexp "^$" nil t)
              (setq header (buffer-substring (point-min) (point))
                    data   (buffer-substring (1+ (point)) (point-max)))
            (setq data (buffer-string))))
        (list
         (cons 'data data)
         (cons 'header header)
         (cons 'status status)))))

  (xtest/http-post
    "http://127.0.0.1:8898"
    ;; Data:
    (format "%s%s%s%s\r\n"
            "Content-Disposition: form-data; name=x; filename=x.png\r\n"
            "Content-type: image/png\r\n"
            (with-temp-buffer
                       (insert-file-contents-literally "/tmp/x.png")
                       (buffer-substring-no-properties (point-min) (point-max)))
            (format "--%s--" (xtest/http-post-multipart-boundary)))
     ;; Extra Headers:
     `(("Content-Type"
        .
        ,(format "multipart/form-data; boundary=%S" (xtest/http-post-multipart-boundary))
          )))
#+end_src

(this is a simplified version of my original code - I tried to
reconstruct the problem with a simpler version.  My original
elisp defuns are a bit larger and based on [4])

The problem:  With this code in place, I get an error message:
  "Multibyte text in HTTP request: [..]"
As far as I can see, it is generated at Line 416 in url-http.el [1].

When I remove this length check, everything works as expected and I
can POST binary data (image/png in my case) to the remote server.

My questions:  Am I doing something wrong with the encoding of the binary
data?

Is this length check in line 416 at [1] really correct when sending
binary data?

Is there a simpler way with native emacs functions to send
multipart/form-data with POST?


[1] https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/url/url-http.el#n416

[2] The bug report when the lines were introduced:
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=23750

[3] The git-commit a98aa02a5dbf079f7b4f3be5487a2f2b741d103d:
https://git.savannah.gnu.org/cgit/emacs.git/commit/lisp/url/url-http.el?id=a98aa02a5dbf079f7b4f3be5487a2f2b741d103d

[4] https://www.emacswiki.org/emacs/http-post-simple.el

-- 
Christian Barthel



                 reply	other threads:[~2024-03-27 15:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zfujhf6h.fsf@shell.onfire.org \
    --to=bch@online.de \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).