anchor.diff:    (clear-callbacks http-base))
   
   (defun get-method (enum)
  +  "Given a libevent EVHTTP_REQ enum key word, return the appropriate method
  +   string."
     (case enum
       (:+evhttp-req-get+ "GET")
       (:+evhttp-req-post+ "POST")
       (:+evhttp-req-head+ "HEAD")
       (:+evhttp-req-put+ "PUT")
       (:+evhttp-req-delete+ "DELETE")
  -    (:+evhttp-req-options "OPTIONS")
  +    (:+evhttp-req-options+ "OPTIONS")
       (:+evhttp-req-trace+ "TRACE")
       (:+evhttp-req-connect+ "CONNECT")
       (:+evhttp-req-patch+ "PATCH")))
  +
  +(defun get-method-reverse (method)
  +  "Given a method string, return the appropriate enum value for the libevent
  +   type."
  +  (case (cond
  +          ((stringp method) (read-from-string method))
  +          ((symbolp method) method))
  +    (GET :+evhttp-req-get+)
  +    (POST :+evhttp-req-post+)
  +    (HEAD :+evhttp-req-head+)
  +    (PUT :+evhttp-req-put+)
  +    (DELETE :+evhttp-req-delete+)
  +    (OPTIONS :+evhttp-req-options+)
  +    (TRACE :+evhttp-req-trace+)
  +    (CONNECT :+evhttp-req-connect+)
  +    (PATCH :+evhttp-req-patch+)
  +    (t :+evhttp-req-get+)))
  +
  +(defun http-get-headers (http-headers)
  +  "Pull the headers out of an HTTP request as a plist."
  +  (let ((header-ptr (le-a:evkeyvalq-thq-first http-headers))
  +        (headers nil))
  +    (loop while (not (cffi:null-pointer-p header-ptr)) do
  +      (let ((key (le-a:evkeyval-key header-ptr))
  +            (val (le-a:evkeyval-value header-ptr)))
  +        (push (cons key val) headers)
  +        (setf header-ptr (le-a:evkeyval-next header-ptr))))
  +    headers))
   
   (cffi:defcallback http-request-cb :void ((request :pointer) (http-base :pointer))
     "ALL HTTP requests come through here. They are processed into the http-request
  
positive.code:            (find-q (position #\? uri))
             (resource (if find-q (subseq uri 0 find-q)))
             (querystring (if find-q (subseq uri (1+ find-q)) ""))
             (body (make-array 0 :element-type '(unsigned-byte 8))))
  
        ;; populate the body array. reads all input data from the HTTP stream,
        ;; and this byte array is set directly into the request class. the app can
        ;; turn it into a string if it wants, but we don't make any assumptions
        ;; here.
        (read-socket-data (le:evhttp-request-get-input-buffer request)
                          (lambda (data)
                            (setf body (append-array body data :element-type '(unsigned-byte 8))))
                          :socket-is-evbuffer t)
  
        ;; parse the headers
        (let ((header-ptr (le-a:evkeyvalq-thq-first (le:evhttp-request-get-input-headers request)))
              (headers nil))
          (loop while (not (cffi:null-pointer-p header-ptr)) do
            (let ((key (le-a:evkeyval-key header-ptr))
                  (val (le-a:evkeyval-value header-ptr)))
              (push (cons key val) headers)
              (setf header-ptr (le-a:evkeyval-next header-ptr))))
  
          ;; build the final request object and send it into the request callback
          (let ((http-request (make-instance 'http-request
                                             :c request
                                             :method method
                                             :uri uri
                                             :resource resource
                                             :querystring querystring
                                             :headers headers
                                             :body body)))
            (funcall request-cb http-request))))))
  
  (defun lookup-status-text (status-code)
    "Get the HTTP standard text that goes along with a status code."
  
negative.code: 
  (defparameter *url-scanner*
    (cl-ppcre:create-scanner
      "^([a-z]+)://(([\\w-]+):([\\w-]+)@)?([^/:\?]+)(:([0-9]+))?((/|\\?).*)?$"
      :case-insensitive-mode t)
    "Scanner that splits URLs into their multiple parts. A bit sloppy abd general,
     but works great for it's purpose.")
  