eschulte pushed a commit to branch master in repository elpa. commit c8b6f84ddf62d96e86b5c8b8fc776da396913fcb Author: Eric Schulte <schulte.e...@gmail.com> Date: Sun Jan 5 23:03:14 2014 -0700
refactoring no multiple concurrent header parsing --- doc/web-server.texi | 55 +++++++++++++++++++++++++++++++++++++------------- web-server.el | 13 ++++------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/doc/web-server.texi b/doc/web-server.texi index a994413..dcd2d90 100644 --- a/doc/web-server.texi +++ b/doc/web-server.texi @@ -136,15 +136,40 @@ the handler function returns the keyword @code{:keep-alive}. @chapter Requests @cindex requests -Each HTTP requests is represented using an @code{ws-request} object -(@pxref{ws-request}). The request object is used to decide which -handler to call, and is passed as an argument to the called handler. -The request object holds the network process, all HTTP headers, and -any parameters. +Each HTTP requests is represented using a @code{ws-request} object +(@pxref{ws-request}). The request object serves two purposes, one +internal and one external. Internally, request objects are used to +hold state while HTTP headers are parsed incrementally as the HTTP +request text is received from the network. Externally, request +objects are used to decide which handler to call, and are then passed +as the only argument to the called handler. + +In addition to fields used internally, each @code{ws-request} object +holds the network process in the @code{process} and holds all HTTP +headers and request GET or POST parameters in the @code{headers} +alist. HTML Headers are keyed using uppercase keywords (e.g., +@code{:GET}), and user supplied parameters are keyed using the string +name of the parameter. + +The @code{process} field may be used by handlers to send data to a +client as in the following example. -The text of the request is parsed into an alist. HTML Headers are -keyed using uppercase keywords (e.g., @code{:GET}), and user supplied -parameters are keyed using the string name of the parameter. +@example +(process-send-string (process request) "hello world") +@end example + +The @code{headers} field may be used to access request information +such as the requested path, + +@example +(cdr (assoc :GET (headers request))) +@end example + +or named parameters as from a web form. + +@example +(cdr (assoc "message" (headers request))) +@end example @node Usage Examples, Hello World, Requests, Top @chapter Usage Examples @@ -301,14 +326,14 @@ Each instance includes the @code{handlers} association list and @end deftp @anchor{ws-request} -@deftp Class ws-request process pending context boundary headers +@deftp Class ws-request process pending context boundary index active headers The @code{ws-request} class represents an active web request. The -@code{process} field holds the network process of the client machine -and may be used by handlers to respond to requests. The -@code{headers} field holds an alist of information on the request for -use by handlers. The remaining @code{pending}, @code{context} and -@code{boundary} fields are used to maintain header parsing information -across calls to the @code{ws-filter} function. +@code{process} field holds the network process of the client and may +be used by handlers to respond to requests. The @code{headers} field +holds an alist of information on the request for use by handlers. The +remaining @code{pending}, @code{context}, @code{boundary}, +@code{index} and @code{active} fields are used to maintain header +parsing information across calls to the @code{ws-filter} function. @end deftp @section Starting and Stopping Servers diff --git a/web-server.el b/web-server.el index 44b4432..48f788e 100644 --- a/web-server.el +++ b/web-server.el @@ -46,7 +46,7 @@ (context :initarg :context :accessor context :initform nil) (boundary :initarg :boundary :accessor boundary :initform nil) (index :initarg :index :accessor index :initform 0) - (active :initarg :active :accessor active :initform 0) + (active :initarg :active :accessor active :initform nil) (headers :initarg :headers :accessor headers :initform (list nil)))) (defvar ws-servers nil @@ -203,12 +203,10 @@ function. (push (make-instance 'ws-request :process proc) requests)) (let ((request (cl-find-if (lambda (c) (equal proc (process c))) requests))) (with-slots (pending) request (setq pending (concat pending string))) - ;; if request is currently being parsed, just indicate new content - (if (> (active request) 0) - (incf (active request)) + (unless (active request) ; don't re-start if request is being parsed + (setf (active request) t) (when (not (eq (catch 'close-connection - (if (progn (incf (active request)) - (ws-parse-request request)) + (if (ws-parse-request request) (ws-call-handler request handlers) :keep-open)) :keep-open)) @@ -268,8 +266,7 @@ Return non-nil only when parsing is complete." ;; All other headers are collected directly. (setcdr (last headers) header))))) (setq index tmp))))) - (decf (active request)) - (when (> (active request) 0) (ws-parse-request request)) + (setf (active request) nil) nil)) (defun ws-call-handler (request handlers)