The different representations can be inconvenient. Plus sometimes it's
easiest to deal with headers as what they really mean to you: A
dictionary of keys and values. If you do this a lot, you may end up
creating some helpers to convert among representations like the
following.
(define/contract (heads-list->string xs)
((listof string?) . -> . string?)
(string-append (string-join xs "\r\n") "\r\n\r\n"))
(define/contract (heads-string->list s)
(string? . -> . (listof string?))
(filter (lambda (s) (not (equal? s "")))
(regexp-split "\r\n" s)))
(define/contract (heads-list->dict xs)
((listof string?) . -> . dict?)
(for/list ([x (in-list xs)])
(match x
[(pregexp "^(\\S+)\\s*:\\s*(.*?)$" (list _ k v)) (cons k v)]
[else (error 'heads-list->dict "bad header: ~a" x)])))
(define/contract (heads-dict->list d)
(dict? . -> . (listof string?))
(for/list ([(k v) (in-dict d)])
(format "~a: ~a" k v)))
(module+ test
(require rackunit)
;; Round-trip?
(define header (list "a: 1" "b: 2" "c: 3"))
(check-equal? (heads-string->list (heads-list->string header)) header)
(check-equal? (heads-dict->list (heads-list->dict header)) header)
;; Edge cases?
(check-equal? (heads-list->string '()) "\r\n\r\n")
(check-equal? (heads-string->list "\r\n\r\n") '())
(check-equal? (heads-list->dict '()) '())
(check-equal? (heads-dict->list '()) '()))
I just wrote this now. There are some oversimplifications like the
fact that HTTP headers may duplicate keys. But you get the idea.
On Mon, Oct 8, 2012 at 8:04 AM, Mikko Tiihonen