bool RequestParser::ParsePartHeaders(bool* need_more_data) {
  std::size_t off = 0;

  while (true) {
    std::string line;
    if (!GetNextLine(off, &line, false)) {
      // Need more data from next read.
      *need_more_data = true;
      return false;
    }

    off = off + line.size() + 2;  // +2 for CRLF

    if (line.empty()) {
      // Headers finished.
      break;
    }

    Header header;
    if (!SplitKV(line, ':', true, &header.first, &header.second)) {
      LOG_ERRO("Invalid part header line: %s", line.c_str());
      return false;
    }

    LOG_INFO("Part header (%s: %s)", header.first.c_str(),
             header.second.c_str());

    // Parse Content-Disposition.
    if (boost::iequals(header.first, headers::kContentDisposition)) {
      ContentDisposition content_disposition{ header.second };
      if (!content_disposition.valid()) {
        LOG_ERRO("Invalid content-disposition header: %s",
                 header.second.c_str());
        return false;
      }
      part_->set_name(content_disposition.name());
      part_->set_file_name(content_disposition.file_name());
      LOG_INFO("Content-Disposition (name=%s; filename=%s)",
               part_->name().c_str(), part_->file_name().c_str());
    }

    // TODO: Parse other headers.
  }

  // Remove the data which has just been parsed.
  pending_data_.erase(0, off);

  return true;
}
bool RequestParser::ParsePartHeaders(bool* need_more_data) {
  std::size_t off = 0;

  while (true) {
    std::string line;
    if (!GetNextLine(off, &line, false)) {
       
      *need_more_data = true;
      return false;
    }

    off = off + line.size() + 2;   

    if (line.empty()) {
       
      break;
    }

    Header header;
    if (!SplitKV(line, ':', true, &header.first, &header.second)) {
      LOG_ERRO("Invalid part header line: %s", line.c_str());
      return false;
    }

    LOG_INFO("Part header (%s: %s)", header.first.c_str(),
             header.second.c_str());

     
    if (boost::iequals(header.first, headers::kContentDisposition)) {
      ContentDisposition content_disposition{ header.second };
      if (!content_disposition.valid()) {
        LOG_ERRO("Invalid content-disposition header: %s",
                 header.second.c_str());
        return false;
      }
      part_->set_name(content_disposition.name());
      part_->set_file_name(content_disposition.file_name());
      LOG_INFO("Content-Disposition (name=%s; filename=%s)",
               part_->name().c_str(), part_->file_name().c_str());
    }

     
  }

   
  pending_data_.erase(0, off);

  return true;
}