Skip to content

Latest commit

 

History

History
325 lines (260 loc) · 11.4 KB

NOTES

File metadata and controls

325 lines (260 loc) · 11.4 KB

Notes and Tasks

-*- org -*-

Notes

Tasks [19/22]

pass all tests on Windows [2/2]

Currently two failing tests.

  • [X] ws/simple-post returns “you said nil” instead of “you said foo”
  • [X] ws/in-directory-p is failing because it assumes “/tmp” which doesn’t work on windows

Content and Transfer encodings

Some issue as to whether compression is better done as a “Content Encoding” which actually changes the content, or as a “Transfer Encoding”, which doesn’t change the content, just the messages.

The latter seems preferable, but possibly less widely supported. See http://stackoverflow.com/questions/11641923/transfer-encoding-gzip-vs-content-encoding-gzip.

  • content-coding
    compress
    Unix compress program (rfc2616)
    deflate
    zlib (see http://www.iana.org/go/rfc1950) format with defalte compression (rfc2616)
    exi
    W3c efficient XML (see http://www.w3.org/TR/exi/)
    gzip
    GNU zip (rfc2616)
    identity
    does nothing
    pack200-zip
    specific to Java archives (see http://www.jcp.org/en/jsr/detail?id=200)
  • transfer-coding
    chunked
    (rfc2616)
    compress
    same as above
    deflate
    same as above
    gzip
    same as above
  • tail-header
    Content-MD5
    Base64 encoded binary MD5 sum of content

Maybe we can set the coding system of the process with define-coding-system, specifically using the :pre-write-conversion flag to e.g., gzip or chunkify the contents.

web sockets

more examples [4/4]

Org-mode agenda

Already exists as part of org-ehtml. file:examples/011-org-agenda.el

display the current buffer

Idea stolen from elnode. file:examples/010-current-buffer.el

browse the BBDB

file:examples/012-search-bbdb.el

org-mode export server

  1. upload a file
  2. supply an export type
  3. return the exported version of the file

handle large files

When large files arrive quickly, the filter functions are called while they are still running on the previous chunk, this leads to nasty race conditions for the state of the request object.

Either introduce some check to wait on new input if input is currently being parsed, or wait until all input has arrived before doing any parsing.

Now using an active field on request objects to avoid race conditions when new header text is received while the parsing function is still active.

robustness to bad requests [0/2]

Low priority, just run behind a proxy.

request timeout

maximum request size

authentication [2/2]

  • State “HOLD” from “TODO” [2014-02-10 Mon 19:06]
    digest may not be worth it, just run Basic over HTTPS

Basic

http://en.wikipedia.org/wiki/Basic_access_authentication

CANCELED Digest

http://en.wikipedia.org/wiki/Digest_access_authentication

If this is implemented, it would be good to implement some safeguards against common attacks.

  • Server nonce is allowed to contain timestamps. Therefore the server may inspect nonce attributes submitted by clients, to prevent replay attacks.
  • Server is also allowed to maintain a list of recently issued or used server nonce values to prevent reuse.

incremental handler calls

not sure if the extra performance is worth the added complexity

Before the header is fully parsed, call any potential handlers. Include a field in the request object to indicate that the request isn’t finished being received so handlers can return and wait to be called again.

Also, put a catch in the filter function and allow the headers function on the request object to throw to said catch aborting the handler and waiting for the rest of the input.

Documentation [6/6]

  • [X] introduction
  • [X] handlers
  • [X] request headers
  • [X] usage examples
  • [X] list of functions

Notes to touch upon

  • [X] how to set content type

Handle POST requests

  1. read standard for POST data
  2. parse multi-line headers with boundaries

For now keep this all incremental and in ws-filter.

Makefile

  • byte-compile
  • package
  • test
  • benchmark

catch errors and return an error code

include an easy error handler like the 404 handler

better parsing of multipart form blocks

parse more than just the content-type headers.

non-multipart form data

e.g., parameter strings

some more convenience functionality [6/6]

  • [X] strip and parse URL query string
  • [X] parse urlencoded post data
  • [X] think about defaulting to (name . content) for form elements
  • [X] maybe don’t require a non-nil return to cancel the connection, instead only keep open if :keep-alive is returned
  • [X] function to send a file (with mime handling)
  • [X] send a 404 with some default text

CANCELED Lazy header processing

  • State “CANCELED” from “TODO” [2013-12-25 Wed 12:21]
    premature optimization

Use lazy sequence functions for header a-list to avoid parsing all headers. For regexp matchers should stop when matched header is encountered (often the first one when :GET), For function matchers provide lazy version of assoc.

Also, there is the issue of how a lazy request for more parameters should act before all incoming text has been received. Emacs does not provide a light-weight mechanism for a function to wait for incoming process text without something gross like the (sit-for 0.1) used in the test suite.

use gnutls for https

low priority – just run behind an https proxy.

This will be a pain, and will require expanding info:emacs-gnutls to add support for starting server processes, currently only client processes are supported.

screen cast?

Tutorials

The following tutorials walk through common usage scenarios including installing the Emacs web-server and running it behind a proxy. Install the Emacs web-server and run (info "web-server") to browse the full manual within Emacs, or view the HTML version at emacs-web-server.

Installation and running a server

Most easily installable through the GNU ELPA, run M-x package-list-packages select web-server and install. Alternately, install from the git repository at https://github.com/eschulte/emacs-web-server and update your the load.

  1. Ensure that you have Emacs version 24 or greater installed.
    emacs --version
        
    GNU Emacs 24.3.1
    Copyright (C) 2013 Free Software Foundation, Inc.
    GNU Emacs comes with ABSOLUTELY NO WARRANTY.
    You may redistribute copies of Emacs
    under the terms of the GNU General Public License.
    For more information about these matters, see the file named COPYING.
        
  2. Download and unpack the zip archive of the Emacs web-server code from emacs-web-server-master.zip or clone the source code repository with git.
    git clone https://github.com/eschulte/emacs-web-server.git
        
  3. Move into the root of the emacs-web-server/ directory and optionally run make to compile the web-server code, and run make check to test your web-server install.
    make
    make check
        
  4. From the root of the emacs-web-server/ directory, start an instance of Emacs with web-server loaded.
    emacs -Q -L . -l web-server
        

    Alternately, from an already running Emacs instance, add this directory to the load path and load the web server with the following.

    (add-to-list 'load-path "path/to/emacs-web-server")
    (require 'web-server)
        
  5. Evaluate the following code in *scratch* buffer of this Emacs instance.
    (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)   
        
  6. Browse to http://localhost:9000 to see that the web-server is running.
  7. Read the web-server manual and work through other Usage Examples.

Running behind a proxy

Public-facing instance of the Emacs web-server should be run behind a more established web server such as Apache or Nginx to provide additional robustness and security.

The following example Apache configuration may be used to have a public facing Apache server listening on port 80 proxy requests to a local web-server instance running on port 8888 of the same machine.

<VirtualHost *:80>
  ServerName  yourserver.com

  ProxyPass / http://localhost:8888/
</VirtualHost>

A similar Nginx configuration is available at http://wiki.nginx.org/LoadBalanceExample.

Running behind an https proxy

The following example configurations will cause Apache or Nginx to act as an HTTPS proxy for an instance of the Emacs web server running on the same machine. With this setup Apache speaks HTTPS to the outside world, and communicates with the Emacs web server using HTTP. This allows use of HTTPS even though the Emacs web server does not implement HTTPS itself. This setup is recommended for any setup, but should be considered required for sites using BASIC HTTP Authentication.

Apache

This requires that Apache has mod_proxy and mod_ssl enabled, and that the certificate and key files required for SSL are present. This these requirements satisfied, and assuming the Emacs web server is listening on port 8888 and is running on the same machine as the Apache web server an Apache virtual host configuration such as the following.

<VirtualHost *:443>
    ProxyPreserveHost On
    ServerName yourserver.com

    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

    ProxyPass / http://localhost:8888/
    ProxyPassReverse / http://localhost:8888/
</VirtualHost>

Nginx

See the following for instructions configuring Nginx as an HTTPS proxy.

Bugs [1/1]

Sometimes servers don’t stop cleanly

  • specifically servers with active client process
  • maybe also implement a ws-stop-all function