/*
    Copyright (c) 2013 250bpm s.r.o.  All rights reserved.
    Copyright (c) 2014 Wirebird Labs LLC.  All rights reserved.

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom
    the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    IN THE SOFTWARE.
*/

#include "wshdr.h"
#include "sha1.h"

#include "../../aio/timer.h"

#include "../../core/sock.h"

#include "../utils/base64.h"

#include "../../utils/alloc.h"
#include "../../utils/err.h"
#include "../../utils/cont.h"
#include "../../utils/fast.h"
#include "../../utils/wire.h"
#include "../../utils/attr.h"
#include "../../utils/random.h"

#include <stddef.h>
#include <string.h>
#include <ctype.h>

/*  State machine finite states. */
#define NN_WSHDR_STATE_IDLE 1
#define NN_WSHDR_STATE_SERVER_RECV 2
#define NN_WSHDR_STATE_SERVER_REPLY 3
#define NN_WSHDR_STATE_CLIENT_SEND 4
#define NN_WSHDR_STATE_CLIENT_RECV 5
#define NN_WSHDR_STATE_HANDSHAKE_SENT 6
#define NN_WSHDR_STATE_STOPPING_TIMER_ERROR 7
#define NN_WSHDR_STATE_STOPPING_TIMER_DONE 8
#define NN_WSHDR_STATE_DONE 9
#define NN_WSHDR_STATE_STOPPING 10

/*  Subordinate srcptr objects. */
#define NN_WSHDR_SRC_USOCK 1
#define NN_WSHDR_SRC_TIMER 2

/*  Time allowed to complete handshake. */
#define NN_WSHDR_TIMEOUT 5000

/*  Possible return codes internal to the parsing operations. */
#define NN_WSHDR_NOMATCH 0
#define NN_WSHDR_MATCH 1

/*  Possible return codes from parsing opening handshake from peer. */
#define NN_WSHDR_VALID 0
#define NN_WSHDR_RECV_MORE 1
#define NN_WSHDR_INVALID -1

/*  Possible handshake responses to send to client when acting as server. */
#define NN_WSHDR_RESPONSE_NULL -1
#define NN_WSHDR_RESPONSE_OK 0
#define NN_WSHDR_RESPONSE_TOO_BIG 1
#define NN_WSHDR_RESPONSE_UNUSED2 2
#define NN_WSHDR_RESPONSE_WSPROTO 3
#define NN_WSHDR_RESPONSE_WSVERSION 4
#define NN_WSHDR_RESPONSE_NNPROTO 5
#define NN_WSHDR_RESPONSE_NOTPEER 6
#define NN_WSHDR_RESPONSE_UNKNOWNTYPE 7

/*  WebSocket protocol tokens as per RFC 6455. */
#define NN_WSHDR_CRLF "\r\n"
#define NN_WSHDR_TERMSEQ "\r\n\r\n"
#define NN_WSHDR_TERMSEQ_LEN 4

/*  Size of minimal valid handshare request and reply. This amount of bytes
    is read initially so that we don't have to read the whole handshake
    in one-byte-at-a-time manner. */
#define NN_WSHDR_REQ_MIN_SIZE 150
#define NN_WSHDR_REP_MIN_SIZE 16

/*  Private functions. */
static void nn_wshdr_handler (struct nn_fsm *self, int src, int type,
    void *srcptr);
static void nn_wshdr_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr);
static void nn_wshdr_leave (struct nn_wshdr *self, int rc);

/*  Private functions. */
static int nn_wshdr_parse_client_opening (struct nn_wshdr *self);
static void nn_wshdr_server_reply (struct nn_wshdr *self);
static void nn_wshdr_client_request (struct nn_wshdr *self);
static int nn_wshdr_parse_server_response (struct nn_wshdr *self);
static int nn_wshdr_hash_key (const uint8_t *key, size_t key_len,
    uint8_t *hashed, size_t hashed_len);
static int nn_ws_match_token (const char* token, const char **subj,
    int case_insensitive);
static int nn_ws_match_value (const char* termseq, const char **subj,
    int ignore_leading_sp, int ignore_trailing_sp, const uint8_t **addr,
    size_t* const len);
static int nn_ws_validate_value (const char* expected, const uint8_t *subj,
    size_t subj_len, int case_insensitive);

void nn_wshdr_init (struct nn_wshdr *self, int src,
    struct nn_fsm *owner)
{
    nn_fsm_init (&self->fsm, nn_wshdr_handler, nn_wshdr_shutdown,
        src, self, owner);
    self->state = NN_WSHDR_STATE_IDLE;
    nn_timer_init (&self->timer, NN_WSHDR_SRC_TIMER, &self->fsm);
    nn_fsm_event_init (&self->done);
    self->timeout = NN_WSHDR_TIMEOUT;
    self->usock = NULL;
    self->usock_owner.src = -1;
    self->usock_owner.fsm = NULL;
    self->pipebase = NULL;
}

void nn_wshdr_term (struct nn_wshdr *self)
{
    nn_assert_state (self, NN_WSHDR_STATE_IDLE);

    nn_fsm_event_term (&self->done);
    nn_timer_term (&self->timer);
    nn_fsm_term (&self->fsm);
}

int nn_wshdr_isidle (struct nn_wshdr *self)
{
    return nn_fsm_isidle (&self->fsm);
}

void nn_wshdr_start (struct nn_wshdr *self,
    struct nn_usock *usock, struct nn_pipebase *pipebase,
    int mode, const char *resource, const char *host)
{
    /*  It's expected this resource has been allocated during intial connect. */
    if (mode == NN_WS_CLIENT)
        nn_assert (strlen (resource) >= 1);

    /*  Take ownership of the underlying socket. */
    nn_assert (self->usock == NULL && self->usock_owner.fsm == NULL);
    self->usock_owner.src = NN_WSHDR_SRC_USOCK;
    self->usock_owner.fsm = &self->fsm;
    nn_usock_swap_owner (usock, &self->usock_owner);
    self->usock = usock;
    self->pipebase = pipebase;
    self->mode = mode;
    self->resource = resource;
    self->remote_host = host;

    memset (self->opening_hs, 0, sizeof (self->opening_hs));
    memset (self->response, 0, sizeof (self->response));

    self->recv_pos = 0;
    self->retries = 0;

    /*  Launch the state machine. */
    nn_fsm_start (&self->fsm);
}

void nn_wshdr_stop (struct nn_wshdr *self)
{
    nn_fsm_stop (&self->fsm);
}

static void nn_wshdr_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_wshdr *wshdr;

    wshdr = nn_cont (self, struct nn_wshdr, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_timer_stop (&wshdr->timer);
        wshdr->state = NN_WSHDR_STATE_STOPPING;
    }
    if (nn_slow (wshdr->state == NN_WSHDR_STATE_STOPPING)) {
        if (!nn_timer_isidle (&wshdr->timer))
            return;
        wshdr->state = NN_WSHDR_STATE_IDLE;
        nn_fsm_stopped (&wshdr->fsm, NN_WSHDR_STOPPED);
        return;
    }

    nn_fsm_bad_state (wshdr->state, src, type);
}

static void nn_wshdr_handler (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_wshdr *wshdr;

    unsigned i;

    wshdr = nn_cont (self, struct nn_wshdr, fsm);

    switch (wshdr->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/******************************************************************************/
    case NN_WSHDR_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:

                /*  The timeout for the handshake to get rid of stuck or
                    DoS-attacking peers. */
                nn_timer_start (&wshdr->timer, wshdr->timeout);

                switch (wshdr->mode) {
                case NN_WS_CLIENT:

                    /*  Send opening handshake to server. */
                    wshdr->recv_len = NN_WSHDR_REP_MIN_SIZE;
                    nn_wshdr_client_request (wshdr);
                    wshdr->state = NN_WSHDR_STATE_CLIENT_SEND;
                    return;

                case NN_WS_SERVER:

                    /*  Begin receiving opening handshake from client. */
                    wshdr->recv_len = NN_WSHDR_REQ_MIN_SIZE;
                    nn_usock_recv (wshdr->usock, wshdr->opening_hs,
                        wshdr->recv_len, NULL);
                    wshdr->state = NN_WSHDR_STATE_SERVER_RECV;
                    return;

                default:
                    /*  Unexpected mode. */
                    nn_assert (0);
                    return;
                }

            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  SERVER_RECV state.                                                        */
/******************************************************************************/
    case NN_WSHDR_STATE_SERVER_RECV:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            switch (type) {
            case NN_USOCK_RECEIVED:
                /*  Parse bytes received thus far. */
                switch (nn_wshdr_parse_client_opening (wshdr)) {
                case NN_WSHDR_INVALID:
                    /*  Opening handshake parsed successfully but does not
                        contain valid values. Respond failure to client. */
                    wshdr->state = NN_WSHDR_STATE_SERVER_REPLY;
                    nn_wshdr_server_reply (wshdr);
                    return;
                case NN_WSHDR_VALID:
                    /*  Opening handshake parsed successfully, and is valid.
                        Respond success to client. */
                    wshdr->state = NN_WSHDR_STATE_SERVER_REPLY;
                    nn_wshdr_server_reply (wshdr);
                    return;
                case NN_WSHDR_RECV_MORE:
                    /*  Not enough bytes have been received to determine
                        validity; remain in the receive state, and retrieve
                        more bytes from client. */
                    wshdr->recv_pos += wshdr->recv_len;

                    /*  Validate the previous recv operation. */
                    nn_assert (wshdr->recv_pos <
                        sizeof (wshdr->opening_hs));

                    /*  Ensure we can back-track at least the length of the
                        termination sequence to determine how many bytes to
                        receive on the next retry. This is an assertion, not
                        a conditional, since under no condition is it
                        necessary to initially receive so few bytes. */
                    nn_assert (wshdr->recv_pos >=
                        (int) NN_WSHDR_TERMSEQ_LEN);

                    for (i = NN_WSHDR_TERMSEQ_LEN; i >= 0; i--) {
                        if (memcmp (NN_WSHDR_TERMSEQ,
                            wshdr->opening_hs + wshdr->recv_pos - i,
                            i) == 0) {
                            break;
                        }
                    }

                    nn_assert (i < NN_WSHDR_TERMSEQ_LEN);

                    wshdr->recv_len = NN_WSHDR_TERMSEQ_LEN - i;

                    /*  In the unlikely case the client would overflow what we
                        assumed was a sufficiently-large buffer to receive the
                        handshake, we fail the client. */
                    if (wshdr->recv_len + wshdr->recv_pos >
                        sizeof (wshdr->opening_hs)) {
                        wshdr->response_code =
                            NN_WSHDR_RESPONSE_TOO_BIG;
                        wshdr->state =
                            NN_WSHDR_STATE_SERVER_REPLY;
                        nn_wshdr_server_reply (wshdr);
                    }
                    else {
                        wshdr->retries++;
                        nn_usock_recv (wshdr->usock,
                            wshdr->opening_hs + wshdr->recv_pos,
                            wshdr->recv_len, NULL);
                    }
                    return;
                default:
                    nn_fsm_error ("Unexpected handshake result",
                        wshdr->state, src, type);
                }
                return;
            case NN_USOCK_SHUTDOWN:
                /*  Ignore it and wait for ERROR event. */
                return;
            case NN_USOCK_ERROR:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  SERVER_REPLY state.                                                       */
/******************************************************************************/
    case NN_WSHDR_STATE_SERVER_REPLY:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SENT:
                /*  As per RFC 6455 4.2.2, the handshake is now complete
                    and the connection is immediately ready for send/recv. */
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_DONE;
            case NN_USOCK_SHUTDOWN:
                /*  Ignore it and wait for ERROR event. */
                return;
            case NN_USOCK_ERROR:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  CLIENT_SEND state.                                                        */
/******************************************************************************/
    case NN_WSHDR_STATE_CLIENT_SEND:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SENT:
                wshdr->state = NN_WSHDR_STATE_CLIENT_RECV;
                nn_usock_recv (wshdr->usock, wshdr->response,
                    wshdr->recv_len, NULL);
                return;
            case NN_USOCK_SHUTDOWN:
                /*  Ignore it and wait for ERROR event. */
                return;
            case NN_USOCK_ERROR:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  CLIENT_RECV state.                                                        */
/******************************************************************************/
    case NN_WSHDR_STATE_CLIENT_RECV:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            switch (type) {
            case NN_USOCK_RECEIVED:
                /*  Parse bytes received thus far. */
                switch (nn_wshdr_parse_server_response (wshdr)) {
                case NN_WSHDR_INVALID:
                    /*  Opening handshake parsed successfully but does not
                        contain valid values. Fail connection. */
                        nn_timer_stop (&wshdr->timer);
                        wshdr->state =
                            NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                    return;
                case NN_WSHDR_VALID:
                    /*  As per RFC 6455 4.2.2, the handshake is now complete
                        and the connection is immediately ready for send/recv. */
                    nn_timer_stop (&wshdr->timer);
                    wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_DONE;
                    return;
                case NN_WSHDR_RECV_MORE:
                    /*  Not enough bytes have been received to determine
                        validity; remain in the receive state, and retrieve
                        more bytes from client. */
                    wshdr->recv_pos += wshdr->recv_len;

                    /*  Validate the previous recv operation. */
                    nn_assert (wshdr->recv_pos <
                        sizeof (wshdr->response));

                    /*  Ensure we can back-track at least the length of the
                        termination sequence to determine how many bytes to
                        receive on the next retry. This is an assertion, not
                        a conditional, since under no condition is it
                        necessary to initially receive so few bytes. */
                    nn_assert (wshdr->recv_pos >=
                        (int) NN_WSHDR_TERMSEQ_LEN);

                    for (i = NN_WSHDR_TERMSEQ_LEN; i >= 0; i--) {
                        if (memcmp (NN_WSHDR_TERMSEQ,
                            wshdr->response + wshdr->recv_pos - i,
                            i) == 0) {
                            break;
                        }
                    }

                    nn_assert (i < NN_WSHDR_TERMSEQ_LEN);

                    wshdr->recv_len = NN_WSHDR_TERMSEQ_LEN - i;

                    /*  In the unlikely case the client would overflow what we
                        assumed was a sufficiently-large buffer to receive the
                        handshake, we fail the connection. */
                    if (wshdr->recv_len + wshdr->recv_pos >
                        sizeof (wshdr->response)) {
                        nn_timer_stop (&wshdr->timer);
                        wshdr->state =
                            NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                    }
                    else {
                        wshdr->retries++;
                        nn_usock_recv (wshdr->usock,
                            wshdr->response + wshdr->recv_pos,
                            wshdr->recv_len, NULL);
                    }
                    return;
                default:
                    nn_fsm_error ("Unexpected handshake result",
                        wshdr->state, src, type);
                }
                return;
            case NN_USOCK_SHUTDOWN:
                /*  Ignore it and wait for ERROR event. */
                return;
            case NN_USOCK_ERROR:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  HANDSHAKE_SENT state.                                                     */
/******************************************************************************/
    case NN_WSHDR_STATE_HANDSHAKE_SENT:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SENT:
                /*  As per RFC 6455 4.2.2, the handshake is now complete
                    and the connection is immediately ready for send/recv. */
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_DONE;
                return;
            case NN_USOCK_SHUTDOWN:
                /*  Ignore it and wait for ERROR event. */
                return;
            case NN_USOCK_ERROR:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&wshdr->timer);
                wshdr->state = NN_WSHDR_STATE_STOPPING_TIMER_ERROR;
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_TIMER_ERROR state.                                               */
/******************************************************************************/
    case NN_WSHDR_STATE_STOPPING_TIMER_ERROR:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            /*  Ignore. The only circumstance the client would send bytes is
                to notify the server it is closing the connection. Wait for the
                socket to eventually error. */
            return;

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_STOPPED:
                nn_wshdr_leave (wshdr, NN_WSHDR_ERROR);
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_TIMER_DONE state.                                                */
/******************************************************************************/
    case NN_WSHDR_STATE_STOPPING_TIMER_DONE:
        switch (src) {

        case NN_WSHDR_SRC_USOCK:
            /*  Ignore. The only circumstance the client would send bytes is
                to notify the server it is closing the connection. Wait for the
                socket to eventually error. */
            return;

        case NN_WSHDR_SRC_TIMER:
            switch (type) {
            case NN_TIMER_STOPPED:
                nn_wshdr_leave (wshdr, NN_WSHDR_OK);
                return;
            default:
                nn_fsm_bad_action (wshdr->state, src, type);
            }

        default:
            nn_fsm_bad_source (wshdr->state, src, type);
        }

/******************************************************************************/
/*  DONE state.                                                               */
/*  The header exchange was either done successfully of failed. There's       */
/*  nothing that can be done in this state except stopping the object.        */
/******************************************************************************/
    case NN_WSHDR_STATE_DONE:
        nn_fsm_bad_source (wshdr->state, src, type);

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (wshdr->state, src, type);
    }
}

/******************************************************************************/
/*  State machine actions.                                                    */
/******************************************************************************/

/*  Get the state machine into the terminal state. */
static void nn_wshdr_leave (struct nn_wshdr *self, int rc)
{
    nn_usock_swap_owner (self->usock, &self->usock_owner);
    self->usock = NULL;
    self->usock_owner.src = -1;
    self->usock_owner.fsm = NULL;
    self->state = NN_WSHDR_STATE_DONE;
    nn_fsm_raise (&self->fsm, &self->done, rc);
}

static int nn_wshdr_parse_client_opening (struct nn_wshdr *self)
{
    /*  As per RFC 6455 section 1.7, this parser is not intended to be a
        general-purpose parser for arbitrary HTTP headers. As with the design
        philosophy of nanomsg, application-specific exchanges are better
        reserved for accepted connections, not as fields within these
        headers. */

    int rc;
    const char *pos;
    unsigned i;
    int id;

    /*  Guarantee that a NULL terminator exists to enable treating this
        recv buffer like a string. */
    nn_assert (memchr (self->opening_hs, '\0', sizeof (self->opening_hs)));

    /*  Having found the NULL terminator, from this point forward string
        functions may be used. */
    nn_assert (strlen (self->opening_hs) < sizeof (self->opening_hs));

    pos = self->opening_hs;

    /*  Is the opening handshake from the client fully received? */
    if (!strstr (pos, NN_WSHDR_TERMSEQ))
        return NN_WSHDR_RECV_MORE;

    self->host = NULL;
    self->origin = NULL;
    self->key = NULL;
    self->upgrade = NULL;
    self->conn = NULL;
    self->version = NULL;
    self->protocol = NULL;
    self->uri = NULL;

    self->host_len = 0;
    self->origin_len = 0;
    self->key_len = 0;
    self->upgrade_len = 0;
    self->conn_len = 0;
    self->version_len = 0;
    self->protocol_len = 0;
    self->uri_len = 0;

    /*  This function, if generating a return value that triggers
        a response to the client, should replace this sentinel value
        with a proper response code. */
    self->response_code = NN_WSHDR_RESPONSE_NULL;

    /*  RFC 7230 3.1.1 Request Line: HTTP Method
        Note requirement of one space and case sensitivity. */
    if (!nn_ws_match_token ("GET\x20", &pos, 0))
        return NN_WSHDR_RECV_MORE;

    /*  RFC 7230 3.1.1 Request Line: Requested Resource. */
    if (!nn_ws_match_value ("\x20", &pos, 0, 0, &self->uri, &self->uri_len))
        return NN_WSHDR_RECV_MORE;

    /*  RFC 7230 3.1.1 Request Line: HTTP version. Note case sensitivity. */
    if (!nn_ws_match_token ("HTTP/1.1", &pos, 0))
        return NN_WSHDR_RECV_MORE;
    if (!nn_ws_match_token (NN_WSHDR_CRLF, &pos, 0))
        return NN_WSHDR_RECV_MORE;

    /*  It's expected the current position is now at the first
        header field. Match them one by one. */
    while (strlen (pos))
    {
        if (nn_ws_match_token ("Host:", &pos, 1)) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->host, &self->host_len);
        }
        else if (nn_ws_match_token ("Origin:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->origin, &self->origin_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Key:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->key, &self->key_len);
        }
        else if (nn_ws_match_token ("Upgrade:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->upgrade, &self->upgrade_len);
        }
        else if (nn_ws_match_token ("Connection:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->conn, &self->conn_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Version:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->version, &self->version_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Protocol:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->protocol, &self->protocol_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Extensions:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->extensions, &self->extensions_len);
        }
        else if (nn_ws_match_token (NN_WSHDR_CRLF,
            &pos, 1) == NN_WSHDR_MATCH) {
            /*  Exit loop since all headers are parsed. */
            break;
        }
        else {
            /*  Skip unknown headers. */
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                NULL, NULL);
        }

        if (rc != NN_WSHDR_MATCH)
            return NN_WSHDR_RECV_MORE;
    }

    /*  Validate the opening handshake is now fully parsed. Additionally,
        as per RFC 6455 section 4.1, the client should not send additional data
        after the opening handshake, so this assertion validates upstream recv
        logic prevented this case. */
    nn_assert (strlen (pos) == 0);

    /*  TODO: protocol expectations below this point are hard-coded here as
        an initial design decision. Perhaps in the future these values should
        be settable via compile time (or run-time socket) options? */

    /*  These header fields are required as per RFC 6455 section 4.1. */
    if (!self->host || !self->upgrade || !self->conn ||
        !self->key || !self->version || !self->protocol) {
        self->response_code = NN_WSHDR_RESPONSE_WSPROTO;
        return NN_WSHDR_INVALID;
    }

    /*  RFC 6455 section 4.2.1.6 (version December 2011). */
    if (nn_ws_validate_value ("13", self->version,
        self->version_len, 1) != NN_WSHDR_MATCH) {
        self->response_code = NN_WSHDR_RESPONSE_WSVERSION;
        return NN_WSHDR_INVALID;
    }

    /*  RFC 6455 section 4.2.1.3 (version December 2011). */
    if (nn_ws_validate_value ("websocket", self->upgrade,
        self->upgrade_len, 1) != NN_WSHDR_MATCH) {
        self->response_code = NN_WSHDR_RESPONSE_WSPROTO;
        return NN_WSHDR_INVALID;
    }

    /*  RFC 6455 section 4.2.1.4 (version December 2011). */
    if (nn_ws_validate_value ("Upgrade", self->conn,
        self->conn_len, 1) != NN_WSHDR_MATCH) {
        self->response_code = NN_WSHDR_RESPONSE_WSPROTO;
        return NN_WSHDR_INVALID;
    }

    /*  At this point, client meets RFC 6455 compliance for opening handshake.
        Now it's time to check nanomsg-imposed required handshake values. */

    /*  Valid protocol values start with SP- prefix. */
    if (self->protocol_len < 4 || memcmp (self->protocol, "SP-", 3) != 0)
        return NN_WSHDR_INVALID;

    /*  After the prefix there should be only decimal digits.
        Compute the protocol ID along the way. */
    id = 0;
    for (i = 3; i != self->protocol_len; ++i) {
        if (self->protocol [i] < '0' || self->protocol [i] > '9')
            return NN_WSHDR_INVALID;
        id *= 10;
        id += self->protocol [i] - '0';
    }

    /*  No leading zeroes. */
    if (self->protocol_len > 4 && self->protocol [3] == '0')
        return NN_WSHDR_INVALID;

    /*  Check whether the peer speaks compatible SP protocol. */
    if (!nn_pipebase_ispeer (self->pipebase, id)) {
        self->response_code = NN_WSHDR_RESPONSE_NOTPEER;
        return NN_WSHDR_INVALID;
    }

    /*  Done. Handshake is valid. */
    self->response_code = NN_WSHDR_RESPONSE_OK;
    return NN_WSHDR_VALID;
}

static int nn_wshdr_parse_server_response (struct nn_wshdr *self)
{
    /*  As per RFC 6455 section 1.7, this parser is not intended to be a
        general-purpose parser for arbitrary HTTP headers. As with the design
        philosophy of nanomsg, application-specific exchanges are better
        reserved for accepted connections, not as fields within these
        headers. */

    int rc;
    const char *pos;

    /*  Guarantee that a NULL terminator exists to enable treating this
        recv buffer like a string. The lack of such would indicate a failure
        upstream to catch a buffer overflow. */
    nn_assert (memchr (self->response, '\0', sizeof (self->response)));

    /*  Having found the NULL terminator, from this point forward string
        functions may be used. */
    nn_assert (strlen (self->response) < sizeof (self->response));

    pos = self->response;

    /*  Is the response from the server fully received? */
    if (!strstr (pos, NN_WSHDR_TERMSEQ))
        return NN_WSHDR_RECV_MORE;

    self->status_code = NULL;
    self->reason_phrase = NULL;
    self->server = NULL;
    self->accept_key = NULL;
    self->upgrade = NULL;
    self->conn = NULL;
    self->version = NULL;
    self->protocol = NULL;

    self->status_code_len = 0;
    self->reason_phrase_len = 0;
    self->server_len = 0;
    self->accept_key_len = 0;
    self->upgrade_len = 0;
    self->conn_len = 0;
    self->version_len = 0;
    self->protocol_len = 0;

    /*  RFC 7230 3.1.2 Status Line: HTTP Version. */
    if (!nn_ws_match_token ("HTTP/1.1\x20", &pos, 0))
        return NN_WSHDR_RECV_MORE;

    /*  RFC 7230 3.1.2 Status Line: Status Code. */
    if (!nn_ws_match_value ("\x20", &pos, 0, 0, &self->status_code,
        &self->status_code_len))
        return NN_WSHDR_RECV_MORE;

    /*  RFC 7230 3.1.2 Status Line: Reason Phrase. */
    if (!nn_ws_match_value (NN_WSHDR_CRLF, &pos, 0, 0,
        &self->reason_phrase, &self->reason_phrase_len))
        return NN_WSHDR_RECV_MORE;

    /*  It's expected the current position is now at the first
        header field. Match them one by one. */
    while (strlen (pos))
    {
        if (nn_ws_match_token ("Server:", &pos, 1)) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->server, &self->server_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Accept:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->accept_key, &self->accept_key_len);
        }
        else if (nn_ws_match_token ("Upgrade:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->upgrade, &self->upgrade_len);
        }
        else if (nn_ws_match_token ("Connection:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->conn, &self->conn_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Version-Server:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->version, &self->version_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Protocol-Server:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->protocol, &self->protocol_len);
        }
        else if (nn_ws_match_token ("Sec-WebSocket-Extensions:",
            &pos, 1) == NN_WSHDR_MATCH) {
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                &self->extensions, &self->extensions_len);
        }
        else if (nn_ws_match_token (NN_WSHDR_CRLF,
            &pos, 1) == NN_WSHDR_MATCH) {
            /*  Exit loop since all headers are parsed. */
            break;
        }
        else {
            /*  Skip unknown headers. */
            rc = nn_ws_match_value (NN_WSHDR_CRLF, &pos, 1, 1,
                NULL, NULL);
        }

        if (rc != NN_WSHDR_MATCH)
            return NN_WSHDR_RECV_MORE;
    }

    /*  Validate the opening handshake is now fully parsed. Additionally,
        as per RFC 6455 section 4.1, the client should not send additional data
        after the opening handshake, so this assertion validates upstream recv
        logic prevented this case. */
    nn_assert (strlen (pos) == 0);

    /*  TODO: protocol expectations below this point are hard-coded here as
        an initial design decision. Perhaps in the future these values should
        be settable via compile time (or run-time socket) options? */

    /*  These header fields are required as per RFC 6455 4.2.2. */
    if (!self->status_code || !self->upgrade || !self->conn ||
        !self->accept_key)
        return NN_WSHDR_INVALID;

    /*  TODO: Currently, we only handle a successful connection upgrade.
        Anything else is treated as a failed connection.
        Consider handling other scenarios like 3xx redirects. */
    if (nn_ws_validate_value ("101", self->status_code,
        self->status_code_len, 1) != NN_WSHDR_MATCH)
        return NN_WSHDR_INVALID;

    /*  RFC 6455 section 4.2.2.5.2 (version December 2011). */
    if (nn_ws_validate_value ("websocket", self->upgrade,
        self->upgrade_len, 1) != NN_WSHDR_MATCH)
        return NN_WSHDR_INVALID;

    /*  RFC 6455 section 4.2.2.5.3 (version December 2011). */
    if (nn_ws_validate_value ("Upgrade", self->conn,
        self->conn_len, 1) != NN_WSHDR_MATCH)
        return NN_WSHDR_INVALID;

    /*  RFC 6455 section 4.2.2.5.4 (version December 2011). */
    if (nn_ws_validate_value (self->expected_accept_key, self->accept_key,
        self->accept_key_len, 1) != NN_WSHDR_MATCH)
        return NN_WSHDR_INVALID;

    /*  Server response meets RFC 6455 compliance for opening handshake. */
    return NN_WSHDR_VALID;
}

/*  Send the initial part of the handshake from client to server. */
static void nn_wshdr_client_request (struct nn_wshdr *self)
{
    int rc;
    struct nn_iovec iov;
    size_t encoded_key_len;
    uint8_t rand_key [16];
    char encoded_key [25];

    /*  Generate random 16-byte key as per RFC 6455 4.1 */
    nn_random_generate (rand_key, sizeof (rand_key));

    /*  Convert the key into Base64. */
    rc = nn_base64_encode (rand_key, sizeof (rand_key),
        encoded_key, sizeof (encoded_key));
    encoded_key_len = strlen (encoded_key);
    nn_assert (encoded_key_len == sizeof (encoded_key) - 1);

    /*  Pre-calculated expected Accept Key value as per
        RFC 6455 section 4.2.2.5.4 (version December 2011). */
    rc = nn_wshdr_hash_key (encoded_key, encoded_key_len,
        self->expected_accept_key, sizeof (self->expected_accept_key));
    nn_assert (rc == NN_WSHDR_ACCEPT_KEY_LEN);

    /*  Generate the request. */
    iov.iov_base = self->opening_hs;
    iov.iov_len = snprintf (self->opening_hs,
        sizeof (self->opening_hs),
        "GET %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "Upgrade: websocket\r\n"
        "Connection: Upgrade\r\n"
        "Sec-WebSocket-Key: %s\r\n"
        "Sec-WebSocket-Version: 13\r\n"
        "Sec-WebSocket-Protocol: SP-%d\r\n\r\n",
        self->resource,
        self->remote_host,
        encoded_key,
        (int) self->pipebase->sock->socktype->protocol);
    nn_assert (iov.iov_len < sizeof (self->opening_hs));

    /*  Send the request to the peer. */
    nn_usock_send (self->usock, &iov, 1);
}

static void nn_wshdr_server_reply (struct nn_wshdr *self)
{
    struct nn_iovec iov;
    char *code;
    int rc;

    /*  Allow room for NULL terminator. */
    char accept_key [NN_WSHDR_ACCEPT_KEY_LEN + 1];

    if (self->response_code == NN_WSHDR_RESPONSE_OK) {

        /*  Upgrade connection as per RFC 6455 section 4.2.2. */
        
        rc = nn_wshdr_hash_key (self->key, self->key_len,
            accept_key, sizeof (accept_key));
        nn_assert (strlen (accept_key) == NN_WSHDR_ACCEPT_KEY_LEN);

        iov.iov_base = &self->response;
        iov.iov_len = snprintf (self->response,
            sizeof (self->response),
            "HTTP/1.1 101 Switching Protocols\r\n"
            "Upgrade: websocket\r\n"
            "Connection: Upgrade\r\n"
            "Sec-WebSocket-Accept: %s\r\n"
            "Sec-WebSocket-Protocol: %.*s\r\n\r\n",
            accept_key,
            (int) self->protocol_len, self->protocol);
        nn_assert (iov.iov_len < sizeof (self->response));
    }
    else {

        /*  Fail the connection with a helpful hint. */
        switch (self->response_code) {
        case NN_WSHDR_RESPONSE_TOO_BIG:
            code = "400 Opening Handshake Too Long";
            break;
        case NN_WSHDR_RESPONSE_WSPROTO:
            code = "400 Cannot Have Body";
            break;
        case NN_WSHDR_RESPONSE_WSVERSION:
            code = "400 Unsupported WebSocket Version";
            break;
        case NN_WSHDR_RESPONSE_NNPROTO:
            code = "400 Missing nanomsg Required Headers";
            break;
        case NN_WSHDR_RESPONSE_NOTPEER:
            code = "400 Incompatible Socket Type";
            break;
        case NN_WSHDR_RESPONSE_UNKNOWNTYPE:
            code = "400 Unrecognized Socket Type";
            break;
        default:
            /*  Unexpected failure response. */
            nn_assert (0);
            break;
        }

        /*  Fail connection as per RFC 6455 4.4. */
        iov.iov_base = &self->response;
        iov.iov_len = snprintf (self->response,
            sizeof (self->response),
            "HTTP/1.1 %s\r\n"
            "Sec-WebSocket-Version: %.*s\r\n",
            code,
            (int) self->version_len, self->version);
        nn_assert (iov.iov_len < sizeof (self->response));
    }

    /*  Send the reply. */
    nn_usock_send (self->usock, &iov, 1);
}

static int nn_wshdr_hash_key (const uint8_t *key, size_t key_len,
    uint8_t *hashed, size_t hashed_len)
{
    int rc;
    unsigned i;
    struct nn_sha1 hash;
    const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    nn_sha1_init (&hash);

    for (i = 0; i < key_len; i++)
        nn_sha1_hashbyte (&hash, key [i]);

    for (i = 0; i < 36; i++)
        nn_sha1_hashbyte (&hash, magic [i]);

    rc = nn_base64_encode (nn_sha1_result (&hash),
        sizeof (hash.state), hashed, hashed_len);

    return rc;
}

/*  Scans for reference token against subject string, optionally ignoring
    case sensitivity. On match, advances the subject pointer to the next
    non-ignored character past match. Both strings must be NULL terminated to
    avoid undefined behavior. Returns NN_WSHDR_MATCH on match; else,
    NN_WSHDR_NOMATCH. */
static int nn_ws_match_token (const char* token, const char **subj,
    int case_insensitive)
{
    const char *pos;

    nn_assert (token && *subj);

    pos = *subj;

    if (case_insensitive) {
        while (*token && *pos) {
            if (tolower (*token) != tolower (*pos))
                return NN_WSHDR_NOMATCH;
            token++;
            pos++;
        }
    }
    else {
        while (*token && *pos) {
            if (*token != *pos)
                return NN_WSHDR_NOMATCH;
            token++;
            pos++;
        }
    }

    /*  Encountered end of subject before matching completed. */
    if (!*pos && *token)
        return NN_WSHDR_NOMATCH;

    /*  Entire token has been matched. */
    nn_assert (!*token);

    /*  On success, advance subject position. */
    *subj = pos;

    return NN_WSHDR_MATCH;
}

/*  Scans subject string for termination sequence, optionally ignoring
    leading and/or trailing spaces in subject. On match, advances
    the subject pointer to the next character past match. Both
    strings must be NULL terminated to avoid undefined behavior. If the
    match succeeds, values are stored into *addr and *len. */
static int nn_ws_match_value (const char* termseq, const char **subj,
    int ignore_leading_sp, int ignore_trailing_sp, const uint8_t **addr,
    size_t* const len)
{
    const char *start;
    const char *end;

    nn_assert (termseq && *subj);

    start = *subj;
    if (addr)
        *addr = NULL;
    if (len)
        *len = 0;

    /*  Find first occurence of termination sequence. */
    end = strstr (start, termseq);

    /*  Was a termination sequence found? */
    if (end) {
        *subj = end + strlen (termseq);
    }
    else {
        return NN_WSHDR_NOMATCH;
    }
        
    if (ignore_leading_sp) {
        while (*start == '\x20' && start < end) {
            start++;
        }
    }

    if (addr)
        *addr = start;

    /*  In this special case, the value was "found", but is just empty or
        ignored space. */
    if (start == end)
        return NN_WSHDR_MATCH;

    if (ignore_trailing_sp) {
        while (*(end - 1) == '\x20' && start < end) {
            end--;
        }
    }

    if (len)
        *len = end - start;

    return NN_WSHDR_MATCH;
}

/*  Compares subject octet stream to expected value, optionally ignoring
    case sensitivity. Returns non-zero on success, zero on failure. */
static int nn_ws_validate_value (const char* expected, const uint8_t *subj,
    size_t subj_len, int case_insensitive)
{
    if (strlen (expected) != subj_len)
        return NN_WSHDR_NOMATCH;

    if (case_insensitive) {
        while (*expected && *subj) {
            if (tolower (*expected) != tolower (*subj))
                return NN_WSHDR_NOMATCH;
            expected++;
            subj++;
        }
    }
    else {
        while (*expected && *subj) {
            if (*expected != *subj)
                return NN_WSHDR_NOMATCH;
            expected++;
            subj++;
        }
    }

    return NN_WSHDR_MATCH;
}

