Example #1
0
YETI_Result HttpHeaders::parse(BufferedInputStream & stream)
{
    String header_name;
    String header_value;
    bool   header_pending = false;
    String line;

    while (YETI_SUCCEEDED(stream.read_line(line, YETI_HTTP_PROTOCOL_MAX_LINE_LENGTH))) {
        if (line.get_length() == 0) {
            // end of headers
            break;
        }
        if (header_pending && (line[0] == ' ' || line[0] == '\t')) {
            header_value.append(line.get_chars() + 1, line.get_length() - 1);
        } else {
            if (header_pending) {
                header_value.trim();
                add_header(header_name, header_value);
                header_pending = false;
                YETI_LOG_FINEST_2("header - %s: %s", header_name.get_chars(), header_value.get_chars());
            }

            int colon_index = line.find(':');
            if (colon_index < 1) {
                // invalid syntax, ignore
                continue;
            }
            header_name = line.left(colon_index);
            const char * value = line.get_chars() + colon_index + 1;
            while (*value == ' ' || *value == '\t') {
                value++;
            }
            header_value =  value;
            header_pending = true;
        }
    }

    if (header_pending) {
        header_value.trim();
        add_header(header_name, header_value);
        YETI_LOG_FINEST_2("header - %s: %s", header_name.get_chars(), header_value.get_chars());
    }

    return YETI_SUCCESS;
}
Example #2
0
YETI_Result HttpResponse::parse(BufferedInputStream & stream,
                                HttpResponse *& response)
{
    response = NULL;
    String line;
    YETI_CHECK_FINE(stream.read_line(line, YETI_HTTP_PROTOCOL_MAX_LINE_LENGTH));
    /*if (YETI_FAILED(res)) {
    if (res != YETI_ERROR_TIMEOUT && res != YETI_ERROR_EOS) YETI_CHECK_WARNING(res);
    return res;
    }*/

    YETI_LOG_FINE_1("http response: %s", line.get_chars());

    int first_space = line.find(' ');
    if (first_space < 1) return YETI_ERROR_HTTP_INVALID_RESPONSE_LINE;
    int second_space =  line.find(' ', first_space + 1);
    if (second_space < 0) {
        if (line.get_length() != 12) {
            return YETI_ERROR_HTTP_INVALID_RESPONSE_LINE;
        }
    } else if (second_space != 4) {
        return YETI_ERROR_HTTP_INVALID_RESPONSE_LINE;
    }

    String protocol = line.sub_string(0, first_space);
    String status_code = line.sub_string(first_space + 1, 3);
    String reason_phrase = line.sub_string(first_space + 1 + 3 + 1,
        line.get_length() - (first_space + 1 + 3 + 1));

    YETI_UInt32 status_code_int = 0;
    status_code.to_integer32(status_code_int);
    response = new HttpResponse(status_code_int, reason_phrase, protocol);

    YETI_Result result = response->parse_headers(stream);
    if (YETI_FAILED(result)) {
        delete response;
        response = NULL;
    }

    return result;
}
Example #3
0
YETI_Result File::save(const char * path, String & data)
{
    DataBuffer buffer(data.get_chars(), data.get_length());
    return File::save(path, buffer);
}
Example #4
0
YETI_Result HttpRequest::parse(BufferedInputStream & stream,
                               const SocketAddress * endpoint,
                               HttpRequest *& request)
{
    // default return value
    request = NULL;
skip_first_empty_line:
    // read the request line
    String line;
    YETI_CHECK_FINER(stream.read_line(line, YETI_HTTP_PROTOCOL_MAX_LINE_LENGTH));
    YETI_LOG_FINEST_1("http request: %s", line.get_chars());
    // when using keep-alive connections, clients such as XBox 360
    // incorrectly send a few empty lines as body for GET requests
    // so we try to skip them until we find something to parse
    if (line.get_length() == 0) goto skip_first_empty_line;
    if (line.get_length() == 0) goto skip_first_empty_line;

    // check the request line
    int first_space = line.find(' ');
    if (first_space < 0) {
        YETI_LOG_FINE_1("http request: %s", line.get_chars());
        return YETI_ERROR_HTTP_INVALID_REQUEST_LINE;
    }
    int second_space = line.find(' ', first_space + 1);
    if (second_space < 0) {
        YETI_LOG_FINE_1("http request: %s", line.get_chars());
        return YETI_ERROR_HTTP_INVALID_REQUEST_LINE;
    }

    // parse the request line
    String method = line.sub_string(0, first_space);
    String uri = line.sub_string(first_space + 1, second_space - first_space - 1);
    String protocol = line.sub_string(second_space + 1);

    // create a request
    bool proxy_style_request = false;
    if (uri.starts_with("http://", true)) {
        // proxy-style request with absolute URI
        request = new HttpRequest(uri, method, protocol);
        proxy_style_request = true;
    } else {
        // normal absolute path request
        request = new HttpRequest("http:", method, protocol);
    }

    // parse headers
    YETI_Result result = request->parse_headers(stream);
    if (YETI_FAILED(result)) {
        delete request;
        request = NULL;
        return result;
    }

    // update the URL
    if (!proxy_style_request) {
        request->m_url_.set_scheme("http");
        request->m_url_.parse_pathplus(uri);
        request->m_url_.set_port(YETI_HTTP_DEFAULT_PORT);

        // check for a Host: header
        HttpHeader * host_header = request->get_headers().get_header(YETI_HTTP_HEADER_HOST);
        if (host_header) {
            request->m_url_.set_host(host_header->get_value());
            // host sometimes doesn't contain port
            if (endpoint) {
                request->m_url_.set_port(endpoint->get_port());
            }
        } else {
            // use the endpoint as the host
            if (endpoint) {
                request->m_url_.set_host(endpoint->to_string());
            } else {
                // use defaults
                request->m_url_.set_host("localhost");
            }
        }
    }

    return YETI_SUCCESS;
}
Example #5
0
YETI_Result HttpEntity::set_input_stream(const String & string)
{
    MemoryStream * memory_stream = new MemoryStream((const void *)string.get_chars(), string.get_length());
    InputStreamReference body(memory_stream);
    return set_input_stream(body, true);
}