commit 3d6bb34305c618e80ebcaa3f321bd9b7d714dc16 from: Artyom Bologov <57838654+aartaka@users.noreply.github.com> via: GitHub date: Sat Jan 15 20:07:19 2022 UTC support binary response body see github issue #4 commit - 54fe3a5eabbee0dc163a691803c54f6784a670be commit + 3d6bb34305c618e80ebcaa3f321bd9b7d714dc16 blob - bc1092547b47cea00cc2719f035886952cebfe99 blob + 5d4aef8fe2217688c34bc1f47d8c6d89250e3d0c --- gemini.lisp +++ gemini.lisp @@ -49,7 +49,7 @@ (error 'malformed-response :reason "missing meta")) (list (parse-status status) meta))) -(defun read-all-stream (in) +(defun read-all-string (in) (with-output-to-string (out) (loop with buffer = (make-array 1024 :element-type 'character) for n-chars = (read-sequence buffer in) @@ -57,6 +57,17 @@ do (write-sequence buffer out :start 0 :end n-chars)))) +(defun read-all-bytes (in) + (let ((data (make-array 0 :element-type '(unsigned-byte 8) :adjustable t :fill-pointer 0))) + (loop with buffer = (make-array 1024 :element-type '(unsigned-byte 8)) + for n-bytes = (read-sequence buffer in) + for data-size = (array-dimension data 0) + while (< 0 n-bytes) + do (adjust-array data (+ data-size n-bytes)) + do (incf (fill-pointer data) n-bytes) + do (replace data buffer :start1 data-size :end2 n-bytes)) + data)) + (defun read-until (in char) (with-output-to-string (out) (loop for ch = (read-char in) @@ -77,7 +88,11 @@ response is fetched, then return the meta and the (dec (format ssl-stream "~a~c~c" req #\return #\newline) (force-output ssl-stream) (let ((resp (parse-response (read-until ssl-stream #\newline)))) - (values resp (read-all-stream ssl-stream)))))) + (values resp (if (and (eq (first resp) :success) + (second resp) + (string= (subseq (second resp) 0 5) "text/")) + (read-all-string ssl-stream) + (read-all-bytes ssl-stream))))))) (defgeneric request (url) (:documentation "Perform a request for the URL"))