Skip to content

Commit

Permalink
Add verb-util-form-url-encode
Browse files Browse the repository at this point in the history
  • Loading branch information
federicotdn committed Jan 5, 2025
1 parent 8a53f42 commit ea789bf
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Verb Changelog
## **master** (MELPA)
- Added support for `Verb-Map-Response` heading property. This allows for calling functions automatically with the HTTP response data, when it is received.
- Added the `verb-util-form-url-encode` helper function for use with `application/x-www-form-urlencoded`.

## **3.0.0** - 2024-12-23 (MELPA Stable)
Breaking changes:
Expand Down
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -734,9 +734,26 @@ Remember to specify `Content-Type` in your HTTP headers, as Verb won't do this f
> [!TIP]
> If uploading binary files (e.g. a PNG image), it's a good idea to set `verb-read-file`'s second argument (`coding-system`) to `'binary`. This will instruct Emacs to insert the file contents into the request buffer as raw bytes.
### Multipart Data
### URL-encoded Form Submission

Verb makes it easy for you to use the `multipart/form-data` content type in your requests. Two helper functions are provided: `verb-boundary` and `verb-part`.
Verb includes a utility function in order to use the [`application/x-www-form-urlencoded`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#url-encoded_form_submission) content type in your requests: `verb-util-form-url-encode`. This function takes an alist of `(KEY . VALUE)`, where `KEY` and `VALUE` are strings. Use this in your request specification body, along with the correct `Content-Type` header value, in order to perform a URL-encoded form submission:

```
(...)
** Fetch the user token (login)
post /{{(verb-var user-id)}}/token-auth
Content-Type: application/x-www-form-urlencoded
{{(verb-util-form-url-encode '(("user" . "johnsmith") ("password" . "mypassword")))}}
```

> [!NOTE]
> The `verb-util-form-url-encode` function will take each key-value pair, URL-encode them and join them with `=`, and then join all the elements with `&` to produce the final string. This can also be achieved by manually typing out the key-values in the request body in a single line (e.g. `user=johnsmith&password=mypassword`).
### Multipart Form Submission

Verb also includes some utility functions in order to use the [`multipart/form-data`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#multipart_form_submission) content type in your requests. Two are currently provided: `verb-boundary` and `verb-part`.

When `verb-boundary` is called using code tags within a request specification, it will return a string containing a valid randomly-generated multipart boundary. This function must be called at least once in order to establish the boundary value when a request is being constructed from request specifications.

Expand Down
5 changes: 5 additions & 0 deletions test/data/test.org
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ get /form-urlencoded
Content-Type: application/x-www-form-urlencoded

hello=world&foo=%7B%22test%22%3A123%7D
** form-urlencoded-with-helper
get /form-urlencoded
Content-Type: application/x-www-form-urlencoded

{{(verb-util-form-url-encode '(("hello" . "world") ("foo" . "{\"test\":123}")))}}
** multipart
:properties:
:Verb-Map-Request: verb-body-lf-to-crlf
Expand Down
11 changes: 11 additions & 0 deletions test/verb-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -2264,6 +2264,10 @@

(ert-deftest test-server-request-form-urlencoded ()
(server-test "form-urlencoded"
(should (string= (buffer-string) "OK"))))

(ert-deftest test-server-request-form-urlencoded-with-helper ()
(server-test "form-urlencoded-with-helper"
(should (string= (buffer-string) "OK"))))

(ert-deftest test-server-multipart ()
Expand Down Expand Up @@ -3063,5 +3067,12 @@
(ert-deftest test-server-map-response-error ()
(should-error (server-test "map-response-error")))

(ert-deftest test-verb-util-form-url-encode ()
(dolist (testcase '((() . "")
((("foo" . "bar")) . "foo=bar")
((("foo" . "bar") ("x" . "y")) . "foo=bar&x=y")
((("foo" . "bar") ("x" . "&&")) . "foo=bar&x=%26%26")))
(should (equal (cdr testcase) (verb-util-form-url-encode (car testcase))))))

(provide 'verb-test)
;;; verb-test.el ends here
11 changes: 11 additions & 0 deletions verb-util.el
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,16 @@ All hyperlinks are replaced with the link they contain."
(replace-regexp-in-string verb-util--org-hyperlink-regexp
"\\1" s t))


(defun verb-util-form-url-encode (values)
"URL-encode VALUES for a form submission (x-www-form-urlencoded).
VALUES must be an alist of (KEY . VALUE) elements, with KEY and VALUE
being strings."
(mapconcat (lambda (elem)
(concat (url-hexify-string (car elem))
"="
(url-hexify-string (cdr elem))))
values "&"))

(provide 'verb-util)
;;; verb-util.el ends here

0 comments on commit ea789bf

Please sign in to comment.