Exemplo n.º 1
0
bool us_http_server_handler_readable_request_header(us_reactor_handler_tcp_t *self_) {
    us_http_server_handler_t *self = (us_http_server_handler_t *)self_;
    bool r = true;
    us_buffer_t *incoming = &self->m_base.m_incoming_queue;
    size_t i;
    bool found_end_of_header = false;
    us_log_tracepoint();
    /* scan until "\r\n\r\n" is seen in the incoming queue */
    for (i = self->m_byte_count; i < us_buffer_readable_count(incoming) - 3; i++) {
        if (us_buffer_peek(incoming, i) == '\r' && us_buffer_peek(incoming, i + 1) == '\n'
            && us_buffer_peek(incoming, i + 2) == '\r' && us_buffer_peek(incoming, i + 3) == '\n') {
            found_end_of_header = true;
            /* skip over the request header that we parsed */
            break;
        }
    }
    if (found_end_of_header) {
        /* found the end of the header, try parse it */
        r = us_http_server_handler_parse_request_header(self);
        /* if parsing fails, r=false means that the socket will close */
        if (r) {
            us_log_debug("Parsed header");
        } else {
            us_log_debug("Parsing header failed");
        }
    } else {
        if (i > 4) {
            self->m_byte_count = i - 4;
        }
    }
    return r;
}
Exemplo n.º 2
0
bool us_http_server_handler_parse_request_header(us_http_server_handler_t *self) {
    bool r = false;
    us_log_tracepoint();
    r = us_http_request_header_parse(self->m_request_header, &self->m_base.m_incoming_queue);
    if (r) {
        /* we have parsed a request! */
        /* TODO: see if http version is 1.1 or higher */
        /* bool http_vesion_1_1 = us_http_request_header_get_http_version( self->m_request_header )>11 */
        /* TODO: try find Connection: Close */
        /* bool connection_close = us_http_request_header_get_connection_close( self->m_request_header ); */
        /* TODO: try find Connetion: Keep-Alive */
        /* bool connection_keep_alive = us_http_request_header_get_connection_keep_alive */
        /* TODO: try find the expected content length */
        /* Get Content-Length field, if there is one */
        /* Some verbs might have content even if content length field is nonexistant */
        if (strcmp(self->m_request_header->m_method, "POST") == 0 || strcmp(self->m_request_header->m_method, "PUT") == 0) {
            /* if we don't have a content_length item, by default todo_count is -1 meaning 'wait for close' */
            self->m_todo_count = us_http_request_header_get_content_length(self->m_request_header, -1);
            us_log_debug("Request method is '%s', path is '%s', content length is %d",
                         self->m_request_header->m_method,
                         self->m_request_header->m_path,
                         self->m_todo_count);
        } else {
            /* any other verb by default has no content if content-length is missing */
            self->m_todo_count = us_http_request_header_get_content_length(self->m_request_header, 0);
            us_log_debug(
                "Request method is '%s', path is '%s'", self->m_request_header->m_method, self->m_request_header->m_path);
        }
        /*
           now, if we have a non-zero content-length to exepect, either -1 or >0,
           and this there is still content to receive,
           then we go to receive content state.
           otherwise, we go straight to handling the request immediately
        */
        if (self->m_todo_count != 0) {
            if (self->m_todo_count > (ssize_t)us_buffer_readable_count(&self->m_base.m_incoming_queue)) {
                us_http_server_handler_set_state_receiving_request_content(self);
                r = true;
            } else {
                r = us_http_server_handler_dispatch(self);
            }
        } else {
            r = us_http_server_handler_dispatch(self);
        }
    }
    if (!r) {
        self->m_base.close(&self->m_base);
    }
    if (r) {
        us_log_debug("Response code is %d, content length is %ld",
                     self->m_response_header->m_code,
                     us_buffer_readable_count(self->m_response_content));
    }
    return r;
}
Exemplo n.º 3
0
bool us_http_server_handler_writable_response(us_reactor_handler_tcp_t *self_) {
    (void)self_;
    /* once the entire response is sent, close the socket */
    us_log_tracepoint();
    us_log_debug("entire response sent, socket is closing");
    return false;
}
Exemplo n.º 4
0
bool us_http_server_handler_dispatch(us_http_server_handler_t *self) {
    bool r = false;
    us_buffer_t *incoming = &self->m_base.m_incoming_queue;
    us_buffer_t *outgoing = &self->m_base.m_outgoing_queue;
    us_log_tracepoint();
    if (self->m_director->dispatch(
            self->m_director, self->m_request_header, incoming, self->m_response_header, self->m_response_content) >= 0) {
        r = us_http_response_header_flatten(self->m_response_header, outgoing);
        if (r) {
            /* Send content if it was not a HEAD request */
            if (strcmp(self->m_request_header->m_method, "HEAD") != 0) {
                if (us_buffer_writable_count(outgoing) > us_buffer_readable_count(self->m_response_content)) {
                    us_buffer_write_buffer(outgoing, self->m_response_content);
                    us_http_server_handler_set_state_sending_response(self);
                    /* response header and response content is now in the outgoing buffer */
                    r = true;
                    us_log_debug("response header and content ready");
                } else {
                    r = false;
                    us_log_error("unable to buffer http response content");
                }
            } else {
                us_http_server_handler_set_state_sending_response(self);
                r = true;
            }
        } else {
            us_log_error("unable to flatten response header");
        }
    }
    if (!r) {
        self->m_base.close(&self->m_base);
    }
    return r;
}
Exemplo n.º 5
0
bool us_http_server_handler_eof_response(us_reactor_handler_tcp_t *self_) {
    bool r = true;
    (void)self_;
    /* eof on incoming data while sending response header is to be ignored */
    us_log_tracepoint();
    us_log_debug("incoming socket closed during response, ignored");
    return r;
}
Exemplo n.º 6
0
bool us_http_server_handler_connected(us_reactor_handler_tcp_t *self_, struct sockaddr *addr, socklen_t addrlen) {
    /* someone made a tcp connection to us, clear our buffers, allocators, and parsers */
    us_http_server_handler_t *self = (us_http_server_handler_t *)self_;
    us_log_tracepoint();
    if (us_log_level >= US_LOG_LEVEL_DEBUG && addr) {
        char hostname_buf[1024];
        char srv_buf[64];
        if (getnameinfo(
                addr, addrlen, hostname_buf, sizeof(hostname_buf), srv_buf, sizeof(srv_buf), NI_NUMERICHOST | NI_NUMERICSERV)
            == 0) {
            us_log_debug("accepted connection from '%s port %s'", hostname_buf, srv_buf);
        } else {
            us_log_debug("accepted connection, unable to resolve address");
        }
    }
    /* we are now in receiving request header */
    us_http_server_handler_set_state_receiving_request_header(self);
    return true;
}
Exemplo n.º 7
0
bool us_http_server_handler_eof_request_content(us_reactor_handler_tcp_t *self_) {
    us_http_server_handler_t *self = (us_http_server_handler_t *)self_;
    bool r = false;
    us_log_tracepoint();
    if (self->m_todo_count == -1) {
        /* when content length is unknown then eof means end of request content, time to dispatch request */
        r = us_http_server_handler_dispatch(self);
    } else {
        us_log_debug("eof during request content xfer");
    }
    return r;
}
Exemplo n.º 8
0
bool us_http_server_handler_readable_request_content(us_reactor_handler_tcp_t *self_) {
    us_http_server_handler_t *self = (us_http_server_handler_t *)self_;
    bool r = true;
    us_buffer_t *incoming = &self->m_base.m_incoming_queue;
    us_log_tracepoint();
    /* if content length is -1, we read until close */
    /* if content length is non zero, we read until incoming queue contains that much */
    if (self->m_todo_count == -1) {
        r = true;
    } else if ((ssize_t)us_buffer_readable_count(incoming) >= self->m_todo_count) {
        us_log_debug("got request content of %d bytes", self->m_todo_count);
        r = us_http_server_handler_dispatch(self);
    }
    return r;
}
Exemplo n.º 9
0
int us_test_allocator_main( int argc, const char **argv )
{
    int r = 1;
    if ( us_testutil_start( 2048, 2048, argc, argv ) )
    {
        char *b;
#if US_ENABLE_LOGGING
        us_logger_printer_start( us_testutil_printer_stdout, us_testutil_printer_stderr );
#endif
        us_log_set_level( US_LOG_LEVEL_DEBUG );
        us_log_info( "Hello world from %s compiled on %s", __FILE__, __DATE__ );
        b = (char *)us_testutil_sys_allocator->alloc( us_testutil_sys_allocator, 512, 1 );
        us_log_debug( "result from alloc of 512 bytes: %p", b );
        us_log_info( "Finishing us_test_allocator" );
        us_logger_finish();
        us_testutil_finish();
        r = 0;
    }
    return r;
}
Exemplo n.º 10
0
static bool system_name_write(us_test_trie_schema_entry_t *US_UNUSED(self)) {
    us_log_debug("%s: ", __FUNCTION__);
    us_log_info("new system name: %s ", device_name);
    return true;
}
Exemplo n.º 11
0
static bool system_name_read(us_test_trie_schema_entry_t *US_UNUSED(self)) {
    us_log_debug("%s: ", __FUNCTION__);
    return true;
}