From 0a2354845e2316ddffe0d23887f938ca2987bb67 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Thu, 6 Mar 2014 21:39:03 -0700 Subject: [PATCH] contribute Emacs web server package (web-server) This package provides an HTTP server for Emacs which handles requests by running Emacs Lisp handlers. See the included manual for details. * externals-list: Add web-server as a git subtree. * packages/web-server/dir: Adding directory file for the web-server.info info file. * packages/web-server/web-server-status-codes.el: HTTP status codes. * packages/web-server/web-server.el: Implement an HTTP server for Emacs. * packages/web-server/web-server.info: Manual for the Emacs web server. --- externals-list | 1 + packages/web-server/dir | 18 + packages/web-server/web-server-status-codes.el | 91 ++ packages/web-server/web-server.el | 702 ++++++++ packages/web-server/web-server.info | 2083 ++++++++++++++++++++++++ 5 files changed, 2895 insertions(+) create mode 100644 packages/web-server/dir create mode 100644 packages/web-server/web-server-status-codes.el create mode 100644 packages/web-server/web-server.el create mode 100644 packages/web-server/web-server.info diff --git a/externals-list b/externals-list index a5eccd8..d5a7cc1 100644 --- a/externals-list +++ b/externals-list @@ -34,6 +34,7 @@ ("temp-buffer-browse" :subtree "https://github.com/leoliu/temp-buffer-browse") ;;FIXME:("vlf" :subtree ??) ("w3" :external nil) + ("web-server" :subtree "https://github.com/eschulte/emacs-web-server.git") ("websocket" :subtree "https://github.com/ahyatt/emacs-websocket.git") ("yasnippet" :subtree "https://github.com/capitaomorte/yasnippet.git") ) diff --git a/packages/web-server/dir b/packages/web-server/dir new file mode 100644 index 0000000..9b3d897 --- /dev/null +++ b/packages/web-server/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "?" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Web Server: (web-server). Web Server for Emacs. diff --git a/packages/web-server/web-server-status-codes.el b/packages/web-server/web-server-status-codes.el new file mode 100644 index 0000000..bf0e4ca --- /dev/null +++ b/packages/web-server/web-server-status-codes.el @@ -0,0 +1,91 @@ +;;; web-server-status-codes.el --- Emacs Web Server HTML status codes + +;;; Code: +(defvar ws-status-codes + '((100 . "Continue") + (101 . "Switching Protocols") + (102 . "Processing") + (200 . "OK") + (201 . "Created") + (202 . "Accepted") + (203 . "Non-Authoritative Information") + (204 . "No Content") + (205 . "Reset Content") + (206 . "Partial Content") + (207 . "Multi-Status") + (208 . "Already Reported") + (226 . "IM Used") + (300 . "Multiple Choices") + (301 . "Moved Permanently") + (302 . "Found") + (303 . "See Other") + (304 . "Not Modified") + (305 . "Use Proxy") + (306 . "Switch Proxy") + (307 . "Temporary Redirect") + (308 . "Permanent Redirect") + (400 . "Bad Request") + (401 . "Unauthorized") + (402 . "Payment Required") + (403 . "Forbidden") + (404 . "Not Found") + (405 . "Method Not Allowed") + (406 . "Not Acceptable") + (407 . "Proxy Authentication Required") + (408 . "Request Timeout") + (409 . "Conflict") + (410 . "Gone") + (411 . "Length Required") + (412 . "Precondition Failed") + (413 . "Request Entity Too Large") + (414 . "Request-URI Too Long") + (415 . "Unsupported Media Type") + (416 . "Requested Range Not Satisfiable") + (417 . "Expectation Failed") + (418 . "I'm a teapot") + (419 . "Authentication Timeout") + (420 . "Method Failure") + (420 . "Enhance Your Calm") + (422 . "Unprocessable Entity") + (423 . "Locked") + (424 . "Failed Dependency") + (424 . "Method Failure") + (425 . "Unordered Collection") + (426 . "Upgrade Required") + (428 . "Precondition Required") + (429 . "Too Many Requests") + (431 . "Request Header Fields Too Large") + (440 . "Login Timeout") + (444 . "No Response") + (449 . "Retry With") + (450 . "Blocked by Windows Parental Controls") + (451 . "Unavailable For Legal Reasons") + (451 . "Redirect") + (494 . "Request Header Too Large") + (495 . "Cert Error") + (496 . "No Cert") + (497 . "HTTP to HTTPS") + (499 . "Client Closed Request") + (500 . "Internal Server Error") + (501 . "Not Implemented") + (502 . "Bad Gateway") + (503 . "Service Unavailable") + (504 . "Gateway Timeout") + (505 . "HTTP Version Not Supported") + (506 . "Variant Also Negotiates") + (507 . "Insufficient Storage") + (508 . "Loop Detected") + (509 . "Bandwidth Limit Exceeded") + (510 . "Not Extended") + (511 . "Network Authentication Required") + (520 . "Origin Error") + (522 . "Connection timed out") + (523 . "Proxy Declined Request") + (524 . "A timeout occurred") + (598 . "Network read timeout error") + (599 . "Network connect timeout error")) + "Possible HTML status codes with names. +From http://en.wikipedia.org/wiki/List_of_HTTP_status_codes.") + +(provide 'web-server-status-codes) +;;; web-server-status-codes.el ends here diff --git a/packages/web-server/web-server.el b/packages/web-server/web-server.el new file mode 100644 index 0000000..500030f --- /dev/null +++ b/packages/web-server/web-server.el @@ -0,0 +1,702 @@ +;;; web-server.el --- Emacs Web Server + +;; Copyright (C) 2013-2014 Free Software Foundation, Inc. + +;; Author: Eric Schulte +;; Maintainer: Eric Schulte +;; Version: 0.1.0 +;; Package-Requires: ((emacs "24.3")) +;; Keywords: http, server, network +;; URL: https://github.com/eschulte/emacs-web-server +;; License: GPLV3 (see the COPYING file in this directory) + +;;; Commentary: + +;; A web server in Emacs running handlers written in Emacs Lisp. +;; +;; Full support for GET and POST requests including URL-encoded +;; parameters and multipart/form data. Supports web sockets. +;; +;; See the examples/ directory for examples demonstrating the usage of +;; the Emacs Web Server. The following launches a simple "hello +;; world" server. +;; +;; (ws-start +;; '(((lambda (_) t) . ; match every request +;; (lambda (request) ; reply with "hello world" +;; (with-slots (process) request +;; (ws-response-header process 200 '("Content-type" . "text/plain")) +;; (process-send-string process "hello world"))))) +;; 9000) + +;;; Code: +(require 'web-server-status-codes) +(require 'mail-parse) ; to parse multipart data in headers +(require 'mm-encode) ; to look-up mime types for files +(require 'url-util) ; to decode url-encoded params +(require 'eieio) +(eval-when-compile (require 'cl)) +(require 'cl-lib) + +(defclass ws-server () + ((handlers :initarg :handlers :accessor handlers :initform nil) + (process :initarg :process :accessor process :initform nil) + (port :initarg :port :accessor port :initform nil) + (requests :initarg :requests :accessor requests :initform nil))) + +(defclass ws-request () + ((process :initarg :process :accessor process :initform nil) + (pending :initarg :pending :accessor pending :initform "") + (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 nil) + (headers :initarg :headers :accessor headers :initform (list nil)))) + +(defvar ws-servers nil + "List holding all web servers.") + +(defvar ws-log-time-format "%Y.%m.%d.%H.%M.%S.%N" + "Logging time format passed to `format-time-string'.") + +(defvar ws-guid "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + "This GUID is defined in RFC6455.") + +;;;###autoload +(defun ws-start (handlers port &optional log-buffer &rest network-args) + "Start a server using HANDLERS and return the server object. + +HANDLERS may be a single function (which is then called on every +request) or a list of conses of the form (MATCHER . FUNCTION), +where the FUNCTION associated with the first successful MATCHER +is called. Handler functions are called with two arguments, the +process and the request object. + +A MATCHER may be either a function (in which case it is called on +the request object) or a cons cell of the form (KEYWORD . STRING) +in which case STRING is matched against the value of the header +specified by KEYWORD. + +Any supplied NETWORK-ARGS are assumed to be keyword arguments for +`make-network-process' to which they are passed directly. + +For example, the following starts a simple hello-world server on +port 8080. + + (ws-start + (lambda (request) + (with-slots (process headers) request + (process-send-string proc + \"HTTP/1.1 200 OK\\r\\nContent-Type: text/plain\\r\\n\\r\\nhello world\"))) + 8080) + +Equivalently, the following starts an identical server using a +function MATCH and the `ws-response-header' convenience +function. + + (ws-start + '(((lambda (_) t) . + (lambda (proc request) + (ws-response-header proc 200 '(\"Content-type\" . \"text/plain\")) + (process-send-string proc \"hello world\") + t))) + 8080) + +" + (let ((server (make-instance 'ws-server :handlers handlers :port port)) + (log (when log-buffer (get-buffer-create log-buffer)))) + (setf (process server) + (apply + #'make-network-process + :name "ws-server" + :service (port server) + :filter 'ws-filter + :server t + :nowait t + :family 'ipv4 + :plist (append (list :server server) + (when log (list :log-buffer log))) + :log (when log + (lambda (proc request message) + (let ((c (process-contact request)) + (buf (plist-get (process-plist proc) :log-buffer))) + (with-current-buffer buf + (goto-char (point-max)) + (insert (format "%s\t%s\t%s\t%s" + (format-time-string ws-log-time-format) + (first c) (second c) message)))))) + network-args)) + (push server ws-servers) + server)) + +(defun ws-stop (server) + "Stop SERVER." + (setq ws-servers (remove server ws-servers)) + (mapc #'delete-process (append (mapcar #'process (requests server)) + (list (process server))))) + +(defun ws-stop-all () + "Stop all servers in `ws-servers'." + (interactive) + (mapc #'ws-stop ws-servers)) + +(defvar ws-http-common-methods '(GET HEAD POST PUT DELETE TRACE) + "HTTP methods from http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.") + +(defvar ws-http-method-rx + (format "^\\(%s\\) \\([^[:space:]]+\\) \\([^[:space:]]+\\)$" + (mapconcat #'symbol-name ws-http-common-methods "\\|"))) + +(defun ws-parse-query-string (string) + "Thin wrapper around `url-parse-query-string'." + (mapcar (lambda (pair) (cons (first pair) (second pair))) + (url-parse-query-string string nil 'allow-newlines))) + +(defun ws-parse (proc string) + "Parse HTTP headers in STRING reporting errors to PROC." + (cl-flet ((to-keyword (s) (intern (concat ":" (upcase s))))) + (cond + ;; Method + ((string-match ws-http-method-rx string) + (let ((method (to-keyword (match-string 1 string))) + (url (match-string 2 string))) + (if (string-match "?" url) + (cons (cons method (substring url 0 (match-beginning 0))) + (ws-parse-query-string + (url-unhex-string (substring url (match-end 0))))) + (list (cons method url))))) + ;; Authorization + ((string-match "^AUTHORIZATION: \\([^[:space:]]+\\) \\(.*\\)$" string) + (let ((protocol (to-keyword (match-string 1 string))) + (credentials (match-string 2 string))) + (list (cons :AUTHORIZATION + (cons protocol + (case protocol + (:BASIC + (let ((cred (base64-decode-string credentials))) + (if (string-match ":" cred) + (cons (substring cred 0 (match-beginning 0)) + (substring cred (match-end 0))) + (ws-error proc "bad credentials: %S" cred)))) + (t (ws-error proc "un-support protocol: %s" + protocol)))))))) + ;; All other headers + ((string-match "^\\([^[:space:]]+\\): \\(.*\\)$" string) + (list (cons (to-keyword (match-string 1 string)) + (match-string 2 string)))) + (:otherwise (ws-error proc "bad header: %S" string) nil)))) + +(defun ws-trim (string) + (while (and (> (length string) 0) + (or (and (string-match "[\r\n]" (substring string -1)) + (setq string (substring string 0 -1))) + (and (string-match "[\r\n]" (substring string 0 1)) + (setq string (substring string 1)))))) + string) + +(defun ws-parse-multipart/form (proc string) + ;; ignore empty and non-content blocks + (when (string-match "Content-Disposition:[[:space:]]*\\(.*\\)\r\n" string) + (let ((dp (cdr (mail-header-parse-content-disposition + (match-string 1 string)))) + (last-index (match-end 0)) + index) + ;; every line up until the double \r\n is a header + (while (and (setq index (string-match "\r\n" string last-index)) + (not (= index last-index))) + (setcdr (last dp) (ws-parse proc (substring string last-index index))) + (setq last-index (+ 2 index))) + ;; after double \r\n is all content + (cons (cdr (assoc 'name dp)) + (cons (cons 'content (substring string (+ 2 last-index))) + dp))))) + +(defun ws-filter (proc string) + (with-slots (handlers requests) (plist-get (process-plist proc) :server) + (unless (cl-find-if (lambda (c) (equal proc (process c))) requests) + (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))) + (unless (active request) ; don't re-start if request is being parsed + (setf (active request) t) + (when (not (eq (catch 'close-connection + (if (ws-parse-request request) + (ws-call-handler request handlers) + :keep-alive)) + :keep-alive)) + ;; Properly shut down processes requiring an ending (e.g., chunked) + (let ((ender (plist-get (process-plist proc) :ender))) + (when ender (process-send-string proc ender))) + (setq requests (cl-remove-if (lambda (r) (eql proc (process r))) requests)) + (delete-process proc)))))) + +(defun ws-parse-request (request) + "Parse request STRING from REQUEST with process PROC. +Return non-nil only when parsing is complete." + (catch 'finished-parsing-headers + (with-slots (process pending context boundary headers index) request + (let ((delimiter (concat "\r\n" (if boundary (concat "--" boundary) ""))) + ;; Track progress through string, always work with the + ;; section of string between INDEX and NEXT-INDEX. + next-index) + ;; parse headers and append to request + (while (setq next-index (string-match delimiter pending index)) + (let ((tmp (+ next-index (length delimiter)))) + (if (= index next-index) ; double \r\n ends current run of headers + (case context + ;; Parse URL data. + ;; http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 + (application/x-www-form-urlencoded + (mapc (lambda (pair) (setcdr (last headers) (list pair))) + (ws-parse-query-string + (replace-regexp-in-string + "\\+" " " + (ws-trim (substring pending index))))) + (throw 'finished-parsing-headers t)) + ;; Set custom delimiter for multipart form data. + (multipart/form-data + (setq delimiter (concat "\r\n--" boundary))) + ;; No special context so we're done. + (t (throw 'finished-parsing-headers t))) + (if (eql context 'multipart/form-data) + (progn + (setcdr (last headers) + (list (ws-parse-multipart/form process + (substring pending index next-index)))) + ;; Boundary suffixed by "--" indicates end of the headers. + (when (and (> (length pending) (+ tmp 2)) + (string= (substring pending tmp (+ tmp 2)) "--")) + (throw 'finished-parsing-headers t))) + ;; Standard header parsing. + (let ((header (ws-parse process (substring pending + index next-index)))) + ;; Content-Type indicates that the next double \r\n + ;; will be followed by a special type of content which + ;; will require special parsing. Thus we will note + ;; the type in the CONTEXT variable for parsing + ;; dispatch above. + (if (and (caar header) (eql (caar header) :CONTENT-TYPE)) + (cl-destructuring-bind (type &rest data) + (mail-header-parse-content-type (cdar header)) + (setq boundary (cdr (assoc 'boundary data))) + (setq context (intern (downcase type)))) + ;; All other headers are collected directly. + (setcdr (last headers) header))))) + (setq index tmp))))) + (setf (active request) nil) + nil)) + +(defun ws-call-handler (request handlers) + (catch 'matched-handler + (when (functionp handlers) + (throw 'matched-handler + (condition-case e (funcall handlers request) + (error (ws-error (process request) "Caught Error: %S" e))))) + (mapc (lambda (handler) + (let ((match (car handler)) + (function (cdr handler))) + (when (or (and (consp match) + (assoc (car match) (headers request)) + (string-match (cdr match) + (cdr (assoc (car match) + (headers request))))) + (and (functionp match) (funcall match request))) + (throw 'matched-handler + (condition-case e (funcall function request) + (error (ws-error (process request) + "Caught Error: %S" e))))))) + handlers) + (ws-error (process request) "no handler matched request: %S" + (headers request)))) + +(defun ws-error (proc msg &rest args) + (let ((buf (plist-get (process-plist proc) :log-buffer)) + (c (process-contact proc))) + (when buf + (with-current-buffer buf + (goto-char (point-max)) + (insert (format "%s\t%s\t%s\tWS-ERROR: %s" + (format-time-string ws-log-time-format) + (first c) (second c) + (apply #'format msg args))))) + (apply #'ws-send-500 proc msg args))) + + +;;; Web Socket +;; Implement to conform to http://tools.ietf.org/html/rfc6455. + +;; The `ws-message' object is used to hold state across multiple calls +;; of the process filter on the websocket network process. The fields +;; play the following roles. +;; process ------ holds the process itself, used for communication +;; pending ------ holds text received from the client but not yet parsed +;; active ------- indicates that parsing is active to avoid re-entry +;; of the `ws-web-socket-parse-messages' function +;; new ---------- indicates that new text was received during parsing +;; and causes `ws-web-socket-parse-messages' to be +;; called again after it terminates +;; data --------- holds the data of parsed messages +;; handler ------ holds the user-supplied function used called on the +;; data of parsed messages +(defclass ws-message () ; web socket message object + ((process :initarg :process :accessor process :initform "") + (pending :initarg :pending :accessor pending :initform "") + (active :initarg :active :accessor active :initform nil) + (new :initarg :new :accessor new :initform nil) + (data :initarg :data :accessor data :initform "") + (handler :initarg :handler :accessor handler :initform ""))) + +(defun ws-web-socket-connect (request handler) + "Establish a web socket connection with request. +If the connection is successful this function will throw +`:keep-alive' to `close-connection' skipping any remaining code +in the request handler. If no web-socket connection is +established (e.g., because REQUEST is not attempting to establish +a connection) then no actions are taken and nil is returned. + +Second argument HANDLER should be a function of one argument +which will be called on all complete messages as they are +received and parsed from the network." + (with-slots (process headers) request + (when (assoc :SEC-WEBSOCKET-KEY headers) + ;; Accept the connection + (ws-response-header process 101 + (cons "Upgrade" "websocket") + (cons "Connection" "upgrade") + (cons "Sec-WebSocket-Accept" + (ws-web-socket-handshake + (cdr (assoc :SEC-WEBSOCKET-KEY headers))))) + ;; Setup the process filter + (set-process-coding-system process 'binary) + (set-process-plist + process (list :message (make-instance 'ws-message + :handler handler :process process))) + (set-process-filter process 'ws-web-socket-filter) + process))) + +(defun ws-web-socket-filter (process string) + (let ((message (plist-get (process-plist process) :message))) + (if (active message) ; don't re-start if message is being parsed + (setf (new message) string) + (setf (pending message) (concat (pending message) string)) + (setf (active message) t) + (ws-web-socket-parse-messages message)) + (setf (active message) nil))) + +(defun ws-web-socket-mask (masking-key data) + (let ((masking-data (apply #'concat (make-list (+ 1 (/ (length data) 4)) + masking-key)))) + (apply #'string (cl-mapcar #'logxor masking-data data)))) + +;; Binary framing protocol +;; from http://tools.ietf.org/html/rfc6455#section-5.2 +;; +;; 0 1 2 3 +;; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +;; +-+-+-+-+-------+-+-------------+-------------------------------+ +;; |F|R|R|R| opcode|M| Payload len | Extended payload length | +;; |I|S|S|S| (4) |A| (7) | (16/64) | +;; |N|V|V|V| |S| | (if payload len==126/127) | +;; | |1|2|3| |K| | | +;; +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + +;; | Extended payload length continued, if payload len == 127 | +;; + - - - - - - - - - - - - - - - +-------------------------------+ +;; | |Masking-key, if MASK set to 1 | +;; +-------------------------------+-------------------------------+ +;; | Masking-key (continued) | Payload Data | +;; +-------------------------------- - - - - - - - - - - - - - - - + +;; : Payload Data continued ... : +;; + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +;; | Payload Data continued ... | +;; +---------------------------------------------------------------+ +;; +(defun ws-web-socket-parse-messages (message) + "Web socket filter to pass whole frames to the client. +See RFC6455." + (with-slots (process active pending data handler new) message + (let ((index 0)) + (cl-labels ((int-to-bits (int size) + (let ((result (make-bool-vector size nil))) + (mapc (lambda (place) + (let ((val (expt 2 place))) + (when (>= int val) + (setq int (- int val)) + (aset result place t)))) + (reverse (number-sequence 0 (- size 1)))) + (reverse (append result nil)))) + (bits-to-int (bits) + (let ((place 0)) + (apply #'+ + (mapcar (lambda (bit) + (prog1 (if bit (expt 2 place) 0) (incf place))) + (reverse bits))))) + (bits (length) + (apply #'append + (mapcar (lambda (int) (int-to-bits int 8)) + (cl-subseq + pending index (incf index length)))))) + (let (fin rsvs opcode mask pl mask-key) + ;; Parse fin bit, rsvs bits and opcode + (let ((byte (bits 1))) + (setq fin (car byte) + rsvs (cl-subseq byte 1 4) + opcode + (let ((it (bits-to-int (cl-subseq byte 4)))) + (case it + (0 :CONTINUATION) + (1 :TEXT) + (2 :BINARY) + ((3 4 5 6 7) :NON-CONTROL) + (8 :CLOSE) + (9 :PING) + (10 :PONG) + ((11 12 13 14 15) :CONTROL) + ;; If an unknown opcode is received, the receiving + ;; endpoint MUST _Fail the WebSocket Connection_. + (t (ws-error process + "Web Socket Fail: bad opcode %d" it)))))) + (unless (cl-every #'null rsvs) + ;; MUST be 0 unless an extension is negotiated that defines + ;; meanings for non-zero values. + (ws-error process "Web Socket Fail: non-zero RSV 1 2 or 3")) + ;; Parse mask and payload length + (let ((byte (bits 1))) + (setq mask (car byte) + pl (bits-to-int (cl-subseq byte 1)))) + (unless (eq mask t) + ;; All frames sent from client to server have this bit set to 1. + (ws-error process "Web Socket Fail: client must mask data")) + (cond + ((= pl 126) (setq pl (bits-to-int (bits 2)))) + ((= pl 127) (setq pl (bits-to-int (bits 8))))) + ;; unmask data + (when mask (setq mask-key (cl-subseq pending index (incf index 4)))) + (setq data (concat data + (ws-web-socket-mask + mask-key (cl-subseq pending index (+ index pl))))) + (if fin + ;; wipe the message state and call the handler + (let ((it data)) + (setq data "" active nil pending "" new nil) + ;; close on a close frame, otherwise call the handler + (if (not (eql opcode :CLOSE)) + (funcall handler process it) + (process-send-string process + (unibyte-string (logior (lsh 1 7) 8) 0)))) + ;; add any remaining un-parsed network data to pending + (when (< (+ index pl) (length pending)) + (setq pending (substring pending (+ index pl))))))) + ;; possibly re-parse any pending input + (when (new message) (ws-web-socket-parse-messages message))))) + +(defun ws-web-socket-frame (string &optional opcode) + "Frame STRING for web socket communication." + (let* ((fin 1) ;; set to 0 if not final frame + (len (length string)) + (opcode (ecase (or opcode :TEXT) (:TEXT 1) (:BINARY 2)))) + ;; Does not do any masking which is only required of client communication + (concat + (cond + ((< len 126) (unibyte-string (logior (lsh fin 7) opcode) len)) + ((< len 65536) (unibyte-string (logior (lsh fin 7) opcode) 126 + ;; extended 16-bit length + (logand (lsh len -8) 255) + (logand len 255))) + (t (unibyte-string (logior (lsh fin 7) opcode) 127 + ;; more extended 64-bit length + (logand (lsh len -56) 255) + (logand (lsh len -48) 255) + (logand (lsh len -40) 255) + (logand (lsh len -32) 255) + (logand (lsh len -24) 255) + (logand (lsh len -16) 255) + (logand (lsh len -8) 255) + (logand len 255)))) + string))) + + +;;; Content and Transfer encoding support +(defvar ws-compress-cmd "compress" + "Command used for the \"compress\" Content or Transfer coding.") + +(defvar ws-deflate-cmd "zlib-flate -compress" + "Command used for the \"deflate\" Content or Transfer coding.") + +(defvar ws-gzip-cmd "gzip" + "Command used for the \"gzip\" Content or Transfer coding.") + +(defmacro ws-encoding-cmd-to-fn (cmd) + "Return a function which applies CMD to strings." + `(lambda (s) + (with-temp-buffer + (insert s) + (shell-command-on-region (point-min) (point-max) ,cmd nil 'replace) + (buffer-string)))) + +(defun ws-chunk (string) + "Convert STRING to a valid chunk for HTTP chunked Transfer-encoding." + (format "%x\r\n%s\r\n" (string-bytes string) string)) + + +;;; Convenience functions to write responses +(defun ws-response-header (proc code &rest headers) + "Send the headers for an HTTP response to PROC. +CODE should be an HTTP status code, see `ws-status-codes' for a +list of known codes. + +When \"Content-Encoding\" or \"Transfer-Encoding\" headers are +supplied any subsequent data written to PROC using `ws-send' will +be encoded appropriately including sending the appropriate data +upon the end of transmission for chunked transfer encoding. + +For example with the header `(\"Content-Encoding\" . \"gzip\")', +any data subsequently written to PROC using `ws-send' will be +compressed using the command specified in `ws-gzip-cmd'." + ;; update process to reflect any Content or Transfer encodings + (let ((content (cdr (assoc "Content-Encoding" headers))) + (transfer (cdr (assoc "Transfer-Encoding" headers)))) + (when content + (set-process-plist proc + (append + (list :content-encoding + (ecase (intern content) + ((compress x-compress) (ws-encoding-cmd-to-fn ws-compress-cmd)) + ((deflate x-deflate) (ws-encoding-cmd-to-fn ws-deflate-cmd)) + ((gzip x-gzip) (ws-encoding-cmd-to-fn ws-gzip-cmd)) + (identity #'identity) + ((exi pack200-zip) + (ws-error proc "`%s' Content-encoding not supported." + content)))) + (process-plist proc)))) + (when transfer + (set-process-plist proc + (append + (when (string= transfer "chunked") (list :ender "0\r\n\r\n")) + (list :transfer-encoding + (ecase (intern transfer) + (chunked #'ws-chunk) + ((compress x-compress) (ws-encoding-cmd-to-fn ws-compress-cmd)) + ((deflate x-deflate) (ws-encoding-cmd-to-fn ws-deflate-cmd)) + ((gzip x-gzip) (ws-encoding-cmd-to-fn ws-gzip-cmd)))) + (process-plist proc))))) + (let ((headers + (cons + (format "HTTP/1.1 %d %s" code (cdr (assoc code ws-status-codes))) + (mapcar (lambda (h) (format "%s: %s" (car h) (cdr h))) headers)))) + (setcdr (last headers) (list "" "")) + (process-send-string proc (mapconcat #'identity headers "\r\n")))) + +(defun ws-send (proc string) + "Send STRING to process PROC. +If any Content or Transfer encodings are in use, apply them to +STRING before sending." + (let + ((cc (or (plist-get (process-plist proc) :content-encoding) #'identity)) + (tc (or (plist-get (process-plist proc) :transfer-encoding) #'identity))) + (process-send-string proc (funcall tc (funcall cc string))))) + +(defun ws-send-500 (proc &rest msg-and-args) + "Send 500 \"Internal Server Error\" to PROC with an optional message." + (ws-response-header proc 500 + '("Content-type" . "text/plain")) + (process-send-string proc (if msg-and-args + (apply #'format msg-and-args) + "500 Internal Server Error")) + (throw 'close-connection nil)) + +(defun ws-send-404 (proc &rest msg-and-args) + "Send 404 \"Not Found\" to PROC with an optional message." + (ws-response-header proc 404 + '("Content-type" . "text/plain")) + (process-send-string proc (if msg-and-args + (apply #'format msg-and-args) + "404 Not Found")) + (throw 'close-connection nil)) + +(defun ws-send-file (proc path &optional mime-type) + "Send PATH to PROC. +Optionally explicitly set MIME-TYPE, otherwise it is guessed by +`mm-default-file-encoding'." + (let ((mime (or mime-type + (mm-default-file-encoding path) + "application/octet-stream"))) + (process-send-string proc + (with-temp-buffer + (insert-file-contents-literally path) + (ws-response-header proc 200 + (cons "Content-type" mime) + (cons "Content-length" (- (point-max) (point-min)))) + (buffer-string))))) + +(defun ws-send-directory-list (proc directory &optional match) + "Send a listing of files in DIRECTORY to PROC. +Optional argument MATCH is passed to `directory-files' and may be +used to limit the files sent." + (ws-response-header proc 200 (cons "Content-type" "text/html")) + (process-send-string proc + (concat ""))) + +(defun ws-in-directory-p (parent path) + "Check if PATH is under the PARENT directory. +If so return PATH, if not return nil." + (if (zerop (length path)) + parent + (let ((expanded (expand-file-name path parent))) + (and (>= (length expanded) (length parent)) + (string= parent (substring expanded 0 (length parent))) + expanded)))) + +(defun ws-with-authentication (handler credentials + &optional realm unauth invalid) + "Return a version of HANDLER protected by CREDENTIALS. +HANDLER should be a function as passed to `ws-start', and +CREDENTIALS should be an alist of elements of the form (USERNAME +. PASSWORD). + +Optional argument REALM sets the realm in the authentication +challenge. Optional arguments UNAUTH and INVALID should be +functions which are called on the request when no authentication +information, or invalid authentication information are provided +respectively." + (lexical-let ((handler handler) + (credentials credentials) + (realm realm) + (unauth unauth) + (invalid invalid)) + (lambda (request) + (with-slots (process headers) request + (let ((auth (cddr (assoc :AUTHORIZATION headers)))) + (cond + ;; no authentication information provided + ((not auth) + (if unauth + (funcall unauth request) + (ws-response-header process 401 + (cons "WWW-Authenticate" + (format "Basic realm=%S" (or realm "restricted"))) + '("Content-type" . "text/plain")) + (process-send-string process "authentication required"))) + ;; valid authentication information + ((string= (cdr auth) (cdr (assoc (car auth) credentials))) + (funcall handler request)) + ;; invalid authentication information + (t + (if invalid + (funcall invalid request) + (ws-response-header process 403 '("Content-type" . "text/plain")) + (process-send-string process "invalid credentials"))))))))) + +(defun ws-web-socket-handshake (key) + "Perform the handshake defined in RFC6455." + (base64-encode-string (sha1 (concat (ws-trim key) ws-guid) nil nil 'binary))) + +(provide 'web-server) +;;; web-server.el ends here diff --git a/packages/web-server/web-server.info b/packages/web-server/web-server.info new file mode 100644 index 0000000..a0941e6 --- /dev/null +++ b/packages/web-server/web-server.info @@ -0,0 +1,2083 @@ +This is web-server.info, produced by makeinfo version 5.2 from +web-server.texi. + +This file documents the Emacs Web Server (web-server) + + Copyright (C) 2013 Eric Schulte + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Section being “GNU GENERAL PUBLIC + LICENSE,” A copy of the license is included in the section entitled + “GNU Free Documentation License.” +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Web Server: (web-server). Web Server for Emacs. +END-INFO-DIR-ENTRY + + +File: web-server.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +Emacs Web Server User Manual +**************************** + +This file documents the Emacs Web Server (web-server) + + Copyright (C) 2013 Eric Schulte + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Section being “GNU GENERAL PUBLIC + LICENSE,” A copy of the license is included in the section entitled + “GNU Free Documentation License.” + +* Menu: + +* Introduction:: Overview of the Emacs Web Server +* Handlers:: Handlers respond to HTTP requests +* Requests:: Getting information on HTTP requests +* Usage Examples:: Examples demonstrating usage +* Function Index:: List of Functions + +Appendices + +* Copying:: The GNU General Public License gives + you permission to redistribute GNU Emacs on + certain terms; it also explains that there is + no warranty. +* GNU Free Documentation License:: The license for this documentation. +* Index:: Complete index. + + + + + +File: web-server.info, Node: Introduction, Next: Handlers, Prev: Top, Up: Top + +1 Introduction +************** + +The Emacs Web Server is a Web server implemented entirely in Emacs Lisp. +HTTP requests are matched to handlers (*note Handlers::) which are Emacs +Lisp functions. Handlers receive as their only argument a request +object (*note Requests::) which holds information about the request and +a process holding the HTTP network connection. Handlers write their +responses directly to the network process. + + A number of examples (*note Usage Examples::) demonstrate usage of +the Emacs Web Server. All public functions of the Emacs Web Server are +listed (*note Function Index::). + + +File: web-server.info, Node: Handlers, Next: Requests, Prev: Handlers, Up: Top + +2 Handlers +********** + +The function ‘ws-start’ takes takes two arguments ‘handlers’ and ‘port’. +It starts a server listening on ‘port’ responding to requests with +‘handlers’. ‘Handlers’ may be either a single function or an +association list composed of pairs of matchers and handler functions. +When ‘handlers’ is a single function the given function is used to serve +every request, when it is an association list, the function of the first +matcher to match each request handles that request. + +2.1 Matchers +============ + +Matchers may be a regular expression or a function. Regular expression +matchers consists of an HTTP header and a regular expression. When the +regular expression matches the content of the given header the matcher +succeeds and the associated handler is called. For example the +following matches any ‘GET’ request whose path starts with the substring +“foo”. + + (:GET . "^foo") + + A function matcher is a function which takes the request object +(*note Requests::) and succeeds when the function returns a non-nil +value. For example the following matcher matches every request, + + (lambda (_) t) + + and the following matches only requests in which the supplied +“number” parameter is odd. + + (lambda (request) + (oddp (string-to-number (cdr (assoc "number" request))))) + +2.2 Handler Function +==================== + +Each handler is a function which takes a request object (*note +Requests::) as its only argument. The function may respond to the +request by writing to the network process held in the ‘process’ field of +the request object. For example, the ‘process-send-string’ function may +be used to write string data to a request as in the following. + + (process-send-string (process request) "hello world") + + When the handler function exits the connection is terminated unless +the handler function returns the keyword ‘:keep-alive’. + + +File: web-server.info, Node: Requests, Next: Usage Examples, Prev: Handlers, Up: Top + +3 Requests +********** + +Each HTTP requests is represented using a ‘ws-request’ object (*note +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 ‘ws-request’ object holds +the network process in the ‘process’ and holds all HTTP headers and +request GET or POST parameters in the ‘headers’ alist. HTML Headers are +keyed using uppercase keywords (e.g., ‘:GET’), and user supplied +parameters are keyed using the string name of the parameter. + + The ‘process’ field may be used by handlers to send data to a client +as in the following example. + + (process-send-string (process request) "hello world") + + The ‘headers’ field may be used to access request information such as +the requested path, + + (cdr (assoc :GET (headers request))) + + or named parameters as from a web form. + + (cdr (assoc "message" (headers request))) + + +File: web-server.info, Node: Usage Examples, Next: Hello World, Prev: Requests, Up: Top + +4 Usage Examples +**************** + +These examples demonstrate usage. +* Menu: + +* Hello World:: Serve “Hello World” to every request +* Hello World UTF8:: Serve “Hello World” w/UTF8 encoding +* Hello World HTML:: Serve “Hello World” in HTML +* File Server:: Serve files from a document root +* URL Parameter Echo:: Echo parameters from a URL query string +* POST Echo:: Echo POST parameters back +* Basic Authentication:: BASIC HTTP authentication +* Org-mode Export:: Export files to HTML and Tex +* File Upload:: Upload files and return their sha1sum +* Web Socket:: Web socket echo server +* Gzipped Transfer Encoding:: Gzip content encoding +* Chunked Transfer Encoding:: Chunked transfer encoding + + +File: web-server.info, Node: Hello World, Next: Hello World UTF8, Prev: Usage Examples, Up: Usage Examples + +4.1 Hello World +=============== + +The simplest possible “hello world” example. The handler consists of a +single (matcher . handler) pair. The function matcher matches _every_ +incoming HTTP request. The handler responds by setting the content type +to ‘text/plain’, and then sending the string “hello world”. When the +handler exits the network connection of the request is closed. + +;;; hello-world.el --- simple hello world server using Emacs Web Server +(ws-start + (lambda (request) + (with-slots (process headers) request + (ws-response-header process 200 '("Content-type" . "text/plain")) + (process-send-string process "hello world"))) + 9000) + + +File: web-server.info, Node: Hello World UTF8, Next: Hello World HTML, Prev: Hello World, Up: Usage Examples + +4.2 Hello World UTF8 +==================== + +This example only differs from the previous in that the “Content-type” +indicates UTF8 encoded data, and the hello world sent is selected at +random from a list of different languages. + +;;; hello-world-utf8.el --- utf8 hello world server using Emacs Web Server +(ws-start + (lambda (request) + (with-slots (process headers) request + (let ((hellos '("こんにちは" + "안녕하세요" + "góðan dag" + "Grüßgott" + "hyvää päivää" + "yá'át'ééh" + "Γεια σας" + "Вiтаю" + "გამარჯობა" + "नमस्ते" + "你好"))) + (ws-response-header process 200 + '("Content-type" . "text/plain; charset=utf-8")) + (process-send-string process + (concat (nth (random (length hellos)) hellos) " world"))))) + 9001) + + +File: web-server.info, Node: Hello World HTML, Next: File Server, Prev: Hello World UTF8, Up: Usage Examples + +4.3 Hello World HTML +==================== + +;;; hello-world-html.el --- html hello world server using Emacs Web Server +(ws-start + (lambda (request) + (with-slots (process headers) request + (ws-response-header process 200 '("Content-type" . "text/html")) + (process-send-string process " + + Hello World + + + hello world + +"))) + 9002) + + This variation of the “hello world” example sends a ‘text/html’ +response instead of a simple ‘text/plain’ response. + + +File: web-server.info, Node: File Server, Next: URL Parameter Echo, Prev: Hello World HTML, Up: Usage Examples + +4.4 File Server +=============== + +The following example implements a file server which will serve files +from the ‘docroot’ document root set to the current working directory in +this example. Four helper functions are used; ‘ws-in-directory-p’ is +used to check if the requested path is within the document root. If not +then ‘ws-send-404’ is used to send a default “File Not Found”. If so +then the file is served with ‘ws-send-file’ (which appropriately sets +the mime-type of the response based on the extension of the file) if it +is a file or is served with ‘ws-send-directory-list’ if it is a +directory. + +;;; file-server.el --- serve any files using Emacs Web Server +(lexical-let ((docroot default-directory)) + (ws-start + (lambda (request) + (with-slots (process headers) request + (let ((path (substring (cdr (assoc :GET headers)) 1))) + (if (ws-in-directory-p docroot path) + (if (file-directory-p path) + (ws-send-directory-list process + (expand-file-name path docroot) "^[^\.]") + (ws-send-file process (expand-file-name path docroot))) + (ws-send-404 process))))) + 9003)) + + +File: web-server.info, Node: URL Parameter Echo, Next: POST Echo, Prev: File Server, Up: Usage Examples + +4.5 URL Parameter Echo +====================== + +This example demonstrates access of URL-encoded parameters in a ‘GET’ +request. For example the following URL + will render as the +following HTML table. + +foo bar +baz qux + +;;; url-param-echo.el --- echo back url-paramed message using Emacs Web Server +(ws-start + '(((:GET . ".*") . + (lambda (request) + (with-slots (process headers) request + (ws-response-header process 200 '("Content-type" . "text/html")) + (process-send-string process + (concat "URL Parameters:
" + (mapconcat (lambda (pair) + (format "" + (car pair) (cdr pair))) + (cl-remove-if-not (lambda (el) (stringp (car el))) + headers) + "") + "
%s%s
")))))) + 9004) + + +File: web-server.info, Node: POST Echo, Next: Basic Authentication, Prev: URL Parameter Echo, Up: Usage Examples + +4.6 POST Echo +============= + +The following example echos back the content of the “message” field in a +‘POST’ request. + +;;; post-echo.el --- echo back posted message using Emacs Web Server +(ws-start + '(((:POST . ".*") . + (lambda (request) + (with-slots (process headers) request + (let ((message (cdr (assoc "message" headers)))) + (ws-response-header process 200 '("Content-type" . "text/plain")) + (process-send-string process + (if message + (format "you said %S\n" (cdr (assoc 'content message))) + "This is a POST request, but it has no \"message\".\n")))))) + ((:GET . ".*") . + (lambda (request) + (with-slots (process) request + (ws-response-header process 200 '("Content-type" . "text/plain")) + (process-send-string process + "This is a GET request not a POST request.\n"))))) + 9005) + + +File: web-server.info, Node: Basic Authentication, Next: Org-mode Export, Prev: POST Echo, Up: Usage Examples + +4.7 Basic Authentication +======================== + +The following example demonstrates BASIC HTTP authentication. The +handler prompts an unauthenticated client for authentication by sending +a “WWW-Authenticate” header. + + (ws-response-header process 401 + '("WWW-Authenticate" . "Basic realm=\"example\"") + '("Content-type" . "text/plain")) + + The client replies by setting the “Authorization” HTTP header which +is parsed into a list of the form ‘(PROTOCOL USERNAME . PASSWORD)’. +Currently only BASIC HTTP authentication is supported. + +Note: BASIC HTTP authentication passes user credentials in plain text +between the client and the server and should generally only be used with +HTTPS network encryption. While the Emacs web server currently doesn’t +support HTTPS network encryption it may be run behind an HTTPS proxy +server (e.g., Apache or Nginx) with HTTPS support. + +;;; basic-authentication.el --- basic authentication +(lexical-let ((users '(("foo" . "bar") + ("baz" . "qux")))) + (ws-start + (ws-with-authentication + (lambda (request) + (with-slots (process headers) request + (let ((user (caddr (assoc :AUTHORIZATION headers)))) + (ws-response-header process 200 '("Content-type" . "text/plain")) + (process-send-string process (format "welcome %s" user))))) + users) + 9006)) + + +File: web-server.info, Node: Org-mode Export, Next: File Upload, Prev: Basic Authentication, Up: Usage Examples + +4.8 Org-mode Export +=================== + +The following example exports a directory of Org-mode files as either +text, HTML or LaTeX. The Org-mode export engine is used to export files +on-demand as they are requested. + +;;; org-mode-file-server.el --- serve on-demand exported Org-mode files +(lexical-let ((docroot "/tmp/")) + (ws-start + (lambda (request) + (with-slots (process headers) request + (let ((path (ws-in-directory-p ; check if path is in docroot + docroot (substring (cdr (assoc :GET headers)) 1)))) + (unless path (ws-send-404 process)) ; send 404 if not in docroot + (if (file-directory-p path) + (progn ;; send directory listing, convert org files to html/tex/txt + (ws-response-header proc 200 (cons "Content-type" "text/html")) + (process-send-string proc + (concat "
"))) + ;; Export the file as requested and return the result + (let* ((base (file-name-sans-extension path)) + (type (case (intern (downcase (file-name-extension path))) + (html 'html) + (tex 'latex) + (txt 'ascii) + (t (ws-error process "%S export not supported" + (file-name-extension path))))) + (orig (concat base ".org"))) + (unless (file-exists-p orig) (ws-send-404 process)) + (save-window-excursion (find-file orig) + (org-export-to-file type path)) + (ws-send-file process path)))))) + 9007)) + + +File: web-server.info, Node: File Upload, Next: Web Socket, Prev: Org-mode Export, Up: Usage Examples + +4.9 File Upload +=============== + +The following example demonstrates accessing an uploaded file. This +simple server accesses the file named “file” and returns it’s sha1sum +and file name. + +;;; file-upload.el --- use an uploaded file +(ws-start + '(((:POST . ".*") . + (lambda (request) + (with-slots (process headers) request + (ws-response-header process 200 '("Content-type" . "text/plain")) + (let ((file (cdr (assoc "file" headers)))) + (process-send-string process + (concat (sha1 (cdr (assoc 'content file))) " " + (cdr (assoc 'filename file)) "\n"))))))) + 9008) + + A file may be uploaded from an HTML form, or using the ‘curl’ program +as in the following example. + + $ curl -s -F file=usr/share/emacs/24.3/etc/COPYING localhost:9008 + 8624bcdae55baeef00cd11d5dfcfa60f68710a02 COPYING + $ sha1sum /usr/share/emacs/24.3/etc/COPYING + 8624bcdae55baeef00cd11d5dfcfa60f68710a02 /usr/share/emacs/24.3/etc/COPYING + + +File: web-server.info, Node: Web Socket, Next: Chunked Transfer Encoding, Prev: File Upload, Up: Usage Examples + +4.10 Web Socket +=============== + +Example demonstrating the use of web sockets for full duplex +communication between clients and the server. Handlers may use the +‘ws-web-socket-connect’ function (*note ws-web-socket-connect::) to +check for and respond to a web socket upgrade request sent by the client +(as demonstrated with the ‘new WebSocket’ JavaScript code in the +example). Upon successfully initializing a web socket connection the +call to ‘ws-web-socket-connect’ will return the web socket network +process. This process may then be used by the server to communicate +with the client over the web socket using the ‘process-send-string’ and +‘ws-web-socket-frame’ functions. All web socket communication must be +wrapped in frames using the ‘ws-web-socket-frame’ function. + + The handler must pass a function as the second argument to +‘ws-web-socket-connect’. This function will be called on every web +socket message received from the client. + +Note: in order to keep the web socket connection alive the request +handler from which ‘ws-web-socket-connect’ is called must return the +‘:keep-alive’ keyword, as demonstrated in the example. + +;;; web-sockets.el --- communicate via web-sockets + +(lexical-let* ((web-socket-port 9009) + (web-socket-page + (format " + + + + +
    + +
  1. Press \"connect\" to initialize the web socket connection to + the server. The server will complete the web socket + handshake at which point you'll see an alert with the text + \"connected\".
  2. + +
  3. Press \"message\" to send the string \"foo\" to the server. + The server will reply with the text \"you said: foo\" which + you will see in an alert as \"server: you said: foo\".
  4. + +
  5. Press \"close\" to close the connection. After the server + responds with a close frame you will see an alert with the + text \"connection closed\".
  6. + +
+
connect +message +close + +" web-socket-port))) + (ws-start + (lambda (request) + (with-slots (process headers) request + ;; if a web-socket request, then connect and keep open + (if (ws-web-socket-connect request + (lambda (proc string) + (process-send-string proc + (ws-web-socket-frame (concat "you said: " string))))) + (prog1 :keep-alive (setq my-connection process)) + ;; otherwise send the index page + (ws-response-header process 200 '("Content-type" . "text/html")) + (process-send-string process web-socket-page)))) + web-socket-port)) + + +File: web-server.info, Node: Gzipped Transfer Encoding, Next: Chunked Transfer Encoding, Prev: Web Socket, Up: Usage Examples + +4.11 Gzipped Transfer Encoding +============================== + +HTTP Responses may be compressed by setting the “gzip” (or “compress” or +“deflate”) content- or transfer-encoding HTTP headers in +‘ws-response-header’. Any further data sent to the process using +‘ws-send’ will automatically be appropriately compressed. + +;;; content-encoding-gzip.el -- gzip content encoding +(ws-start + (lambda (request) + (with-slots (process headers) request + (ws-response-header process 200 + '("Content-type" . "text/plain; charset=utf-8") + '("Content-Encoding" . "x-gzip")) + (let ((s "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec +hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam +nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis +natoque penatibus et magnis dis parturient montes, nascetur +ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique +diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam +vestibulum accumsan nisl. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec +hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam +nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis +natoque penatibus et magnis dis parturient montes, nascetur +ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique +diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam +vestibulum accumsan nisl.")) + (ws-send process s)))) + 9016) + + +File: web-server.info, Node: Chunked Transfer Encoding, Next: Function Index, Prev: Web Socket, Up: Usage Examples + +4.12 Chunked Transfer Encoding +============================== + +Similarly, HTTP Responses may be sent using the “chunked” transfer +encoding by passing the appropriate HTTP header to ‘ws-response-header’. +Any further data sent to the process using ‘ws-send’ will automatically +be appropriately encoded for chunked transfer. + +;;; transfer-encoding-chunked.el -- chunked transfer encoding +(ws-start + (lambda (request) + (let ((s " +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec +hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam +nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis +natoque penatibus et magnis dis parturient montes, nascetur +ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique +diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam +vestibulum accumsan nisl. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec +hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam +nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis +natoque penatibus et magnis dis parturient montes, nascetur +ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique +diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam +vestibulum accumsan nisl. +")) + (with-slots (process headers) request + (ws-response-header process 200 + '("Content-type" . "text/plain; charset=utf-8") + '("Transfer-Encoding" . "chunked")) + (ws-send process s) (sit-for 0.5) + (ws-send process s) (sit-for 0.5) + (ws-send process s) (sit-for 0.5) + (ws-send process s)))) + 9017) + + +File: web-server.info, Node: Function Index, Next: Copying, Prev: Usage Examples, Up: Top + +5 Function Index +**************** + +The following functions implement the Emacs Web Server public API. + +5.1 Objects +=========== + +The following objects represent web servers and requests. + + -- Class: ws-server handlers process port requests + Every Emacs web server is an instance of the ‘ws-server’ class. + Each instance includes the ‘handlers’ association list and ‘port’ + passed to ‘ws-start’, as well as the server network ‘process’ and a + list of all active ‘requests’. + + -- Class: ws-request process pending context boundary index active + headers + The ‘ws-request’ class represents an active web request. The + ‘process’ field holds the network process of the client and may be + used by handlers to respond to requests. The ‘headers’ field holds + an alist of information on the request for use by handlers. The + remaining ‘pending’, ‘context’, ‘boundary’, ‘index’ and ‘active’ + fields are used to maintain header parsing information across calls + to the ‘ws-filter’ function. + +5.2 Starting and Stopping Servers +================================= + +The following functions start and stop Emacs web servers. The +‘ws-servers’ list holds all running servers. + + -- Function: ws-start handlers port &optional log-buffer &rest + network-args + ‘ws-start’ starts a server listening on ‘port’ using ‘handlers’ + (*note Handlers::) to match and respond to requests. An instance + of the ‘ws-server’ class is returned. + + -- Variable: ws-servers + The ‘ws-servers’ list holds all active Emacs web servers. + + -- Function: ws-stop server + ‘ws-stop’ stops ‘server’ deletes all related processes, and frees + the server’s port. Evaluate the following to stop all emacs web + servers. + (mapc #'ws-stop ws-servers) + + -- Function: ws-stop-all + ‘ws-stop-all’ stops all emacs web servers by mapping ‘ws-stop’ over + ‘ws-servers’. + +5.3 Convenience Functions +========================= + +The following convenience functions automate many common tasks +associated with responding to HTTP requests. + + -- Function: ws-response-header process code &rest headers + Send the headers required to start an HTTP response to ‘proc’. + ‘proc’ should be a ‘ws-request’ ‘proc’ of an active request. + + For example start a standard 200 “OK” HTML response with the + following. + + (ws-response-header process 200 '("Content-type" . "text/html")) + + The encoding may optionally be set in the HTTP header. Send a UTF8 + encoded response with the following. + + (ws-response-header process 200 + '("Content-type" . "text/plain; charset=utf-8")) + + Additionally, when “Content-Encoding” or “Transfer-Encoding” + headers are supplied any subsequent data written to ‘proc’ using + ‘ws-send’ will be encoded appropriately including sending the + appropriate data upon the end of transmission for chunked transfer + encoding. + + For example with the header ‘("Content-Encoding" . "gzip")’, any + data subsequently written to ‘proc’ using ‘ws-send’ will be + compressed using the command specified in ‘ws-gzip-cmd’. See *note + Gzipped Transfer Encoding:: and *note Chunked Transfer Encoding:: + for more complete examples. + + -- Function: ws-send proc string + Send ‘string’ to process ‘proc’. If any Content or Transfer + encodings are in use, apply them to ‘string’ before sending. + + -- Function: ws-send-500 process &rest msg-and-args + ‘ws-send-500’ sends a default 500 “Internal Server Error” response + to ‘process’. + + -- Function: ws-send-404 process &rest msg-and-args + ‘ws-send-500’ sends a default 404 “File Not Found” response to + ‘process’. + + -- Function: ws-send-file process path &optional mime-type + ‘ws-send-file’ sends the file located at ‘path’ to ‘process’. If + the optional ‘mime-type’ is not set, then the mime-type is + determined by calling ‘mm-default-file-encoding’ on ‘path’ or is + set to “application/octet-stream” if no mime-type can be + determined. + + -- Function: ws-send-directory-list process directory &optional match + ‘ws-send-directory-list’ sends the a listing of the files located + in ‘directory’ to ‘process’. The list is sent as an HTML list of + links to the files. Optional argument ‘match’ may be set to a + regular expression, in which case only those files that match are + listed. + + -- Function: ws-in-directory-p parent path + Check if ‘path’ is under the ‘parent’ directory. + + (ws-in-directory-p "/tmp/" "pics") + ⇒ "/tmp/pics" + + (ws-in-directory-p "/tmp/" "..") + ⇒ nil + + (ws-in-directory-p "/tmp/" "~/pics") + ⇒ nil + + -- Function: ws-with-authentication handler credentials &optional realm + unauth invalid + Return a version of ‘handler’ which is protected by ‘credentials’. + Handler should be a normal handler function (*note Handlers::) and + ‘credentials’ should be an association list of usernames and + passwords. + + For example, a server running the following handlers, + + (list (cons '(:GET . ".*") 'view-handler) + (cons '(:POST . ".*") 'edit-handler)) + + could have authorization added by changing the handlers to the + following. + + (list (cons '(:GET . ".*") view-handler) + (cons '(:POST . ".*") (ws-with-authentication + 'org-ehtml-edit-handler + '(("admin" . "password"))))) + + -- Function: ws-web-socket-connect request handler + If ‘request’ is a web socket upgrade request (indicated by the + presence of the ‘:SEC-WEBSOCKET-KEY’ header argument) establish a + web socket connection to the client. Call ‘handler’ on web socket + messages received from the client. + + (ws-web-socket-connect request + (lambda (proc string) + (process-send-string proc + (ws-web-socket-frame (concat "you said: " string))))) + ⇒ #> + +5.4 Customization Variables +=========================== + +The following variables may be changed to control the behavior of the +web server. Specifically the ‘ws-*-cmd’ variables specify the command +lines used to compress data according to content and or transfer +encoding HTTP headers passed to *note ws-response-header::. + + -- Variable: ws-compress-cmd + Command used for the “compress” Content or Transfer coding. + + -- Variable: ws-deflate-cmd + Command used for the “deflate” Content or Transfer coding. + + -- Variable: ws-gzip-cmd + Command used for the “gzip” Content or Transfer coding. + + +File: web-server.info, Node: Copying, Next: GNU Free Documentation License, Prev: Function Index, Up: Top + +Appendix A GNU GENERAL PUBLIC LICENSE +************************************* + + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. + + Everyone is permitted to copy and distribute verbatim copies of this + license document, but changing it is not allowed. + +Preamble +======== + +The GNU General Public License is a free, copyleft license for software +and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program—to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers’ and authors’ protection, the GPL clearly explains +that there is no warranty for this free software. For both users’ and +authors’ sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users’ freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + +TERMS AND CONDITIONS +==================== + + 0. Definitions. + + “This License” refers to version 3 of the GNU General Public + License. + + “Copyright” also means copyright-like laws that apply to other + kinds of works, such as semiconductor masks. + + “The Program” refers to any copyrightable work licensed under this + License. Each licensee is addressed as “you”. “Licensees” and + “recipients” may be individuals or organizations. + + To “modify” a work means to copy from or adapt all or part of the + work in a fashion requiring copyright permission, other than the + making of an exact copy. The resulting work is called a “modified + version” of the earlier work or a work “based on” the earlier work. + + A “covered work” means either the unmodified Program or a work + based on the Program. + + To “propagate” a work means to do anything with it that, without + permission, would make you directly or secondarily liable for + infringement under applicable copyright law, except executing it on + a computer or modifying a private copy. Propagation includes + copying, distribution (with or without modification), making + available to the public, and in some countries other activities as + well. + + To “convey” a work means any kind of propagation that enables other + parties to make or receive copies. Mere interaction with a user + through a computer network, with no transfer of a copy, is not + conveying. + + An interactive user interface displays “Appropriate Legal Notices” + to the extent that it includes a convenient and prominently visible + feature that (1) displays an appropriate copyright notice, and (2) + tells the user that there is no warranty for the work (except to + the extent that warranties are provided), that licensees may convey + the work under this License, and how to view a copy of this + License. If the interface presents a list of user commands or + options, such as a menu, a prominent item in the list meets this + criterion. + + 1. Source Code. + + The “source code” for a work means the preferred form of the work + for making modifications to it. “Object code” means any non-source + form of a work. + + A “Standard Interface” means an interface that either is an + official standard defined by a recognized standards body, or, in + the case of interfaces specified for a particular programming + language, one that is widely used among developers working in that + language. + + The “System Libraries” of an executable work include anything, + other than the work as a whole, that (a) is included in the normal + form of packaging a Major Component, but which is not part of that + Major Component, and (b) serves only to enable use of the work with + that Major Component, or to implement a Standard Interface for + which an implementation is available to the public in source code + form. A “Major Component”, in this context, means a major + essential component (kernel, window system, and so on) of the + specific operating system (if any) on which the executable work + runs, or a compiler used to produce the work, or an object code + interpreter used to run it. + + The “Corresponding Source” for a work in object code form means all + the source code needed to generate, install, and (for an executable + work) run the object code and to modify the work, including scripts + to control those activities. However, it does not include the + work’s System Libraries, or general-purpose tools or generally + available free programs which are used unmodified in performing + those activities but which are not part of the work. For example, + Corresponding Source includes interface definition files associated + with source files for the work, and the source code for shared + libraries and dynamically linked subprograms that the work is + specifically designed to require, such as by intimate data + communication or control flow between those subprograms and other + parts of the work. + + The Corresponding Source need not include anything that users can + regenerate automatically from other parts of the Corresponding + Source. + + The Corresponding Source for a work in source code form is that + same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of + copyright on the Program, and are irrevocable provided the stated + conditions are met. This License explicitly affirms your unlimited + permission to run the unmodified Program. The output from running + a covered work is covered by this License only if the output, given + its content, constitutes a covered work. This License acknowledges + your rights of fair use or other equivalent, as provided by + copyright law. + + You may make, run and propagate covered works that you do not + convey, without conditions so long as your license otherwise + remains in force. You may convey covered works to others for the + sole purpose of having them make modifications exclusively for you, + or provide you with facilities for running those works, provided + that you comply with the terms of this License in conveying all + material for which you do not control copyright. Those thus making + or running the covered works for you must do so exclusively on your + behalf, under your direction and control, on terms that prohibit + them from making any copies of your copyrighted material outside + their relationship with you. + + Conveying under any other circumstances is permitted solely under + the conditions stated below. Sublicensing is not allowed; section + 10 makes it unnecessary. + + 3. Protecting Users’ Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological + measure under any applicable law fulfilling obligations under + article 11 of the WIPO copyright treaty adopted on 20 December + 1996, or similar laws prohibiting or restricting circumvention of + such measures. + + When you convey a covered work, you waive any legal power to forbid + circumvention of technological measures to the extent such + circumvention is effected by exercising rights under this License + with respect to the covered work, and you disclaim any intention to + limit operation or modification of the work as a means of + enforcing, against the work’s users, your or third parties’ legal + rights to forbid circumvention of technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program’s source code as you + receive it, in any medium, provided that you conspicuously and + appropriately publish on each copy an appropriate copyright notice; + keep intact all notices stating that this License and any + non-permissive terms added in accord with section 7 apply to the + code; keep intact all notices of the absence of any warranty; and + give all recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, + and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to + produce it from the Program, in the form of source code under the + terms of section 4, provided that you also meet all of these + conditions: + + a. The work must carry prominent notices stating that you + modified it, and giving a relevant date. + + b. The work must carry prominent notices stating that it is + released under this License and any conditions added under + section 7. This requirement modifies the requirement in + section 4 to “keep intact all notices”. + + c. You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable + section 7 additional terms, to the whole of the work, and all + its parts, regardless of how they are packaged. This License + gives no permission to license the work in any other way, but + it does not invalidate such permission if you have separately + received it. + + d. If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has + interactive interfaces that do not display Appropriate Legal + Notices, your work need not make them do so. + + A compilation of a covered work with other separate and independent + works, which are not by their nature extensions of the covered + work, and which are not combined with it such as to form a larger + program, in or on a volume of a storage or distribution medium, is + called an “aggregate” if the compilation and its resulting + copyright are not used to limit the access or legal rights of the + compilation’s users beyond what the individual works permit. + Inclusion of a covered work in an aggregate does not cause this + License to apply to the other parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms + of sections 4 and 5, provided that you also convey the + machine-readable Corresponding Source under the terms of this + License, in one of these ways: + + a. Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b. Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that + product model, to give anyone who possesses the object code + either (1) a copy of the Corresponding Source for all the + software in the product that is covered by this License, on a + durable physical medium customarily used for software + interchange, for a price no more than your reasonable cost of + physically performing this conveying of source, or (2) access + to copy the Corresponding Source from a network server at no + charge. + + c. Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, + and only if you received the object code with such an offer, + in accord with subsection 6b. + + d. Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to + the Corresponding Source in the same way through the same + place at no further charge. You need not require recipients + to copy the Corresponding Source along with the object code. + If the place to copy the object code is a network server, the + Corresponding Source may be on a different server (operated by + you or a third party) that supports equivalent copying + facilities, provided you maintain clear directions next to the + object code saying where to find the Corresponding Source. + Regardless of what server hosts the Corresponding Source, you + remain obligated to ensure that it is available for as long as + needed to satisfy these requirements. + + e. Convey the object code using peer-to-peer transmission, + provided you inform other peers where the object code and + Corresponding Source of the work are being offered to the + general public at no charge under subsection 6d. + + A separable portion of the object code, whose source code is + excluded from the Corresponding Source as a System Library, need + not be included in conveying the object code work. + + A “User Product” is either (1) a “consumer product”, which means + any tangible personal property which is normally used for personal, + family, or household purposes, or (2) anything designed or sold for + incorporation into a dwelling. In determining whether a product is + a consumer product, doubtful cases shall be resolved in favor of + coverage. For a particular product received by a particular user, + “normally used” refers to a typical or common use of that class of + product, regardless of the status of the particular user or of the + way in which the particular user actually uses, or expects or is + expected to use, the product. A product is a consumer product + regardless of whether the product has substantial commercial, + industrial or non-consumer uses, unless such uses represent the + only significant mode of use of the product. + + “Installation Information” for a User Product means any methods, + procedures, authorization keys, or other information required to + install and execute modified versions of a covered work in that + User Product from a modified version of its Corresponding Source. + The information must suffice to ensure that the continued + functioning of the modified object code is in no case prevented or + interfered with solely because modification has been made. + + If you convey an object code work under this section in, or with, + or specifically for use in, a User Product, and the conveying + occurs as part of a transaction in which the right of possession + and use of the User Product is transferred to the recipient in + perpetuity or for a fixed term (regardless of how the transaction + is characterized), the Corresponding Source conveyed under this + section must be accompanied by the Installation Information. But + this requirement does not apply if neither you nor any third party + retains the ability to install modified object code on the User + Product (for example, the work has been installed in ROM). + + The requirement to provide Installation Information does not + include a requirement to continue to provide support service, + warranty, or updates for a work that has been modified or installed + by the recipient, or for the User Product in which it has been + modified or installed. Access to a network may be denied when the + modification itself materially and adversely affects the operation + of the network or violates the rules and protocols for + communication across the network. + + Corresponding Source conveyed, and Installation Information + provided, in accord with this section must be in a format that is + publicly documented (and with an implementation available to the + public in source code form), and must require no special password + or key for unpacking, reading or copying. + + 7. Additional Terms. + + “Additional permissions” are terms that supplement the terms of + this License by making exceptions from one or more of its + conditions. Additional permissions that are applicable to the + entire Program shall be treated as though they were included in + this License, to the extent that they are valid under applicable + law. If additional permissions apply only to part of the Program, + that part may be used separately under those permissions, but the + entire Program remains governed by this License without regard to + the additional permissions. + + When you convey a copy of a covered work, you may at your option + remove any additional permissions from that copy, or from any part + of it. (Additional permissions may be written to require their own + removal in certain cases when you modify the work.) You may place + additional permissions on material, added by you to a covered work, + for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material + you add to a covered work, you may (if authorized by the copyright + holders of that material) supplement the terms of this License with + terms: + + a. Disclaiming warranty or limiting liability differently from + the terms of sections 15 and 16 of this License; or + + b. Requiring preservation of specified reasonable legal notices + or author attributions in that material or in the Appropriate + Legal Notices displayed by works containing it; or + + c. Prohibiting misrepresentation of the origin of that material, + or requiring that modified versions of such material be marked + in reasonable ways as different from the original version; or + + d. Limiting the use for publicity purposes of names of licensors + or authors of the material; or + + e. Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f. Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified + versions of it) with contractual assumptions of liability to + the recipient, for any liability that these contractual + assumptions directly impose on those licensors and authors. + + All other non-permissive additional terms are considered “further + restrictions” within the meaning of section 10. If the Program as + you received it, or any part of it, contains a notice stating that + it is governed by this License along with a term that is a further + restriction, you may remove that term. If a license document + contains a further restriction but permits relicensing or conveying + under this License, you may add to a covered work material governed + by the terms of that license document, provided that the further + restriction does not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you + must place, in the relevant source files, a statement of the + additional terms that apply to those files, or a notice indicating + where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in + the form of a separately written license, or stated as exceptions; + the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly + provided under this License. Any attempt otherwise to propagate or + modify it is void, and will automatically terminate your rights + under this License (including any patent licenses granted under the + third paragraph of section 11). + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly and + finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from + that copyright holder, and you cure the violation prior to 30 days + after your receipt of the notice. + + Termination of your rights under this section does not terminate + the licenses of parties who have received copies or rights from you + under this License. If your rights have been terminated and not + permanently reinstated, you do not qualify to receive new licenses + for the same material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or + run a copy of the Program. Ancillary propagation of a covered work + occurring solely as a consequence of using peer-to-peer + transmission to receive a copy likewise does not require + acceptance. However, nothing other than this License grants you + permission to propagate or modify any covered work. These actions + infringe copyright if you do not accept this License. Therefore, + by modifying or propagating a covered work, you indicate your + acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically + receives a license from the original licensors, to run, modify and + propagate that work, subject to this License. You are not + responsible for enforcing compliance by third parties with this + License. + + An “entity transaction” is a transaction transferring control of an + organization, or substantially all assets of one, or subdividing an + organization, or merging organizations. If propagation of a + covered work results from an entity transaction, each party to that + transaction who receives a copy of the work also receives whatever + licenses to the work the party’s predecessor in interest had or + could give under the previous paragraph, plus a right to possession + of the Corresponding Source of the work from the predecessor in + interest, if the predecessor has it or can get it with reasonable + efforts. + + You may not impose any further restrictions on the exercise of the + rights granted or affirmed under this License. For example, you + may not impose a license fee, royalty, or other charge for exercise + of rights granted under this License, and you may not initiate + litigation (including a cross-claim or counterclaim in a lawsuit) + alleging that any patent claim is infringed by making, using, + selling, offering for sale, or importing the Program or any portion + of it. + + 11. Patents. + + A “contributor” is a copyright holder who authorizes use under this + License of the Program or a work on which the Program is based. + The work thus licensed is called the contributor’s “contributor + version”. + + A contributor’s “essential patent claims” are all patent claims + owned or controlled by the contributor, whether already acquired or + hereafter acquired, that would be infringed by some manner, + permitted by this License, of making, using, or selling its + contributor version, but do not include claims that would be + infringed only as a consequence of further modification of the + contributor version. For purposes of this definition, “control” + includes the right to grant patent sublicenses in a manner + consistent with the requirements of this License. + + Each contributor grants you a non-exclusive, worldwide, + royalty-free patent license under the contributor’s essential + patent claims, to make, use, sell, offer for sale, import and + otherwise run, modify and propagate the contents of its contributor + version. + + In the following three paragraphs, a “patent license” is any + express agreement or commitment, however denominated, not to + enforce a patent (such as an express permission to practice a + patent or covenant not to sue for patent infringement). To “grant” + such a patent license to a party means to make such an agreement or + commitment not to enforce a patent against the party. + + If you convey a covered work, knowingly relying on a patent + license, and the Corresponding Source of the work is not available + for anyone to copy, free of charge and under the terms of this + License, through a publicly available network server or other + readily accessible means, then you must either (1) cause the + Corresponding Source to be so available, or (2) arrange to deprive + yourself of the benefit of the patent license for this particular + work, or (3) arrange, in a manner consistent with the requirements + of this License, to extend the patent license to downstream + recipients. “Knowingly relying” means you have actual knowledge + that, but for the patent license, your conveying the covered work + in a country, or your recipient’s use of the covered work in a + country, would infringe one or more identifiable patents in that + country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or + arrangement, you convey, or propagate by procuring conveyance of, a + covered work, and grant a patent license to some of the parties + receiving the covered work authorizing them to use, propagate, + modify or convey a specific copy of the covered work, then the + patent license you grant is automatically extended to all + recipients of the covered work and works based on it. + + A patent license is “discriminatory” if it does not include within + the scope of its coverage, prohibits the exercise of, or is + conditioned on the non-exercise of one or more of the rights that + are specifically granted under this License. You may not convey a + covered work if you are a party to an arrangement with a third + party that is in the business of distributing software, under which + you make payment to the third party based on the extent of your + activity of conveying the work, and under which the third party + grants, to any of the parties who would receive the covered work + from you, a discriminatory patent license (a) in connection with + copies of the covered work conveyed by you (or copies made from + those copies), or (b) primarily for and in connection with specific + products or compilations that contain the covered work, unless you + entered into that arrangement, or that patent license was granted, + prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting + any implied license or other defenses to infringement that may + otherwise be available to you under applicable patent law. + + 12. No Surrender of Others’ Freedom. + + If conditions are imposed on you (whether by court order, agreement + or otherwise) that contradict the conditions of this License, they + do not excuse you from the conditions of this License. If you + cannot convey a covered work so as to satisfy simultaneously your + obligations under this License and any other pertinent obligations, + then as a consequence you may not convey it at all. For example, + if you agree to terms that obligate you to collect a royalty for + further conveying from those to whom you convey the Program, the + only way you could satisfy both those terms and this License would + be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have + permission to link or combine any covered work with a work licensed + under version 3 of the GNU Affero General Public License into a + single combined work, and to convey the resulting work. The terms + of this License will continue to apply to the part which is the + covered work, but the special requirements of the GNU Affero + General Public License, section 13, concerning interaction through + a network will apply to the combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new + versions of the GNU General Public License from time to time. Such + new versions will be similar in spirit to the present version, but + may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Program specifies that a certain numbered version of the GNU + General Public License “or any later version” applies to it, you + have the option of following the terms and conditions either of + that numbered version or of any later version published by the Free + Software Foundation. If the Program does not specify a version + number of the GNU General Public License, you may choose any + version ever published by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future + versions of the GNU General Public License can be used, that + proxy’s public statement of acceptance of a version permanently + authorizes you to choose that version for the Program. + + Later license versions may give you additional or different + permissions. However, no additional obligations are imposed on any + author or copyright holder as a result of your choosing to follow a + later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE + COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE + RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. + SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES + AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR + DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE + THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA + BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD + PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF + THE POSSIBILITY OF SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided + above cannot be given local legal effect according to their terms, + reviewing courts shall apply local law that most closely + approximates an absolute waiver of all civil liability in + connection with the Program, unless a warranty or assumption of + liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS +=========================== + +How to Apply These Terms to Your New Programs +============================================= + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least the +“copyright” line and a pointer to where the full notice is found. + + ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. + Copyright (C) YEAR NAME OF AUTHOR + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Also add information on how to contact you by electronic and paper +mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + PROGRAM Copyright (C) YEAR NAME OF AUTHOR + This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’. + This is free software, and you are welcome to redistribute it + under certain conditions; type ‘show c’ for details. + + The hypothetical commands ‘show w’ and ‘show c’ should show the +appropriate parts of the General Public License. Of course, your +program’s commands might be different; for a GUI interface, you would +use an “about box”. + + You should also get your employer (if you work as a programmer) or +school, if any, to sign a “copyright disclaimer” for the program, if +necessary. For more information on this, and how to apply and follow +the GNU GPL, see . + + The GNU General Public License does not permit incorporating your +program into proprietary programs. If your program is a subroutine +library, you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +GNU Lesser General Public License instead of this License. But first, +please read . + + +File: web-server.info, Node: GNU Free Documentation License, Next: Index, Prev: Copying, Up: Top + +Appendix B GNU Free Documentation License +***************************************** + + Version 1.3, 3 November 2008 + + Copyright © 2000, 2001, 2002, 2007, 2008, 2009 Free Software Foundation, Inc. + + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other + functional and useful document "free" in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or + noncommercially. Secondarily, this License preserves for the + author and publisher a way to get credit for their work, while not + being considered responsible for modifications made by others. + + This License is a kind of “copyleft”, which means that derivative + works of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft + license designed for free software. + + We have designed this License in order to use it for manuals for + free software, because free software needs free documentation: a + free program should come with manuals providing the same freedoms + that the software does. But this License is not limited to + software manuals; it can be used for any textual work, regardless + of subject matter or whether it is published as a printed book. We + recommend this License principally for works whose purpose is + instruction or reference. + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work, in any medium, + that contains a notice placed by the copyright holder saying it can + be distributed under the terms of this License. Such a notice + grants a world-wide, royalty-free license, unlimited in duration, + to use that work under the conditions stated herein. The + “Document”, below, refers to any such manual or work. Any member + of the public is a licensee, and is addressed as “you”. You accept + the license if you copy, modify or distribute the work in a way + requiring permission under copyright law. + + A “Modified Version” of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + + A “Secondary Section” is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document’s overall + subject (or to related matters) and contains nothing that could + fall directly within that overall subject. (Thus, if the Document + is in part a textbook of mathematics, a Secondary Section may not + explain any mathematics.) The relationship could be a matter of + historical connection with the subject or with related matters, or + of legal, commercial, philosophical, ethical or political position + regarding them. + + The “Invariant Sections” are certain Secondary Sections whose + titles are designated, as being those of Invariant Sections, in the + notice that says that the Document is released under this License. + If a section does not fit the above definition of Secondary then it + is not allowed to be designated as Invariant. The Document may + contain zero Invariant Sections. If the Document does not identify + any Invariant Sections then there are none. + + The “Cover Texts” are certain short passages of text that are + listed, as Front-Cover Texts or Back-Cover Texts, in the notice + that says that the Document is released under this License. A + Front-Cover Text may be at most 5 words, and a Back-Cover Text may + be at most 25 words. + + A “Transparent” copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images composed + of pixels) generic paint programs or (for drawings) some widely + available drawing editor, and that is suitable for input to text + formatters or for automatic translation to a variety of formats + suitable for input to text formatters. A copy made in an otherwise + Transparent file format whose markup, or absence of markup, has + been arranged to thwart or discourage subsequent modification by + readers is not Transparent. An image format is not Transparent if + used for any substantial amount of text. A copy that is not + “Transparent” is called “Opaque”. + + Examples of suitable formats for Transparent copies include plain + ASCII without markup, Texinfo input format, LaTeX input format, + SGML or XML using a publicly available DTD, and standard-conforming + simple HTML, PostScript or PDF designed for human modification. + Examples of transparent image formats include PNG, XCF and JPG. + Opaque formats include proprietary formats that can be read and + edited only by proprietary word processors, SGML or XML for which + the DTD and/or processing tools are not generally available, and + the machine-generated HTML, PostScript or PDF produced by some word + processors for output purposes only. + + The “Title Page” means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the + material this License requires to appear in the title page. For + works in formats which do not have any title page as such, “Title + Page” means the text near the most prominent appearance of the + work’s title, preceding the beginning of the body of the text. + + The “publisher” means any person or entity that distributes copies + of the Document to the public. + + A section “Entitled XYZ” means a named subunit of the Document + whose title either is precisely XYZ or contains XYZ in parentheses + following text that translates XYZ in another language. (Here XYZ + stands for a specific section name mentioned below, such as + “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) + To “Preserve the Title” of such a section when you modify the + Document means that it remains a section “Entitled XYZ” according + to this definition. + + The Document may include Warranty Disclaimers next to the notice + which states that this License applies to the Document. These + Warranty Disclaimers are considered to be included by reference in + this License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and + has no effect on the meaning of this License. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License + applies to the Document are reproduced in all copies, and that you + add no other conditions whatsoever to those of this License. You + may not use technical measures to obstruct or control the reading + or further copying of the copies you make or distribute. However, + you may accept compensation in exchange for copies. If you + distribute a large enough number of copies you must also follow the + conditions in section 3. + + You may also lend copies, under the same conditions stated above, + and you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies (or copies in media that commonly + have printed covers) of the Document, numbering more than 100, and + the Document’s license notice requires Cover Texts, you must + enclose the copies in covers that carry, clearly and legibly, all + these Cover Texts: Front-Cover Texts on the front cover, and + Back-Cover Texts on the back cover. Both covers must also clearly + and legibly identify you as the publisher of these copies. The + front cover must present the full title with all words of the title + equally prominent and visible. You may add other material on the + covers in addition. Copying with changes limited to the covers, as + long as they preserve the title of the Document and satisfy these + conditions, can be treated as verbatim copying in other respects. + + If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto + adjacent pages. + + If you publish or distribute Opaque copies of the Document + numbering more than 100, you must either include a machine-readable + Transparent copy along with each Opaque copy, or state in or with + each Opaque copy a computer-network location from which the general + network-using public has access to download using public-standard + network protocols a complete Transparent copy of the Document, free + of added material. If you use the latter option, you must take + reasonably prudent steps, when you begin distribution of Opaque + copies in quantity, to ensure that this Transparent copy will + remain thus accessible at the stated location until at least one + year after the last time you distribute an Opaque copy (directly or + through your agents or retailers) of that edition to the public. + + It is requested, but not required, that you contact the authors of + the Document well before redistributing any large number of copies, + to give them a chance to provide you with an updated version of the + Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document + under the conditions of sections 2 and 3 above, provided that you + release the Modified Version under precisely this License, with the + Modified Version filling the role of the Document, thus licensing + distribution and modification of the Modified Version to whoever + possesses a copy of it. In addition, you must do these things in + the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title + distinct from that of the Document, and from those of previous + versions (which should, if there were any, be listed in the + History section of the Document). You may use the same title + as a previous version if the original publisher of that + version gives permission. + + B. List on the Title Page, as authors, one or more persons or + entities responsible for authorship of the modifications in + the Modified Version, together with at least five of the + principal authors of the Document (all of its principal + authors, if it has fewer than five), unless they release you + from this requirement. + + C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + + D. Preserve all the copyright notices of the Document. + + E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + + F. Include, immediately after the copyright notices, a license + notice giving the public permission to use the Modified + Version under the terms of this License, in the form shown in + the Addendum below. + + G. Preserve in that license notice the full lists of Invariant + Sections and required Cover Texts given in the Document’s + license notice. + + H. Include an unaltered copy of this License. + + I. Preserve the section Entitled “History”, Preserve its Title, + and add to it an item stating at least the title, year, new + authors, and publisher of the Modified Version as given on the + Title Page. If there is no section Entitled “History” in the + Document, create one stating the title, year, authors, and + publisher of the Document as given on its Title Page, then add + an item describing the Modified Version as stated in the + previous sentence. + + J. Preserve the network location, if any, given in the Document + for public access to a Transparent copy of the Document, and + likewise the network locations given in the Document for + previous versions it was based on. These may be placed in the + “History” section. You may omit a network location for a work + that was published at least four years before the Document + itself, or if the original publisher of the version it refers + to gives permission. + + K. For any section Entitled “Acknowledgements” or “Dedications”, + Preserve the Title of the section, and preserve in the section + all the substance and tone of each of the contributor + acknowledgements and/or dedications given therein. + + L. Preserve all the Invariant Sections of the Document, unaltered + in their text and in their titles. Section numbers or the + equivalent are not considered part of the section titles. + + M. Delete any section Entitled “Endorsements”. Such a section + may not be included in the Modified Version. + + N. Do not retitle any existing section to be Entitled + “Endorsements” or to conflict in title with any Invariant + Section. + + O. Preserve any Warranty Disclaimers. + + If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no + material copied from the Document, you may at your option designate + some or all of these sections as invariant. To do this, add their + titles to the list of Invariant Sections in the Modified Version’s + license notice. These titles must be distinct from any other + section titles. + + You may add a section Entitled “Endorsements”, provided it contains + nothing but endorsements of your Modified Version by various + parties—for example, statements of peer review or that the text has + been approved by an organization as the authoritative definition of + a standard. + + You may add a passage of up to five words as a Front-Cover Text, + and a passage of up to 25 words as a Back-Cover Text, to the end of + the list of Cover Texts in the Modified Version. Only one passage + of Front-Cover Text and one of Back-Cover Text may be added by (or + through arrangements made by) any one entity. If the Document + already includes a cover text for the same cover, previously added + by you or by arrangement made by the same entity you are acting on + behalf of, you may not add another; but you may replace the old + one, on explicit permission from the previous publisher that added + the old one. + + The author(s) and publisher(s) of the Document do not by this + License give permission to use their names for publicity for or to + assert or imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under + this License, under the terms defined in section 4 above for + modified versions, provided that you include in the combination all + of the Invariant Sections of all of the original documents, + unmodified, and list them all as Invariant Sections of your + combined work in its license notice, and that you preserve all + their Warranty Disclaimers. + + The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name + but different contents, make the title of each such section unique + by adding at the end of it, in parentheses, the name of the + original author or publisher of that section if known, or else a + unique number. Make the same adjustment to the section titles in + the list of Invariant Sections in the license notice of the + combined work. + + In the combination, you must combine any sections Entitled + “History” in the various original documents, forming one section + Entitled “History”; likewise combine any sections Entitled + “Acknowledgements”, and any sections Entitled “Dedications”. You + must delete all sections Entitled “Endorsements.” + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other + documents released under this License, and replace the individual + copies of this License in the various documents with a single copy + that is included in the collection, provided that you follow the + rules of this License for verbatim copying of each of the documents + in all other respects. + + You may extract a single document from such a collection, and + distribute it individually under this License, provided you insert + a copy of this License into the extracted document, and follow this + License in all other respects regarding verbatim copying of that + document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other + separate and independent documents or works, in or on a volume of a + storage or distribution medium, is called an “aggregate” if the + copyright resulting from the compilation is not used to limit the + legal rights of the compilation’s users beyond what the individual + works permit. When the Document is included in an aggregate, this + License does not apply to the other works in the aggregate which + are not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half + of the entire aggregate, the Document’s Cover Texts may be placed + on covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic + form. Otherwise they must appear on printed covers that bracket + the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section + 4. Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also + include the original English version of this License and the + original versions of those notices and disclaimers. In case of a + disagreement between the translation and the original version of + this License or a notice or disclaimer, the original version will + prevail. + + If a section in the Document is Entitled “Acknowledgements”, + “Dedications”, or “History”, the requirement (section 4) to + Preserve its Title (section 1) will typically require changing the + actual title. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense, or distribute it is void, + and will automatically terminate your rights under this License. + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly and + finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from + that copyright holder, and you cure the violation prior to 30 days + after your receipt of the notice. + + Termination of your rights under this section does not terminate + the licenses of parties who have received copies or rights from you + under this License. If your rights have been terminated and not + permanently reinstated, receipt of a copy of some or all of the + same material does not give you any rights to use it. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of + the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + . + + Each version of the License is given a distinguishing version + number. If the Document specifies that a particular numbered + version of this License “or any later version” applies to it, you + have the option of following the terms and conditions either of + that specified version or of any later version that has been + published (not as a draft) by the Free Software Foundation. If the + Document does not specify a version number of this License, you may + choose any version ever published (not as a draft) by the Free + Software Foundation. If the Document specifies that a proxy can + decide which future versions of this License can be used, that + proxy’s public statement of acceptance of a version permanently + authorizes you to choose that version for the Document. + + 11. RELICENSING + + “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any + World Wide Web server that publishes copyrightable works and also + provides prominent facilities for anybody to edit those works. A + public wiki that anybody can edit is an example of such a server. + A “Massive Multiauthor Collaboration” (or “MMC”) contained in the + site means any set of copyrightable works thus published on the MMC + site. + + “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 + license published by Creative Commons Corporation, a not-for-profit + corporation with a principal place of business in San Francisco, + California, as well as future copyleft versions of that license + published by that same organization. + + “Incorporate” means to publish or republish a Document, in whole or + in part, as part of another Document. + + An MMC is “eligible for relicensing” if it is licensed under this + License, and if all works that were first published under this + License somewhere other than this MMC, and subsequently + incorporated in whole or in part into the MMC, (1) had no cover + texts or invariant sections, and (2) were thus incorporated prior + to November 1, 2008. + + The operator of an MMC Site may republish an MMC contained in the + site under CC-BY-SA on the same site at any time before August 1, + 2009, provided the MMC is eligible for relicensing. + +ADDENDUM: How to use this License for your documents +==================================================== + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (C) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + + If you have Invariant Sections, Front-Cover Texts and Back-Cover +Texts, replace the “with…Texts.” line with this: + + with the Invariant Sections being LIST THEIR TITLES, with + the Front-Cover Texts being LIST, and with the Back-Cover Texts + being LIST. + + If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + + If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of free +software license, such as the GNU General Public License, to permit +their use in free software. + + +File: web-server.info, Node: Index, Prev: GNU Free Documentation License, Up: Top + +Index +***** + +[index] +* Menu: + +* content type: Function Index. (line 60) +* function index: Function Index. (line 6) +* handler function: Handlers. (line 41) +* handlers: Handlers. (line 6) +* introduction: Introduction. (line 6) +* matchers: Handlers. (line 17) +* requests: Requests. (line 6) +* start and stop: Function Index. (line 32) +* usage examples: Usage Examples. (line 6) +* ws-compress-cmd: Function Index. (line 165) +* ws-deflate-cmd: Function Index. (line 168) +* ws-gzip-cmd: Function Index. (line 171) +* ws-in-directory-p: Function Index. (line 113) +* ws-request: Function Index. (line 19) +* ws-response-header: Function Index. (line 60) +* ws-send: Function Index. (line 87) +* ws-send-404: Function Index. (line 95) +* ws-send-500: Function Index. (line 91) +* ws-send-directory-list: Function Index. (line 106) +* ws-send-file: Function Index. (line 99) +* ws-server: Function Index. (line 13) +* ws-servers: Function Index. (line 41) +* ws-start: Function Index. (line 35) +* ws-stop: Function Index. (line 44) +* ws-stop-all: Function Index. (line 50) +* ws-web-socket-connect: Function Index. (line 145) +* ws-with-authentication: Function Index. (line 125) + + + +Tag Table: +Node: Top709 +Node: Introduction2088 +Node: Handlers2778 +Node: Requests4796 +Node: Usage Examples6114 +Node: Hello World7048 +Node: Hello World UTF87830 +Node: Hello World HTML8955 +Node: File Server9615 +Node: URL Parameter Echo10923 +Node: POST Echo12102 +Node: Basic Authentication13116 +Node: Org-mode Export14602 +Node: File Upload17289 +Node: Web Socket18390 +Node: Gzipped Transfer Encoding21580 +Node: Chunked Transfer Encoding23193 +Node: Function Index24933 +Ref: ws-server25217 +Ref: ws-request25543 +Ref: ws-start26307 +Ref: ws-servers26594 +Ref: ws-stop26687 +Ref: ws-stop-all26920 +Ref: ws-response-header27213 +Ref: ws-send28453 +Ref: ws-send-50028632 +Ref: ws-send-40428789 +Ref: ws-send-file28939 +Ref: ws-send-directory-list29312 +Ref: ws-in-directory-p29694 +Ref: ws-with-authentication30013 +Ref: ws-web-socket-connect30849 +Ref: ws-compress-cmd31736 +Ref: ws-deflate-cmd31836 +Ref: ws-gzip-cmd31934 +Node: Copying32026 +Node: GNU Free Documentation License69817 +Node: Index95168 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: -- 1.9.0