bool HttpMessage::ParseHeaders(const StringPiece& data, HttpMessage::ErrorCode* error) { HttpMessage::ErrorCode error_placeholder; if (error == NULL) error = &error_placeholder; StringPiece::size_type pos = data.find_first_of('\n'); if (pos == StringPiece::npos) { pos = data.size(); } std::string first_line = StringTrimRight(data.substr(0, pos), "\r"); if (first_line.empty()) { *error = HttpMessage::ERROR_NO_START_LINE; return false; } if (!ParseStartLine(first_line, error)) return false; int error_code = 0; bool result = m_headers.Parse(data.substr(pos + 1), &error_code); *error = static_cast<HttpMessage::ErrorCode>(error_code); return result; }
/// Return the vocID of word "text" if it exist in the vocabulary /// Otherwise return 0 IndexType C_IDVocabulary::returnId(const StringPiece &text) const { StringPiece stemmed(text); if (stem_len_ > 0) { //take first stem_len_ characters stemmed = text.substr(stem_len_); } else if ((stem_len_ < 0) && (text.length() > -stem_len_)) {//take last stem_len_ characters stemmed = text.substr(text.length() + stem_len_, -stem_len_); } //otherwise leave as it is WordId::const_iterator iter = word_id_.find(stemmed); if(iter == word_id_.end()) { return 0; } else { return iter->second; } }
bool HttpRequest::ParseStartLine(const StringPiece& data, HttpMessage::ErrorCode* error) { ErrorCode error_placeholder; if (error == NULL) error = &error_placeholder; static const size_t kMinHttpMethodLength = 3; size_t pos = data.find(' ', kMinHttpMethodLength); if (pos == StringPiece::npos) { *error = ERROR_START_LINE_NOT_COMPLETE; return false; } StringPiece method = data.substr(0, pos); StringTrim(&method); m_method = GetMethodByName(method); if (m_method == METHOD_UNKNOWN) { *error = ERROR_METHOD_NOT_FOUND; return false; } size_t prev_pos = pos + 1; pos = data.find(' ', prev_pos); StringPiece uri; if (pos == StringPiece::npos) { uri = data.substr(prev_pos); } else { uri = data.substr(prev_pos, pos - prev_pos); } StringTrim(&uri); uri.copy_to_string(&m_uri); if (pos != StringPiece::npos) { StringPiece version = data.substr(pos); StringTrim(&version); if (!ParseVersion(version)) { *error = ERROR_VERSION_UNSUPPORTED; return false; } } return true; }
static inline void SplitUsingStringDelimiterToIterator(const StringPiece& full, const char* delim, ITR& result) { if (full.empty()) { return; } if (delim[0] == '\0') { *result++ = full.as_string(); return; } // Optimize the common case where delim is a single character. if (delim[1] == '\0') { SplitStringToIteratorUsing(full, delim, result); return; } size_t delim_length = strlen(delim); for (std::string::size_type begin_index = 0; begin_index < full.size(); ) { std::string::size_type end_index = full.find(delim, begin_index); if (end_index == std::string::npos) { *result++ = full.substr(begin_index).as_string(); return; } if (end_index > begin_index) { *result++ = full.substr(begin_index, (end_index - begin_index)).as_string(); } begin_index = end_index + delim_length; } }
static inline void SplitStringToIteratorUsing(const StringPiece& full, const char* delim, ITR& result) { // Optimize the common case where delim is a single character. if (delim[0] != '\0' && delim[1] == '\0') { char c = delim[0]; const char* p = full.data(); const char* end = p + full.size(); while (p != end) { if (*p == c) ++p; else { const char* start = p; while (++p != end && *p != c) {} *result++ = StringType(start, p - start); } } return; } std::string::size_type begin_index, end_index; begin_index = full.find_first_not_of(delim); while (begin_index != std::string::npos) { end_index = full.find_first_of(delim, begin_index); if (end_index == std::string::npos) { *result++ = full.substr(begin_index).as_string(); return; } *result++ = full.substr(begin_index, (end_index - begin_index)).as_string(); begin_index = full.find_first_not_of(delim, end_index); } }
static std::vector<std::string> splitAndTransform(const StringPiece& str, char sep, const std::function<char(char)>& f) { std::vector<std::string> parts; const StringPiece::const_iterator end = std::end(str); StringPiece::const_iterator start = std::begin(str); StringPiece::const_iterator current; do { current = std::find(start, end, sep); parts.emplace_back(str.substr(start, current).toString()); if (f) { std::string& part = parts.back(); std::transform(part.begin(), part.end(), part.begin(), f); } start = current + 1; } while (current != end); return parts; }
size_t HttpHeaders::Parse(const StringPiece& data, int* error) { int error_placeholder; if (error == NULL) error = &error_placeholder; // Starts with empty line means empty headers. if (StringStartsWith(data, "\n") || StringStartsWith(data, "\r\n")) { m_headers.clear(); return (data[0] == '\r') + 1; // sizeof \n or \r\n } size_t end_pos; size_t tail_size; if ((end_pos = data.find("\r\n\r\n")) != std::string::npos) { tail_size = 4; } else if ((end_pos = data.find("\n\n")) != std::string::npos) { tail_size = 2; } else { *error = HttpMessage::ERROR_MESSAGE_NOT_COMPLETE; return 0; } std::vector<StringPiece> lines; SplitLines(data.substr(0, end_pos + tail_size), &lines); if (lines.empty()) { *error = HttpMessage::ERROR_MESSAGE_NOT_COMPLETE; return 0; } m_headers.clear(); // Skip the head line and the last line(empty but '\n') for (int i = 0; i < static_cast<int>(lines.size() - 1); ++i) { StringPiece line = lines[i]; size_t pos = line.find(':'); if (pos != StringPiece::npos) { StringPiece name = line.substr(0, pos); StringPiece value = line.substr(pos + 1); StringTrim(&name); StringTrim(&value); // Push an empty element and modify it to avoid copy. m_headers.push_back(std::pair<std::string, std::string>()); std::pair<std::string, std::string> &header = m_headers.back(); name.copy_to_string(&header.first); value.copy_to_string(&header.second); } else { if (!lines[i].empty()) { VLOG(3) << "Invalid http header" << lines[i] << ", ignore"; } else { *error = HttpMessage::ERROR_FIELD_NOT_COMPLETE; m_headers.clear(); return 0; } } } *error = HttpMessage::SUCCESS; return end_pos + tail_size; }