Skip to content

Commit

Permalink
(refs #33) got rid of dependence on metabang-bind.
Browse files Browse the repository at this point in the history
  • Loading branch information
fukamachi committed Feb 21, 2012
1 parent 18924fc commit 5875707
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 116 deletions.
1 change: 0 additions & 1 deletion clack-handler-apache.asd
Expand Up @@ -27,7 +27,6 @@
:cl-syntax-annot
:modlisp
:split-sequence
:metabang-bind
:anaphora)
:components ((:file "src/core/handler/apache"))
:description "Clack handler for Apache2 + mod_lisp.")
Expand Down
3 changes: 1 addition & 2 deletions clack-middleware-oauth.asd
Expand Up @@ -25,7 +25,6 @@
:cl-syntax
:cl-syntax-annot
:cl-oauth
:anaphora
:metabang-bind)
:anaphora)
:components ((:file "src/contrib/middleware/oauth"))
:description "Supports authorization mechanism by OAuth")
1 change: 0 additions & 1 deletion clack.asd
Expand Up @@ -24,7 +24,6 @@
:depends-on (;; Utility
:trivial-types
:alexandria
:metabang-bind
:anaphora
:arnesi
:split-sequence
Expand Down
10 changes: 5 additions & 5 deletions src/contrib/middleware/oauth.lisp
Expand Up @@ -10,7 +10,6 @@
(:use :cl
:clack
:anaphora
:metabang-bind
:clack.request
:clack.response))

Expand Down Expand Up @@ -58,10 +57,11 @@
req-token))

(defmethod obtain-request-token ((this <clack-middleware-oauth>) req)
(bind ((oauth-token (query-parameter req "oauth_token"))
((req-token time) (gethash oauth-token (oauth-state this))))
@ignore time
req-token))
(let ((oauth-token (query-parameter req "oauth_token")))
(destructuring-bind (req-token time)
(gethash oauth-token (oauth-state this))
@ignore time
req-token)))

(defmethod obtain-access-token ((this <clack-middleware-oauth>) req-token)
(cl-oauth:obtain-access-token (oauth-access-token-uri this) req-token))
Expand Down
14 changes: 6 additions & 8 deletions src/core/app/urlmap.lisp
Expand Up @@ -9,8 +9,7 @@
(clack.util:namespace clack.app.urlmap
(:use :cl
:clack
:anaphora
:metabang-bind)
:anaphora)
(:import-from :cl-ppcre
:scan
:scan-to-strings
Expand All @@ -27,12 +26,11 @@
@export
(defmethod mount ((this <clack-app-urlmap>) location app)
"Regist an `app' to the `location'."
(bind ((#(host location)
(aif (nth-value
1
(scan-to-strings "^https?://(.*?)(/.*)" location))
it
`#(nil ,location))))
(destructuring-bind (host location)
(aif (nth-value 1
(scan-to-strings "^https?://(.*?)(/.*)" location))
(coerce it 'list)
(list nil location))
(unless (char= #\/ (aref location 0))
(error "Paths need to start with /"))
(push (list host location app)
Expand Down
151 changes: 75 additions & 76 deletions src/core/handler/apache.lisp
Expand Up @@ -9,7 +9,6 @@
(clack.util:namespace clack.handler.apache
(:use :cl
:modlisp
:metabang-bind
:split-sequence
:anaphora)
(:import-from :alexandria
Expand Down Expand Up @@ -49,84 +48,84 @@ This function is called on each request."
(handle-response (call app (command->plist command)))))

(defun command->plist (command)
(bind ((url (ml:header-value command :url))
(pos (position #\? url))
((server-name &optional (server-port "80"))
(split-sequence #\: (ml:header-value command :host)
:from-end t)))
(append
(list
:request-method (ml:header-value command :method)
:script-name ""
:path-info (awhen (subseq url 0 pos)
(url-decode it))
:query-string (subseq url (1+ (or pos 0)))
:raw-body (awhen (ml:header-value command :posted-content)
(flex:make-flexi-stream
(flex:make-in-memory-input-stream
(flex:string-to-octets it))
:external-format :utf-8))
:content-length (awhen (ml:header-value command :content-length)
(parse-integer it :junk-allowed t))
:content-type (ml:header-value command :content-type)
:server-name server-name
:server-port (parse-integer server-port :junk-allowed t)
:server-protocol (ml:header-value command :server-protocol)
:request-uri url
;; FIXME: always return :http
:url-scheme :http
:remote-addr (ml:header-value command :remote-ip-addr)
:remote-port (ml:header-value command :remote-ip-port)
:http-server :modlisp)

;; NOTE: this code almost same thing of Clack.Handler.Hunchentoot's
(loop for (k . v) in command
unless (find k '(:request-method :script-name :path-info :server-name :server-port :server-protocol :request-uri :remote-addr :remote-port :query-string :content-length :content-type :accept :connection))
append (list (make-keyword (format nil "HTTP-~:@(~A~)" k))
v)))))
(let* ((url (ml:header-value command :url))
(pos (position #\? url)))
(destructuring-bind (server-name &optional (server-port "80"))
(split-sequence #\: (ml:header-value command :host)
:from-end t)
(append
(list
:request-method (ml:header-value command :method)
:script-name ""
:path-info (awhen (subseq url 0 pos)
(url-decode it))
:query-string (subseq url (1+ (or pos 0)))
:raw-body (awhen (ml:header-value command :posted-content)
(flex:make-flexi-stream
(flex:make-in-memory-input-stream
(flex:string-to-octets it))
:external-format :utf-8))
:content-length (awhen (ml:header-value command :content-length)
(parse-integer it :junk-allowed t))
:content-type (ml:header-value command :content-type)
:server-name server-name
:server-port (parse-integer server-port :junk-allowed t)
:server-protocol (ml:header-value command :server-protocol)
:request-uri url
;; FIXME: always return :http
:url-scheme :http
:remote-addr (ml:header-value command :remote-ip-addr)
:remote-port (ml:header-value command :remote-ip-port)
:http-server :modlisp)

;; NOTE: this code almost same thing of Clack.Handler.Hunchentoot's
(loop for (k . v) in command
unless (find k '(:request-method :script-name :path-info :server-name :server-port :server-protocol :request-uri :remote-addr :remote-port :query-string :content-length :content-type :accept :connection))
append (list (make-keyword (format nil "HTTP-~:@(~A~)" k))
v))))))

(defun handle-response (res)
"Function for managing response. Take response and output it to `ml:*modlisp-socket*'."
(bind (((status headers body) res)
(keep-alive-p (getf headers :content-length)))
(setf (getf headers :status) (write-to-string status))
(when keep-alive-p
(setf (getf headers :keep-socket) "1"
(getf headers :connection) "Keep-Alive"))

;; NOTE: This almost same of Clack.Handler.Hunchentoot's.
;; Convert plist to alist and make sure the values are strings.
(setf headers
(loop for (k v) on headers by #'cddr
with hash = (make-hash-table :test #'eq)
if (gethash k hash)
do (setf (gethash k hash)
(format nil "~:[~;~:*~A, ~]~A" (gethash k hash) v))
else do (setf (gethash k hash) v)
finally
(return (loop for k being the hash-keys in hash
using (hash-value v)
if v
collect (cons k (princ-to-string v))))))

(etypecase body
(pathname
(with-open-file (file body
:direction :input
:element-type '(unsigned-byte 8)
:if-does-not-exist nil)
(ml::write-response (:headers headers
:len (princ-to-string (file-length file)))
(loop with buf = (make-array 1024 :element-type '(unsigned-byte 8))
for pos = (read-sequence buf file)
until (zerop pos)
do (write-sequence buf ml:*modlisp-socket* :end pos)))))
(list
(ml::write-response (:headers headers)
(write-sequence (flex:string-to-octets
(format nil "~{~A~^~%~}" body)
:external-format :utf-8)
ml:*modlisp-socket*))))))
(destructuring-bind (status headers body) res
(let ((keep-alive-p (getf headers :content-length)))
(setf (getf headers :status) (write-to-string status))
(when keep-alive-p
(setf (getf headers :keep-socket) "1"
(getf headers :connection) "Keep-Alive"))

;; NOTE: This almost same of Clack.Handler.Hunchentoot's.
;; Convert plist to alist and make sure the values are strings.
(setf headers
(loop for (k v) on headers by #'cddr
with hash = (make-hash-table :test #'eq)
if (gethash k hash)
do (setf (gethash k hash)
(format nil "~:[~;~:*~A, ~]~A" (gethash k hash) v))
else do (setf (gethash k hash) v)
finally
(return (loop for k being the hash-keys in hash
using (hash-value v)
if v
collect (cons k (princ-to-string v))))))

(etypecase body
(pathname
(with-open-file (file body
:direction :input
:element-type '(unsigned-byte 8)
:if-does-not-exist nil)
(ml::write-response (:headers headers
:len (princ-to-string (file-length file)))
(loop with buf = (make-array 1024 :element-type '(unsigned-byte 8))
for pos = (read-sequence buf file)
until (zerop pos)
do (write-sequence buf ml:*modlisp-socket* :end pos)))))
(list
(ml::write-response (:headers headers)
(write-sequence (flex:string-to-octets
(format nil "~{~A~^~%~}" body)
:external-format :utf-8)
ml:*modlisp-socket*)))))))

(doc:start)

Expand Down
45 changes: 22 additions & 23 deletions src/core/request.lisp
Expand Up @@ -8,8 +8,7 @@

(clack.util:namespace clack.request
(:use :cl
:anaphora
:metabang-bind)
:anaphora)
(:import-from :trivial-types
:property-list)
(:import-from :alexandria
Expand Down Expand Up @@ -149,27 +148,27 @@ Typically this will be something like :HTTP/1.0 or :HTTP/1.1.")
(parameters->plist (query-string this)))

;; POST parameters
(bind ((body (raw-body this))
((:values type subtype charset)
(parse-content-type (content-type this)))
(content-type (concatenate 'string type "/" subtype))
(external-format
(flex:make-external-format
(if charset
(make-keyword (string-upcase charset))
:utf-8)
:eol-style :lf)))
(cond
((string= content-type "application/x-www-form-urlencoded")
(setf (slot-value this 'body-parameters)
(parameters->plist (read-line (ensure-character-input-stream body) nil ""))))
((and (string= content-type "multipart/form-data")
(not (uploads this))) ;; not set yet.
(setf (uploads this)
(clack.util.hunchentoot:parse-rfc2388-form-data
(flex:make-flexi-stream body)
content-type
external-format))))))
(multiple-value-bind (type subtype charset)
(parse-content-type (content-type this))
(let ((body (raw-body this))
(content-type (concatenate 'string type "/" subtype))
(external-format
(flex:make-external-format
(if charset
(make-keyword (string-upcase charset))
:utf-8)
:eol-style :lf)))
(cond
((string= content-type "application/x-www-form-urlencoded")
(setf (slot-value this 'body-parameters)
(parameters->plist (read-line (ensure-character-input-stream body) nil ""))))
((and (string= content-type "multipart/form-data")
(not (uploads this))) ;; not set yet.
(setf (uploads this)
(clack.util.hunchentoot:parse-rfc2388-form-data
(flex:make-flexi-stream body)
content-type
external-format)))))))

@export
(defun shared-raw-body (env)
Expand Down

0 comments on commit 5875707

Please sign in to comment.