Adjusted conversion of JSON response

- IPFS sometimes returns the JSON response as a string, confusing the
  existing code. Switched to a check of :content-type in the response
  header.
- While we are at it, detect errors by testing the response code.
This commit is contained in:
bnmcgn@gmail.com 2021-05-17 07:42:10 -07:00
parent db8682b513
commit d5e641c3ea

View File

@ -30,28 +30,29 @@
If the JSON is 'error JSON', I.E., it signals that an error has been If the JSON is 'error JSON', I.E., it signals that an error has been
recieved, two values are returned: NIL and the string-error-message." recieved, two values are returned: NIL and the string-error-message."
(let ((result (let ((result
(multiple-value-list
(drakma:http-request (drakma:http-request
(make-call-url call arguments) (make-call-url call arguments)
:method method :method method
:url-encoder #'ipfs::url-encode :url-encoder #'ipfs::url-encode
:parameters parameters :parameters parameters
:want-stream want-stream))) :want-stream want-stream))))
(if want-stream (if want-stream
result (car result)
(process-result result)))) (apply #'process-result result))))
(defun process-result (result) (defun process-result (body status-code headers uri http-stream must-close status-text)
(cond (declare (ignore uri http-stream must-close status-text))
((stringp result) (values nil result)) (let* ((result (cond ((stringp body) body)
((vectorp result) ((vectorp body) (flexi-streams:octets-to-string body))))
(let* ((string (flexi-streams:octets-to-string result)) (result (if (search "application/json" (cdr (assoc :content-type headers)))
(alist (simplify (yason:parse result :object-as :alist))
(with-input-from-string (stream string) result)))
(loop while (peek-char t stream nil) (if (eql 200 status-code)
collect (yason:parse stream :object-as :alist))))) result
(if (ignore-errors (equal (cdr (s-assoc "Type" (simplify alist))) "error")) (values nil (if (stringp result)
(values NIL (cdr (s-assoc "Message" (simplify alist)))) result
(simplify alist)))))) (ignore-errors (cdr (s-assoc "Message" result))))))))
;; STRING LIST &key STRING STRING → STRING ;; STRING LIST &key STRING STRING → STRING
(defun make-call-url (call arguments &key (host *api-host*) (root *api-root*)) (defun make-call-url (call arguments &key (host *api-host*) (root *api-root*))
@ -509,6 +510,7 @@
a local file. a local file.
/ipns/docs.ipfs.io/reference/api/http/#api-v0-files-rm" /ipns/docs.ipfs.io/reference/api/http/#api-v0-files-rm"
(let ((result (let ((result
(multiple-value-list
(drakma:http-request (drakma:http-request
(make-call-url (make-call-url
"files/write" "files/write"
@ -520,8 +522,8 @@ a local file.
,@(when hash (list "hash" hash)))) ,@(when hash (list "hash" hash))))
:method :post :method :post
:parameters `(("data" . ,path-or-string)) :parameters `(("data" . ,path-or-string))
:form-data t))) :form-data t))))
(process-result result))) (apply #'process-result result)))