Пример #1
0
bool CHttpServer::parse_request(String &method, String &uri, String &query, HeaderList &headers, String &body )
{
    method.clear();
    uri.clear();
    headers.clear();
    body.clear();

    size_t s = 0;
    ByteVector request;

    bool parsing_headers = true;
    size_t content_length = 0;

    for (;;) {
        if (!receive_request(request))
            return false;

        size_t lim = request.size();
        while (parsing_headers) {
            size_t e;
            for(e = s; e < lim && request[e] != '\r'; ++e);
            if (e >= lim - 1) {
                // Incomplete line, will read further
                break;
            }
            if (request[e + 1] != '\n') {
                if (verbose) RAWLOG_ERROR("Wrong request syntax, line should ends by '\\r\\n'");
                return false;
            }
            
            String line(&request[s], e - s);
            s = e + 2;
            
            if (line.empty()) {
                parsing_headers = false;
                break;
            }
            
            if (uri.empty()) {
                // Parse start line
                if (!parse_startline(line, method, uri, query) || uri.empty())
                    return false;
            }
            else {
                Header hdr;
                if (!parse_header(line, hdr) || hdr.name.empty())
                    return false;
                headers.push_back(hdr);
                
                String low;
                std::transform(hdr.name.begin(), hdr.name.end(), std::back_inserter(low), &::tolower);
                if (low == "content-length") {
                    content_length = ::atoi(hdr.value.c_str());
                }
            }
        }

        if (!parsing_headers) {
            if (content_length == 0)
                return true;

            if (lim - s < content_length)
                continue;

            body.assign(&request[s], &request[s] + content_length);
            return true;
        }
    }
}