fill_headers(agooReq r, VALUE hash) {
    char	*h = r->header.start;
    char	*end = h + r->header.len + 1; // +1 for last \r
    char	*key = h;
    char	*kend = key;
    char	*val = NULL;
    char	*vend;
    int		klen;
    bool	upgrade = false;
    bool	ws = false;

    if (NULL == r) {
	rb_raise(rb_eArgError, "Request is no longer valid.");
    }

    for (; h < end; h++) {
	switch (*h) {
	case ':':
	    if (NULL == val) {
		kend = h;
		val = h + 1;
	    }
	    break;
	case '\r':
	    if (NULL != val) {
		for (; ' ' == *val; val++) {
		}
		vend = h;
	    }
	    if (NULL != key) {
		for (; ' ' == *key; key++) {
		}
	    }
	    if ('\n' == *(h + 1)) {
		h++;
	    }
	    klen = (int)(kend - key);
	    add_header_value(hash, key, klen, val, (int)(vend - val));
	    if (sizeof(upgrade_key) - 1 == klen && 0 == strncasecmp(key, upgrade_key, sizeof(upgrade_key) - 1)) {
		if (sizeof(websocket_val) - 1 == vend - val &&
		    0 == strncasecmp(val, websocket_val, sizeof(websocket_val) - 1)) {
		    ws = true;
		}
	    } else if (sizeof(connection_key) - 1 == klen && 0 == strncasecmp(key, connection_key, sizeof(connection_key) - 1)) {
		char	buf[1024];

		strncpy(buf, val, vend - val);
		buf[sizeof(buf)-1] = '\0';
		if (NULL != strstr(buf, upgrade_key)) {
		    upgrade = true;
		}
	    } else if (sizeof(accept_key) - 1 == klen && 0 == strncasecmp(key, accept_key, sizeof(accept_key) - 1)) {
		if (sizeof(event_stream_val) - 1 == vend - val &&
		    0 == strncasecmp(val, event_stream_val, sizeof(event_stream_val) - 1)) {
		    r->upgrade = AGOO_UP_SSE;
		}
	    }
	    key = h + 1;
	    kend = NULL;
	    val = NULL;
	    vend = NULL;
	    break;
	default:
	    break;
	}
    }
    if (upgrade && ws) {
	r->upgrade = AGOO_UP_WS;
    }
}
fill_headers(agooReq r, VALUE hash) {
    char	*h = r->header.start;
    char	*end = h + r->header.len + 1;  
    char	*key = h;
    char	*kend = key;
    char	*val = NULL;
    char	*vend;
    int		klen;
    bool	upgrade = false;
    bool	ws = false;

    if (NULL == r) {
	rb_raise(rb_eArgError, "Request is no longer valid.");
    }

    for (; h < end; h++) {
	switch (*h) {
	case ':':
	    if (NULL == val) {
		kend = h;
		val = h + 1;
	    }
	    break;
	case '\r':
	    if (NULL != val) {
		for (; ' ' == *val; val++) {
		}
		vend = h;
	    }
	    if (NULL != key) {
		for (; ' ' == *key; key++) {
		}
	    }
	    if ('\n' == *(h + 1)) {
		h++;
	    }
	    klen = (int)(kend - key);
	    add_header_value(hash, key, klen, val, (int)(vend - val));
	    if (sizeof(upgrade_key) - 1 == klen && 0 == strncasecmp(key, upgrade_key, sizeof(upgrade_key) - 1)) {
		if (sizeof(websocket_val) - 1 == vend - val &&
		    0 == strncasecmp(val, websocket_val, sizeof(websocket_val) - 1)) {
		    ws = true;
		}
	    } else if (sizeof(connection_key) - 1 == klen && 0 == strncasecmp(key, connection_key, sizeof(connection_key) - 1)) {
		char	buf[1024];

		strncpy(buf, val, vend - val);
		buf[sizeof(buf)-1] = '\0';
		if (NULL != strstr(buf, upgrade_key)) {
		    upgrade = true;
		}
	    } else if (sizeof(accept_key) - 1 == klen && 0 == strncasecmp(key, accept_key, sizeof(accept_key) - 1)) {
		if (sizeof(event_stream_val) - 1 == vend - val &&
		    0 == strncasecmp(val, event_stream_val, sizeof(event_stream_val) - 1)) {
		    r->upgrade = AGOO_UP_SSE;
		}
	    }
	    key = h + 1;
	    kend = NULL;
	    val = NULL;
	    vend = NULL;
	    break;
	default:
	    break;
	}
    }
    if (upgrade && ws) {
	r->upgrade = AGOO_UP_WS;
    }
}