Skip to content

Instantly share code, notes, and snippets.

@DarrenN
Created January 21, 2018 20:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DarrenN/b2a764c0e8f80dc19dbb3858700749c1 to your computer and use it in GitHub Desktop.
Save DarrenN/b2a764c0e8f80dc19dbb3858700749c1 to your computer and use it in GitHub Desktop.
Fun with Lenses, structs and net/url in Racket
#lang racket/base
(require json
lens
net/url
net/url-string
net/head
racket/dict
racket/string)
(struct/lens status (version code text) #:transparent)
(struct/lens response (status headers port) #:transparent)
(define URL "https://httpbin.org/redirect/3")
(define URL2 "http://infoscience.epfl.ch/record/169879/files/RMTrees.pdf")
;; GET url-string and return a response struct
(define (get-url url-string)
(define-values (port header)
(get-pure-port/headers (string->url url-string) #:redirections 5
#:status? #t))
(define status (parse-status (get-status header)))
(define headers (headers->jsoneq (extract-all-fields header)))
(response status headers port))
;; Convert dict into jsexpr? (hasheq)
(define (headers->jsoneq header-dict)
(for/hasheq ([hd header-dict])
(values (string->symbol (car hd)) (string-trim (cdr hd)))))
;; Pull status string from beginning of header string
(define (get-status header-string)
(car (regexp-match #px"[\\w/ .]*" header-string)))
;; Convert status string into a struct
(define (parse-status status-str)
(define-values (version code text) (apply values (string-split status-str)))
(status version code text))
;; Lenses
(define get-content-type-lens
(lens-compose (hash-ref-lens 'Content-Type) response-headers-lens))
(define get-status-code-lens
(lens-compose status-code-lens response-status-lens))
;; Use lenses on response structs
(println (lens-view get-status-code-lens (get-url URL))) ; "200"
(println (lens-view get-content-type-lens (get-url URL2))) ; "application/pdf"
@octplane
Copy link

hello, https://gist.github.com/DarrenN/b2a764c0e8f80dc19dbb3858700749c1#file-net-lens-rkt-L37 fails when the destination is "Moved Permanently", just so you know :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment