mongrel2.nim
author Mahlon E. Smith <mahlon@martini.nu>
Tue, 15 Sep 2015 11:28:40 -0700
changeset 3 ecde1a332692
parent 0 f480e159f575
permissions -rw-r--r--
I'm not sure how I missed this one. Ssssh. Nothing to see here.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     1
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     2
# Copyright (c) 2015, Mahlon E. Smith <mahlon@martini.nu>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     3
# All rights reserved.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     4
# Redistribution and use in source and binary forms, with or without
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     5
# modification, are permitted provided that the following conditions are met:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     6
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     7
#     * Redistributions of source code must retain the above copyright
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     8
#       notice, this list of conditions and the following disclaimer.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     9
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    10
#     * Redistributions in binary form must reproduce the above copyright
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    11
#       notice, this list of conditions and the following disclaimer in the
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    12
#       documentation and/or other materials provided with the distribution.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    13
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    14
#     * Neither the name of Mahlon E. Smith nor the names of his
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    15
#       contributors may be used to endorse or promote products derived
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    16
#       from this software without specific prior written permission.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    17
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    18
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    19
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    20
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    21
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    22
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    23
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    24
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    25
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    26
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    27
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    28
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    29
## This module is a simple interface to the Mongrel2 webserver
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    30
## environment (http://mongrel2.org/).  After a Mongrel2 server has been
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    31
## properly configured, you can use this library to easily service client
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    32
## requests.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    33
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    34
## Bare minimal, do-nothing example:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    35
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    36
## .. code-block:: nim
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    37
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    38
##    newM2Handler( "app-id", "tcp://127.0.0.1:9009", "tcp://127.0.0.1:9008" ).run
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    39
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    40
## Yep, that's it.  Assuming your Mongrel2 server is configured with a
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    41
## matching application identifier and request/response communication
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    42
## ports, that's enough to see the default output from the handler when
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    43
## loaded in browser.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    44
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    45
## It's likely that you'll want to do something of more substance.  This
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    46
## is performed via an `action` hook, which is just a proc() reference.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    47
## It is passed the parsed `M2Request` client request, and it needs to
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    48
## return a matching `M2Response` object.  What happens in between is
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    49
## entirely up to you.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    50
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    51
## Here's a "hello world":
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    52
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    53
## .. code-block:: nim
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    54
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    55
##    let handler = newM2Handler( "app-id", "tcp://127.0.0.1:9009", "tcp://127.0.0.1:9008" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    56
##    
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    57
##    proc hello_world( request: M2Request ): M2Response =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    58
##        result = request.response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    59
##        result[ "Content-Type" ] = "text/plain"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    60
##        result.body = "Hello there, world!"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    61
##        result.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    62
##    
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    63
##    handler.action = hello_world
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    64
##    handler.run
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    65
##    
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    66
## And finally, a slightly more interesting example:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    67
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    68
## .. code-block:: nim
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    69
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    70
##   import
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    71
##       mongrel2,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    72
##       json,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    73
##       re
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    74
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    75
##   let handler = newM2Handler( "app-id", "tcp://127.0.0.1:9009", "tcp://127.0.0.1:9008" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    76
##   var data    = %*[] ## the JSON data to "remember"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    77
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    78
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    79
##   proc demo( request: M2Request ): M2Response =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    80
##       ## This is a demonstration handler action.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    81
##       ##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    82
##       ## It accepts and stores a JSON data structure
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    83
##       ## on POST, and returns it on GET.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    84
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    85
##       # Create a response object for the current request.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    86
##       var response = request.response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    87
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    88
##       case request.meth
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    89
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    90
##       # For GET requests, display the current JSON structure.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    91
##       #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    92
##       of "GET":
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    93
##           if request[ "Accept" ].match( re(".*text/(html|plain).*") ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    94
##               response[ "Content-Type" ] = "text/plain"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    95
##               response.body   = "Hi there.  POST some JSON to me and I'll remember it.\n\n" & $( data )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    96
##               response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    97
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    98
##           elif request[ "Accept" ].match( re("application/json") ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    99
##               response[ "Content-Type" ] = "application/json"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   100
##               response.body   = $( data )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   101
##               response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   102
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   103
##           else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   104
##               response.status = HTTP_BAD_REQUEST
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   105
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   106
##       # POST requests overwrite the current JSON structure.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   107
##       #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   108
##       of "POST":
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   109
##           if request[ "Content-Type" ].match( re(".*application/json.*") ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   110
##               try:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   111
##                   data = request.body.parse_json
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   112
##                   response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   113
##                   response[ "Content-Type" ] = "application/json"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   114
##                   response.body = $( data )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   115
##               except:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   116
##                   response.status = HTTP_BAD_REQUEST
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   117
##                   response[ "Content-Type" ] = "text/plain"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   118
##                   response.body = request.body
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   119
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   120
##           else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   121
##               response.body   = "I only accept valid JSON strings."
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   122
##               response.status = HTTP_BAD_REQUEST
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   123
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   124
##       else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   125
##           response.status = HTTP_NOT_ACCEPTABLE
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   126
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   127
##       return response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   128
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   129
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   130
##   # Attach the proc reference to the handler action.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   131
##   handler.action = demo
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   132
##   
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   133
##   # Start 'er up!
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   134
##   handler.run
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   135
##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   136
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   137
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   138
import
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   139
    json,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   140
    strutils,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   141
    tables,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   142
    times,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   143
    tnetstring,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   144
    zmq
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   145
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   146
type
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   147
    M2Handler* = ref object of RootObj
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   148
        handler_id:         string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   149
        request_sock:       TConnection
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   150
        response_sock:      TConnection
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   151
        action*:            proc ( request: M2Request ): M2Response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   152
        disconnect_action*: proc ( request: M2Request )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   153
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   154
    M2Request* = ref object of RootObj
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   155
        sender_id*:   string  ## Mongrel2 app-id
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   156
        conn_id*:     string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   157
        path*:        string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   158
        meth*:        string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   159
        version*:     string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   160
        uri*:         string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   161
        pattern*:     string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   162
        scheme*:      string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   163
        remote_addr*: string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   164
        query*:       string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   165
        headers*:     seq[ tuple[name: string, value: string] ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   166
        body*:        string 
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   167
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   168
    M2Response* = ref object of RootObj
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   169
        sender_id*: string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   170
        conn_id*:   string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   171
        status*:    int
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   172
        headers*:   seq[ tuple[name: string, value: string] ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   173
        body*:      string 
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   174
        extended:   string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   175
        ex_data:    seq[ string ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   176
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   177
const 
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   178
    MAX_CLIENT_BROADCAST = 128 ## The maximum number of client to broadcast a response to
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   179
    CRLF = "\r\n"              ## Network line ending
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   180
    DEFAULT_CONTENT = """
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   181
<!DOCTYPE html>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   182
<html lang="en">
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   183
    <head>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   184
        <title>It works!</title>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   185
        <link href='http://fonts.googleapis.com/css?family=Play' rel='stylesheet' type='text/css'>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   186
        <style>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   187
        body {
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   188
            margin: 50px;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   189
            height: 100%;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   190
            background-color: #ddd;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   191
            font-family: Play, Arial, serif;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   192
            font-weight: 400;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   193
            background: linear-gradient( to bottom, #7db9e8 25%,#fff 100% );
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   194
        }
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   195
        a, a:hover, a:visited {
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   196
            text-decoration: none;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   197
            color: rgb( 66,131,251 );
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   198
        }
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   199
        .content {
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   200
            font-size: 1.2em;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   201
            border-radius: 10px;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   202
            margin: 0 auto 0 auto;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   203
            width: 50%;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   204
            padding: 5px 20px 20px 20px;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   205
            box-shadow: 1px 2px 6px #000;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   206
            background-color: #fff;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   207
            border: 1px;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   208
        }
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   209
        .handler {
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   210
            font-size: 0.9em;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   211
            padding: 2px 0 0 10px;
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   212
            color: rgb( 192,220,255 );
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   213
            background-color: rgb( 6,20,85 );
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   214
            border: 2px solid rgb( 66,131,251 );
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   215
        }
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   216
        </style>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   217
    </head>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   218
    <body>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   219
        <div class="content">
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   220
            <h1>Almost there...</h1>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   221
            <p>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   222
                This is the default handler output.  While this is
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   223
                useful to demonstrate that your <a href="http://mongrel2.org">Mongrel2</a>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   224
                server is indeed speaking to your <a href="http://nim-lang.org">nim</a>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   225
                handler, you're probably going to want to do something else for production use.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   226
            </p>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   227
            <p>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   228
                Here's an example handler:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   229
            </p>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   230
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   231
            <div class="handler">
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   232
            <pre>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   233
import
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   234
    mongrel2,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   235
    json,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   236
    re
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   237
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   238
let handler = newM2Handler( "app-id", "tcp://127.0.0.1:9009", "tcp://127.0.0.1:9008" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   239
var data    = %*[] ## the JSON data to "remember"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   240
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   241
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   242
proc demo( request: M2Request ): M2Response =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   243
    ## This is a demonstration handler action.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   244
    ##
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   245
    ## It accepts and stores a JSON data structure
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   246
    ## on POST, and returns it on GET.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   247
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   248
    # Create a response object for the current request.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   249
    var response = request.response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   250
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   251
    case request.meth
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   252
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   253
    # For GET requests, display the current JSON structure.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   254
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   255
    of "GET":
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   256
        if request[ "Accept" ].match( re(".*text/(html|plain).*") ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   257
            response[ "Content-Type" ] = "text/plain"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   258
            response.body   = "Hi there.  POST some JSON to me and I'll remember it.\n\n" & $( data )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   259
            response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   260
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   261
        elif request[ "Accept" ].match( re("application/json") ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   262
            response[ "Content-Type" ] = "application/json"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   263
            response.body   = $( data )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   264
            response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   265
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   266
        else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   267
            response.status = HTTP_BAD_REQUEST
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   268
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   269
    # Overwrite the current JSON structure.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   270
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   271
    of "POST":
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   272
        if request[ "Content-Type" ].match( re(".*application/json.*") ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   273
            try:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   274
                data = request.body.parse_json
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   275
                response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   276
                response[ "Content-Type" ] = "application/json"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   277
                response.body = $( data )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   278
            except:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   279
                response.status = HTTP_BAD_REQUEST
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   280
                response[ "Content-Type" ] = "text/plain"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   281
                response.body = request.body
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   282
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   283
        else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   284
            response.body   = "I only accept valid JSON strings."
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   285
            response.status = HTTP_BAD_REQUEST
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   286
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   287
    else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   288
        response.status = HTTP_NOT_ACCEPTABLE
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   289
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   290
    return response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   291
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   292
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   293
# Attach the proc reference to the handler action.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   294
handler.action = demo
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   295
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   296
# Start 'er up!
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   297
handler.run
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   298
            </pre>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   299
            </div>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   300
        </div>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   301
    </body>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   302
</html>
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   303
    """
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   304
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   305
    HTTP_CONTINUE*                      = 100
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   306
    HTTP_SWITCHING_PROTOCOLS*           = 101
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   307
    HTTP_PROCESSING*                    = 102
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   308
    HTTP_OK*                            = 200
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   309
    HTTP_CREATED*                       = 201
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   310
    HTTP_ACCEPTED*                      = 202
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   311
    HTTP_NON_AUTHORITATIVE*             = 203
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   312
    HTTP_NO_CONTENT*                    = 204
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   313
    HTTP_RESET_CONTENT*                 = 205
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   314
    HTTP_PARTIAL_CONTENT*               = 206
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   315
    HTTP_MULTI_STATUS*                  = 207
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   316
    HTTP_MULTIPLE_CHOICES*              = 300
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   317
    HTTP_MOVED_PERMANENTLY*             = 301
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   318
    HTTP_MOVED*                         = 301
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   319
    HTTP_MOVED_TEMPORARILY*             = 302
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   320
    HTTP_REDIRECT*                      = 302
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   321
    HTTP_SEE_OTHER*                     = 303
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   322
    HTTP_NOT_MODIFIED*                  = 304
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   323
    HTTP_USE_PROXY*                     = 305
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   324
    HTTP_TEMPORARY_REDIRECT*            = 307
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   325
    HTTP_BAD_REQUEST*                   = 400
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   326
    HTTP_AUTH_REQUIRED*                 = 401
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   327
    HTTP_UNAUTHORIZED*                  = 401
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   328
    HTTP_PAYMENT_REQUIRED*              = 402
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   329
    HTTP_FORBIDDEN*                     = 403
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   330
    HTTP_NOT_FOUND*                     = 404
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   331
    HTTP_METHOD_NOT_ALLOWED*            = 405
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   332
    HTTP_NOT_ACCEPTABLE*                = 406
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   333
    HTTP_PROXY_AUTHENTICATION_REQUIRED* = 407
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   334
    HTTP_REQUEST_TIME_OUT*              = 408
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   335
    HTTP_CONFLICT*                      = 409
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   336
    HTTP_GONE*                          = 410
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   337
    HTTP_LENGTH_REQUIRED*               = 411
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   338
    HTTP_PRECONDITION_FAILED*           = 412
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   339
    HTTP_REQUEST_ENTITY_TOO_LARGE*      = 413
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   340
    HTTP_REQUEST_URI_TOO_LARGE*         = 414
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   341
    HTTP_UNSUPPORTED_MEDIA_TYPE*        = 415
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   342
    HTTP_RANGE_NOT_SATISFIABLE*         = 416
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   343
    HTTP_EXPECTATION_FAILED*            = 417
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   344
    HTTP_UNPROCESSABLE_ENTITY*          = 422
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   345
    HTTP_LOCKED*                        = 423
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   346
    HTTP_FAILED_DEPENDENCY*             = 424
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   347
    HTTP_UPGRADE_REQUIRED*              = 426
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   348
    HTTP_RECONDITION_REQUIRED*          = 428
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   349
    HTTP_TOO_MANY_REQUESTS*             = 429
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   350
    HTTP_REQUEST_HEADERS_TOO_LARGE*     = 431
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   351
    HTTP_SERVER_ERROR*                  = 500
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   352
    HTTP_NOT_IMPLEMENTED*               = 501
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   353
    HTTP_BAD_GATEWAY*                   = 502
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   354
    HTTP_SERVICE_UNAVAILABLE*           = 503
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   355
    HTTP_GATEWAY_TIME_OUT*              = 504
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   356
    HTTP_VERSION_NOT_SUPPORTED*         = 505
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   357
    HTTP_VARIANT_ALSO_VARIES*           = 506
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   358
    HTTP_INSUFFICIENT_STORAGE*          = 507
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   359
    HTTP_NOT_EXTENDED*                  = 510
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   360
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   361
    HTTPCODE = {
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   362
        HTTP_CONTINUE:                      ( desc: "Continue",                        label: "CONTINUE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   363
        HTTP_SWITCHING_PROTOCOLS:           ( desc: "Switching Protocols",             label: "SWITCHING_PROTOCOLS" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   364
        HTTP_PROCESSING:                    ( desc: "Processing",                      label: "PROCESSING" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   365
        HTTP_OK:                            ( desc: "OK",                              label: "OK" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   366
        HTTP_CREATED:                       ( desc: "Created",                         label: "CREATED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   367
        HTTP_ACCEPTED:                      ( desc: "Accepted",                        label: "ACCEPTED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   368
        HTTP_NON_AUTHORITATIVE:             ( desc: "Non-Authoritative Information",   label: "NON_AUTHORITATIVE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   369
        HTTP_NO_CONTENT:                    ( desc: "No Content",                      label: "NO_CONTENT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   370
        HTTP_RESET_CONTENT:                 ( desc: "Reset Content",                   label: "RESET_CONTENT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   371
        HTTP_PARTIAL_CONTENT:               ( desc: "Partial Content",                 label: "PARTIAL_CONTENT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   372
        HTTP_MULTI_STATUS:                  ( desc: "Multi-Status",                    label: "MULTI_STATUS" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   373
        HTTP_MULTIPLE_CHOICES:              ( desc: "Multiple Choices",                label: "MULTIPLE_CHOICES" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   374
        HTTP_MOVED_PERMANENTLY:             ( desc: "Moved Permanently",               label: "MOVED_PERMANENTLY" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   375
        HTTP_MOVED:                         ( desc: "Moved Permanently",               label: "MOVED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   376
        HTTP_MOVED_TEMPORARILY:             ( desc: "Found",                           label: "MOVED_TEMPORARILY" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   377
        HTTP_REDIRECT:                      ( desc: "Found",                           label: "REDIRECT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   378
        HTTP_SEE_OTHER:                     ( desc: "See Other",                       label: "SEE_OTHER" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   379
        HTTP_NOT_MODIFIED:                  ( desc: "Not Modified",                    label: "NOT_MODIFIED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   380
        HTTP_USE_PROXY:                     ( desc: "Use Proxy",                       label: "USE_PROXY" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   381
        HTTP_TEMPORARY_REDIRECT:            ( desc: "Temporary Redirect",              label: "TEMPORARY_REDIRECT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   382
        HTTP_BAD_REQUEST:                   ( desc: "Bad Request",                     label: "BAD_REQUEST" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   383
        HTTP_AUTH_REQUIRED:                 ( desc: "Authorization Required",          label: "AUTH_REQUIRED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   384
        HTTP_UNAUTHORIZED:                  ( desc: "Authorization Required",          label: "UNAUTHORIZED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   385
        HTTP_PAYMENT_REQUIRED:              ( desc: "Payment Required",                label: "PAYMENT_REQUIRED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   386
        HTTP_FORBIDDEN:                     ( desc: "Forbidden",                       label: "FORBIDDEN" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   387
        HTTP_NOT_FOUND:                     ( desc: "Not Found",                       label: "NOT_FOUND" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   388
        HTTP_METHOD_NOT_ALLOWED:            ( desc: "Method Not Allowed",              label: "METHOD_NOT_ALLOWED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   389
        HTTP_NOT_ACCEPTABLE:                ( desc: "Not Acceptable",                  label: "NOT_ACCEPTABLE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   390
        HTTP_PROXY_AUTHENTICATION_REQUIRED: ( desc: "Proxy Authentication Required",   label: "PROXY_AUTHENTICATION_REQUIRED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   391
        HTTP_REQUEST_TIME_OUT:              ( desc: "Request Time-out",                label: "REQUEST_TIME_OUT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   392
        HTTP_CONFLICT:                      ( desc: "Conflict",                        label: "CONFLICT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   393
        HTTP_GONE:                          ( desc: "Gone",                            label: "GONE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   394
        HTTP_LENGTH_REQUIRED:               ( desc: "Length Required",                 label: "LENGTH_REQUIRED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   395
        HTTP_PRECONDITION_FAILED:           ( desc: "Precondition Failed",             label: "PRECONDITION_FAILED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   396
        HTTP_REQUEST_ENTITY_TOO_LARGE:      ( desc: "Request Entity Too Large",        label: "REQUEST_ENTITY_TOO_LARGE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   397
        HTTP_REQUEST_URI_TOO_LARGE:         ( desc: "Request-URI Too Large",           label: "REQUEST_URI_TOO_LARGE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   398
        HTTP_UNSUPPORTED_MEDIA_TYPE:        ( desc: "Unsupported Media Type",          label: "UNSUPPORTED_MEDIA_TYPE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   399
        HTTP_RANGE_NOT_SATISFIABLE:         ( desc: "Requested Range Not Satisfiable", label: "RANGE_NOT_SATISFIABLE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   400
        HTTP_EXPECTATION_FAILED:            ( desc: "Expectation Failed",              label: "EXPECTATION_FAILED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   401
        HTTP_UNPROCESSABLE_ENTITY:          ( desc: "Unprocessable Entity",            label: "UNPROCESSABLE_ENTITY" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   402
        HTTP_LOCKED:                        ( desc: "Locked",                          label: "LOCKED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   403
        HTTP_FAILED_DEPENDENCY:             ( desc: "Failed Dependency",               label: "FAILED_DEPENDENCY" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   404
        HTTP_UPGRADE_REQUIRED:              ( desc: "Upgrade Required",                label: "UPGRADE_REQUIRED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   405
        HTTP_RECONDITION_REQUIRED:          ( desc: "Precondition Required",           label: "RECONDITION_REQUIRED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   406
        HTTP_TOO_MANY_REQUESTS:             ( desc: "Too Many Requests",               label: "TOO_MANY_REQUESTS" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   407
        HTTP_REQUEST_HEADERS_TOO_LARGE:     ( desc: "Request Headers too Large",       label: "REQUEST_HEADERS_TOO_LARGE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   408
        HTTP_SERVER_ERROR:                  ( desc: "Internal Server Error",           label: "SERVER_ERROR" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   409
        HTTP_NOT_IMPLEMENTED:               ( desc: "Method Not Implemented",          label: "NOT_IMPLEMENTED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   410
        HTTP_BAD_GATEWAY:                   ( desc: "Bad Gateway",                     label: "BAD_GATEWAY" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   411
        HTTP_SERVICE_UNAVAILABLE:           ( desc: "Service Temporarily Unavailable", label: "SERVICE_UNAVAILABLE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   412
        HTTP_GATEWAY_TIME_OUT:              ( desc: "Gateway Time-out",                label: "GATEWAY_TIME_OUT" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   413
        HTTP_VERSION_NOT_SUPPORTED:         ( desc: "HTTP Version Not Supported",      label: "VERSION_NOT_SUPPORTED" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   414
        HTTP_VARIANT_ALSO_VARIES:           ( desc: "Variant Also Negotiates",         label: "VARIANT_ALSO_VARIES" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   415
        HTTP_INSUFFICIENT_STORAGE:          ( desc: "Insufficient Storage",            label: "INSUFFICIENT_STORAGE" ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   416
        HTTP_NOT_EXTENDED:                  ( desc: "Not Extended",                    label: "NOT_EXTENDED" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   417
    }.toTable
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   418
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   419
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   420
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   421
proc newM2Handler*( id: string, req_sock: string, res_sock: string ): M2Handler =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   422
    ## Instantiate a new `M2Handler` object.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   423
    ## The `id` should match the app ID in the Mongrel2 config,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   424
    ## `req_sock` is the ZMQ::PULL socket Mongrel2 sends client request
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   425
    ## data on, and `res_sock` is the ZMQ::PUB socket Mongrel2 subscribes
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   426
    ## to.  Nothing is put into action until the run() method is invoked.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   427
    new( result )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   428
    result.handler_id    = id
3
ecde1a332692 I'm not sure how I missed this one. Ssssh. Nothing to see here.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   429
    result.request_sock  = zmq.connect( req_sock, PULL )
ecde1a332692 I'm not sure how I missed this one. Ssssh. Nothing to see here.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   430
    result.response_sock = zmq.connect( res_sock, PUB )
0
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   431
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   432
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   433
proc parse_request( request: string ): M2Request =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   434
    ## Parse a message `request` string received from Mongrel2,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   435
    ## return it as a M2Request object.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   436
    var
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   437
        reqstr     = request.split( ' ' )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   438
        rest       = ""
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   439
        req_tnstr: TNetstringNode
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   440
        headers:   JsonNode
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   441
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   442
    new( result )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   443
    result.sender_id = reqstr[ 0 ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   444
    result.conn_id   = reqstr[ 1 ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   445
    result.path      = reqstr[ 2 ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   446
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   447
    # There must be a better way to join() a seq...
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   448
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   449
    for i in 3 .. reqstr.high:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   450
        rest = rest & reqstr[ i ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   451
        if i < reqstr.high: rest = rest & ' '
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   452
    reqtnstr    = rest.parse_tnetstring
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   453
    result.body = reqtnstr.extra.parse_tnetstring.getStr("")
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   454
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   455
    # Pull Mongrel2 control headers into the request object.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   456
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   457
    headers = reqtnstr.getStr.parse_json
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   458
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   459
    if headers.has_key( "METHOD" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   460
        result.meth = headers[ "METHOD" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   461
        headers.delete( "METHOD" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   462
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   463
    if headers.has_key( "PATTERN" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   464
        result.pattern = headers[ "PATTERN" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   465
        headers.delete( "PATTERN" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   466
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   467
    if headers.has_key( "REMOTE_ADDR" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   468
        result.remote_addr = headers[ "REMOTE_ADDR" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   469
        headers.delete( "REMOTE_ADDR" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   470
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   471
    if headers.has_key( "URI" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   472
        result.uri = headers[ "URI" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   473
        headers.delete( "URI" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   474
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   475
    if headers.has_key( "URL_SCHEME" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   476
        result.scheme = headers[ "URL_SCHEME" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   477
        headers.delete( "URL_SCHEME" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   478
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   479
    if headers.has_key( "VERSION" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   480
        result.version = headers[ "VERSION" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   481
        headers.delete( "VERSION" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   482
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   483
    if headers.has_key( "QUERY" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   484
        result.query = headers[ "QUERY" ].getStr
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   485
        headers.delete( "QUERY" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   486
    
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   487
    # Remaining headers are client supplied.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   488
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   489
    result.headers = @[]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   490
    for key, val in headers:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   491
        result.headers.add( ( key, val.getStr ) )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   492
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   493
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   494
proc response*( request: M2Request ): M2Response =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   495
    ## Instantiate a new `M2Response`, paired from an `M2Request`.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   496
    new( result )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   497
    result.sender_id = request.sender_id
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   498
    result.conn_id   = request.conn_id
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   499
    result.headers   = @[]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   500
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   501
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   502
proc `[]`*( request: M2Request, label: string ): string =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   503
    ## Defer to the underlying headers tuple array.  Lookup is case-insensitive.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   504
    for header in request.headers:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   505
        if cmpIgnoreCase( label, header.name ) == 0:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   506
            return header.value
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   507
    return nil
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   508
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   509
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   510
proc is_disconnect*( request: M2Request ): bool =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   511
    ## Returns true if this is a Mongrel2 disconnect request.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   512
    if ( request.path == "@*" and request.meth == "JSON") :
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   513
        var body = request.body.parseJson
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   514
        if ( body.has_key( "type" ) and body[ "type" ].getStr == "disconnect" ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   515
            return true
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   516
    return false
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   517
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   518
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   519
proc `[]`*( response: M2Response, label: string ): string =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   520
    ## Defer to the underlying headers tuple array.  Lookup is case-insensitive.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   521
    for header in response.headers:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   522
        if cmpIgnoreCase( label, header.name ) == 0:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   523
            return header.value
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   524
    return nil
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   525
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   526
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   527
proc `[]=`*( response: M2Response, name: string, value: string ) =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   528
    ## Set a header on the response.  Duplicates are replaced.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   529
    var new_headers: seq[ tuple[name: string, value: string] ] = @[]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   530
    for header in response.headers:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   531
        if cmpIgnoreCase( name, header.name ) != 0:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   532
            new_headers.add( header )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   533
    response.headers = new_headers
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   534
    response.headers.add( (name, value) )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   535
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   536
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   537
proc add_header*( response: M2Response, name: string, value: string ) =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   538
    ## Adds a header to the response.  Duplicates are ignored.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   539
    response.headers.add( (name, value) )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   540
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   541
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   542
proc extend*( response: M2Response, filter: string ) =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   543
    ## Set a response as extended.  This means different things depending on
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   544
    ## the Mongrel2 filter in use.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   545
    response.extended = filter
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   546
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   547
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   548
proc add_extended_data*( response: M2Response, data: varargs[string, `$`] ) =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   549
    ## Attach filter arguments to the extended response.  Arguments should
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   550
    ## be coercible into strings.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   551
    if isNil( response.ex_data ): response.ex_data = @[]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   552
    for arg in data:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   553
        response.ex_data.add( arg )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   554
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   555
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   556
proc is_extended*( response: M2Response ): bool =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   557
    ## Predicate method to determine if a response is extended.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   558
    return not isNil( response.extended )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   559
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   560
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   561
proc broadcast*[T]( response: M2Response, ids: openarray[T] ) =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   562
    ## Send the response to multiple backend client IDs.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   563
    assert( ids.len <= MAX_CLIENT_BROADCAST, "Exceeded client broadcast maximum" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   564
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   565
    response.conn_id = $( ids[0] )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   566
    for i in 1 .. ids.high:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   567
        if i <= ids.high: response.conn_id = response.conn_id & ' '
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   568
        response.conn_id = response.conn_id & $( ids[i] )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   569
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   570
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   571
proc format( response: M2Response ): string =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   572
    ## Format an `M2Response` object for Mongrel2.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   573
    var conn_id: string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   574
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   575
    # Mongrel2 extended response.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   576
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   577
    if response.is_extended:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   578
        conn_id = newTNetstringString( "X " & response.conn_id ).dump_tnetstring
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   579
        result = response.sender_id & ' ' & conn_id
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   580
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   581
        # 1st argument is the filter name.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   582
        #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   583
        var tnet_array = newTNetstringArray()
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   584
        tnet_array.add( newTNetstringString(response.extended) )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   585
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   586
        # rest are the filter arguments, if any.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   587
        #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   588
        if not isNil( response.ex_data ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   589
            for data in response.ex_data:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   590
                tnet_array.add( newTNetstringString(data) )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   591
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   592
        result = result & ' ' & tnet_array.dump_tnetstring
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   593
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   594
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   595
    else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   596
        # Regular HTTP request/response cycle.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   597
        #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   598
        if isNil( response.body ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   599
            response.body = HTTPCODE[ response.status ].desc
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   600
            response[ "Content-Length" ] = $( response.body.len )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   601
        else:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   602
            response[ "Content-Length" ] = $( response.body.len )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   603
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   604
        let code = "$1 $2" % [ $(response.status), HTTPCODE[response.status].label ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   605
        conn_id  = newTNetstringString( response.conn_id ).dump_tnetstring
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   606
        result   = response.sender_id & ' ' & conn_id
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   607
        result   = result & " HTTP/1.1 " & code & CRLF
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   608
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   609
        for header in response.headers:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   610
            result = result & header.name & ": " & header.value & CRLF
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   611
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   612
        result = result & CRLF & response.body
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   613
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   614
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   615
proc handle_default( request: M2Request ): M2Response =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   616
    ## This is the default handler, if the caller didn't install one.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   617
    result                   = request.response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   618
    result[ "Content-Type" ] = "text/html"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   619
    result.body              = DEFAULT_CONTENT
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   620
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   621
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   622
proc run*( handler: M2Handler ) {. noreturn .} =
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   623
    ## Enter the request loop conversation with Mongrel2.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   624
    ## If an action() proc is attached, run that to generate
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   625
    ## a response.  Otherwise, run the default.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   626
    while true:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   627
        var
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   628
            request:  M2Request
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   629
            response: M2Response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   630
            info:     string
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   631
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   632
        request = parse_request( handler.request_sock.receive ) # block, waiting for next request
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   633
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   634
        # Ignore disconnects unless there's a separate
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   635
        # disconnect_action.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   636
        #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   637
        if request.is_disconnect:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   638
            if not isNil( handler.disconnect_action ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   639
                discard handler.disconnect_action
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   640
            continue
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   641
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   642
        # Defer regular response content to the handler action.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   643
        #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   644
        if isNil( handler.action ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   645
            handler.action = handle_default
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   646
        response = handler.action( request )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   647
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   648
        if response.status == 0: response.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   649
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   650
        if defined( testing ):
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   651
            echo "REQUEST:\n",  repr(request)
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   652
            echo "RESPONSE:\n", repr(response)
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   653
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   654
        info = "$1 $2 $3" % [
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   655
            request.remote_addr,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   656
            request.meth,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   657
            request.uri
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   658
        ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   659
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   660
        echo "$1: $2 --> $3 $4" % [
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   661
            $(get_localtime(getTime())),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   662
            info,
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   663
            $( response.status ),
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   664
            HTTPCODE[ response.status ].label
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   665
        ]
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   666
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   667
        handler.response_sock.send( response.format )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   668
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   669
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   670
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   671
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   672
# Tests!
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   673
#
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   674
when isMainModule:
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   675
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   676
    var reqstr = """host 33 /hosts 502:{"PATH":"/hosts","x-forwarded-for":"10.3.0.75","cache-control":"max-age=0","accept-language":"en-US,en;q=0.5","connection":"keep-alive","accept-encoding":"gzip, deflate","dnt":"1","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","user-agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0","host":"hotsoup.sunset.laika.com:8080","METHOD":"GET","VERSION":"HTTP/1.1","URI":"/hosts","PATTERN":"/hosts","URL_SCHEME":"http","REMOTE_ADDR":"10.3.0.75"},0:,"""
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   677
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   678
    var req  = parse_request( reqstr )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   679
    var dreq = parse_request( """host 1234 @* 17:{"METHOD":"JSON"},21:{"type":"disconnect"},""" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   680
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   681
    # Request parsing.
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   682
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   683
    doAssert( req.sender_id          == "host" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   684
    doAssert( req.conn_id            == "33" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   685
    doAssert( req.path               == "/hosts" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   686
    doAssert( req.remote_addr        == "10.3.0.75" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   687
    doAssert( req.scheme             == "http" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   688
    doAssert( req.meth               == "GET" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   689
    doAssert( req["DNT"]             == "1" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   690
    doAssert( req["X-Forwarded-For"] == "10.3.0.75" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   691
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   692
    doAssert( req.is_disconnect == false )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   693
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   694
    var res = req.response
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   695
    res.status = HTTP_OK
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   696
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   697
    doAssert( res.sender_id == req.sender_id )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   698
    doAssert( res.conn_id == req.conn_id )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   699
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   700
    # Response headers
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   701
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   702
    res.add_header( "alright", "yep" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   703
    res[ "something" ] = "nope"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   704
    res[ "something" ] = "yep"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   705
    doAssert( res["alright"]   == "yep" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   706
    doAssert( res["something"] == "yep" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   707
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   708
    # Client broadcasts
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   709
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   710
    res.broadcast([ 1, 2, 3, 4 ])
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   711
    doAssert( res.conn_id == "1 2 3 4" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   712
    doAssert( res.format == "host 7:1 2 3 4, HTTP/1.1 200 OK\r\nalright: yep\r\nsomething: yep\r\nContent-Length: 2\r\n\r\nOK" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   713
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   714
    # Extended replies
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   715
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   716
    doAssert( res.is_extended == false )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   717
    res.extend( "sendfile" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   718
    doAssert( res.is_extended == true )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   719
    doAssert( res.format == "host 9:X 1 2 3 4, 11:8:sendfile,]" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   720
    res.add_extended_data( "arg1", "arg2" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   721
    res.add_extended_data( "arg3" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   722
    doAssert( res.format == "host 9:X 1 2 3 4, 32:8:sendfile,4:arg1,4:arg2,4:arg3,]" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   723
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   724
    doAssert( dreq.is_disconnect == true )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   725
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   726
    # Automatic body if none is specified
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   727
    #
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   728
    res.extended = nil
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   729
    res.body     = nil
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   730
    res.status   = HTTP_CREATED
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   731
    discard res.format
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   732
    doAssert( res.body == "Created" )
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   733
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   734
    echo "* Tests passed!"
f480e159f575 Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   735