Hi Arthur,

Thanks a lot for your quick response and providing the code that runs curl in a subprocess; it will prove very useful.

The 127.0.0.1 URL is using HTTP, not HTTPS, and I was able to use it fine by manually using sockets, so it would still be nice to figure out where the bug is:

;; Rudimentary, for demonstration
(define (read-lines port)
  (let ((line (read-line port)))
    (if (equal? line "0")
    (list)
    (cons line (read-lines port)))))

(pp (let ((port (open-tcp-stream-socket "127.0.0.1" 10002)))
      (write-string "GET /_matrix/client/v3/login HTTP/1.1
Host: matrix-synapse.mit.edu

" port)
      (flush-output port)
      (let ((output (read-lines port)))
    (close-port port)
    output)))

;; Output:
("HTTP/1.1 200 OK"
 "Server: nginx/1.18.0 (Ubuntu)"
 "Date: Sun, 20 Apr 2025 19:04:25 GMT"
 "Content-Type: application/json"
 "Transfer-Encoding: chunked"
 "Connection: keep-alive"
 "Cache-Control: no-cache, no-store, must-revalidate"
 "Access-Control-Allow-Origin: *"
 "Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS"
 "Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Date"
 "Access-Control-Expose-Headers: Synapse-Trace-Id, Server"
 ""
 "b7"
 
"{\"flows\":[{\"type\":\"m.login.sso\",\"identity_providers\":[{\"id\":\"saml\",\"name\":\"Touchstone\"}]},{\"type\":\"m.login.token\"},{\"type\":\"m.login.password\"},{\"type\":\"m.login.application_service\"}]}")

Best,
Gabriel

On 4/20/25 13:17, Arthur A. Gleckler wrote:
Hi, Gabriel.  Thanks for the report.  Also, http-get doesn't support
TLS/SSL, and silently converts requests to HTTP.

I'm afraid that it's unlikely that this will be fixed soon.  In the
meantime, I offer you the code below, which I use to work around this
problem.  It calls curl in a subprocess.  Despite the extra overhead, it is
fast enough for most projects.

(define (curl-prepare-headers alist)
   (append-map (lambda (h)
                 (list "--header"
                       (format #false "~A: ~A" (car h) (cdr h))))
               alist))

(define (curl-http-delete headers url)
   (call-with-output-string
    (lambda (port)
      (assert (zero?
               (run-synchronous-subprocess
                "/usr/bin/curl"
                (cons* "--request" "DELETE"
                       "--silent"
                       "--url" url
                       (curl-prepare-headers headers))
                'output port))
              "Error in HTTP DELETE."
              url))))

(define curl-http-get
   (case-lambda
    ((headers url)
     ;; This fails if a non-NFC string is returned.
     (call-with-output-string
      (lambda (port)
        (assert (zero?
                 (run-synchronous-subprocess
                  "/usr/bin/curl"
                  (cons* "--location"
                         "--silent"
                         "--url" url
                         (curl-prepare-headers headers))
                  'output port))
                "Error in HTTP GET."
                url))))
    ((headers url pathname)
     (assert (zero?
              (run-synchronous-subprocess
               "/usr/bin/curl"
               (cons* "--location"
                      "--output" (enough-namestring pathname)
                      "--silent"
                      "--url" url
                      (curl-prepare-headers headers))))
             "Error in HTTP GET."
             url))))

(define (curl-http-put data headers url)
   (call-with-output-string
    (lambda (port)
      (assert (zero?
               (run-synchronous-subprocess
                "/usr/bin/curl"
                (cons* "--silent"
                       "--upload-file" "-"
                       "--url" url
                       (curl-prepare-headers headers))
                'input (open-input-string data)
                'output port))
              "Error in HTTP PUT."
              url))))


Reply via email to