Closed ongoingrv closed 4 months ago
Note that I recently started using verb when I found out that restclient, which I have been using until now, has been archived. I am very happy with verb so far :)
Hi ! Would it be possible to just use two separate code tags?
Access-Token: {{( ... )}}
Client-Secret: {{( ... )}}
So you would have to pieces of code, each one for generating the contents of each header.
The problem is that currently the request spec parser first scans all the lines of headers, and then expands code tags. However, each line is still considered one header, even the expansion has generated extra lines. The reason tags are not expanded before reading the lines is to avoid evaluating code tags for lines that have been commented out with #
.
Thanks for the quick respone!
I have tried to use separate tags now but I am not able to get it to work. My problem is that I would either want the headers Access-Token and Client-Secret, or Authorization. For example for my old restclient setup I have the following function that I use to extract header values:
(defun foo-headers (token)
"Return"
(interactive "sToken: ")
(let ((bearerp (> (length token) 5)))
(format
(if bearerp
(format "Authorization: Bearer %s" token)
(format "Access-Token: %s\nClient-Secret: <secret>" token)))))
That means I can make only one call to the function to setup the required headers as (foo-headers "XXXX")
would result in
Access-Token: XXXX
Client-Secret: <secret>
and (foo-headers "X-Bearer-X")
would result in
Authorization: Bearer X-Bearer-X
I tried to set up separate tags, but it seems like the API do not like the empty header values. The setup I tried was the following:
(defun foo-bearer-p (token)
"Return t if TOKEN is a bearer token."
(interactive "sToken: ")
(> (length token) 36))
(defun foo-client-secret (token)
"Return value for Client-Secret header."
(interactive "sToken: ")
(if (foo-bearer-p token)
""
"secret"))
(defun foo-access-token (token)
"Return value for Access-Token header."
(interactive "sToken: ")
(if (foo-bearer-p token)
""
token))
(defun foo-authorization (token)
"Return value for Authorization header."
(interactive "sToken: ")
(if (foo-bearer-p token)
(concat "Bearer " token)
""))
And I setup the headers as
Authorization: {{(foo-authorization (verb-var token))}}
Access-Token: {{(foo-access-token (verb-var token))}}
Client-Secret: {{(foo-client-secret (verb-var token))}}
That means I would end up with headers looking like
Authorization: Bearer someValue
Access-Token:
Client-Secret:
or
Authorization:
Access-Token: someTokenValue
Client-Secret: secret
I also tried to rewrite my logic a bit so that a function would return the whole header for Authorization or Access-Token in one function, and then have a separate function that would return the Client-Secret header or nothing at all. I.e.
(defun foo-auth-or-access-token (token)
(if (foo-bearer-p token)
(concat "Authorization: Bearer " token)
(concat "Access-Token: " token)))
(defun foo-client-secret (token)
(if (foo-bearer-p token)
""
(concat "Client-Secret: " secret)))
But when using that togeter with
{{(foo-auth-or-access-token (verb-var token))}}
{{(foo-client-secret (verb-var token))}}
I get the error message
Invalid HTTP header: ""
Make sure there’s a blank line between the headers and the request body
Edit: Fix string in defun
Sorry for my huge reply, just wanted to let you know exactly what I tried.
No worries, thank you for the lengthy details! I've pushed a commit to main
that changes the header parsing. Now it is like this:
HEADER: VALUE
The update should be in MELPA soon-ish. Let me know if it works for you! Also added a test: https://github.com/federicotdn/verb/blob/main/test/verb-test.el#L947
Works like a charm, thank you very much! Now I will be able to completely replace restclient.
Thanks for the quick help, I appreciate it very much as I will use this package almost daily at work :)
Edit: Fix broken link.
No problem 👍🏻 Thanks for the information regarding restclient.el btw, I wasn't aware.
I have a use case where the authorization headers for an API can be one of two sets:
However I am unable to use code tags and have the result contain more than one line.
For example, evaluating
{{(format "Access-Token: some-token\nClient-Secret: very-secret")}}
results in
Access-Token: some-token
instead of the expectedI would very much like to be able to evaluate elisp functions returning multi line strings, since all the API endpoints are otherwise the same and it would be very inconvenient to have to keep two different setups up to date.
Might be that I am missing something and that what I am trying to achieve is possible, if so I apologize for my ignorance.