mem_cache.cc revision 3551c9c881056c480085172ff9840cab31610854
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2009 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/mem_cache.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dirent.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <map>
17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <string>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/strings/string_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/dump_cache/url_to_filename_encoder.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/dump_cache/url_utilities.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/balsa_frame.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/balsa_headers.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The directory where cache locates);
27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char FLAGS_cache_base_dir[] = ".";
28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreBodyAndHeadersVisitor::ProcessBodyData(const char *input,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 size_t size) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  body.append(input, size);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreBodyAndHeadersVisitor::HandleHeaderError(BalsaFrame* framer) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HandleError();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreBodyAndHeadersVisitor::HandleHeaderWarning(BalsaFrame* framer) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HandleError();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreBodyAndHeadersVisitor::HandleChunkingError(BalsaFrame* framer) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HandleError();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StoreBodyAndHeadersVisitor::HandleBodyError(BalsaFrame* framer) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HandleError();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFileData::FileData(const BalsaHeaders* headers,
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   const std::string& filename,
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   const std::string& body)
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : filename_(filename)
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    , body_(body) {
58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (headers) {
59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    headers_.reset(new BalsaHeaders);
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    headers_->CopyFrom(*headers);
61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileData::FileData() {}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileData::~FileData() {}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochMemoryCache::MemoryCache() : cwd_(FLAGS_cache_base_dir) {}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochMemoryCache::~MemoryCache() {
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ClearFiles();
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryCache::CloneFrom(const MemoryCache& mc) {
75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK_NE(this, &mc);
76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ClearFiles();
77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  files_ = mc.files_;
78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  cwd_ = mc.cwd_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryCache::AddFiles() {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<std::string> paths;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paths.push_back(cwd_ + "/GET_");
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DIR* current_dir = NULL;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!paths.empty()) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (current_dir == NULL && !paths.empty()) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string current_dir_name = paths.front();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Attempting to open dir: \"" << current_dir_name << "\"";
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_dir = opendir(current_dir_name.c_str());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paths.pop_front();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (current_dir == NULL) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        perror("Unable to open directory. ");
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_dir_name.clear();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (current_dir) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        VLOG(1) << "Succeeded opening";
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (struct dirent* dir_data = readdir(current_dir);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             dir_data != NULL;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             dir_data = readdir(current_dir)) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::string current_entry_name =
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            current_dir_name + "/" + dir_data->d_name;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (dir_data->d_type == DT_REG) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            VLOG(1) << "Found file: " << current_entry_name;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadAndStoreFileContents(current_entry_name.c_str());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          } else if (dir_data->d_type == DT_DIR) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            VLOG(1) << "Found subdir: " << current_entry_name;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (std::string(dir_data->d_name) != "." &&
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                std::string(dir_data->d_name) != "..") {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              VLOG(1) << "Adding to search path: " << current_entry_name;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              paths.push_front(current_entry_name);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        VLOG(1) << "Oops, no data left. Closing dir.";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        closedir(current_dir);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_dir = NULL;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryCache::ReadToString(const char* filename, std::string* output) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output->clear();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fd = open(filename, 0, "r");
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fd == -1)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[4096];
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssize_t read_status = read(fd, buffer, sizeof(buffer));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (read_status > 0) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output->append(buffer, static_cast<size_t>(read_status));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_status = read(fd, buffer, sizeof(buffer));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (read_status <= 0 && errno == EINTR);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close(fd);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryCache::ReadAndStoreFileContents(const char* filename) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreBodyAndHeadersVisitor visitor;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BalsaFrame framer;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_balsa_visitor(&visitor);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_balsa_headers(&(visitor.headers));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string filename_contents;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReadToString(filename, &filename_contents);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ugly hack to make everything look like 1.1.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (filename_contents.find("HTTP/1.0") == 0)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filename_contents[7] = '1';
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = 0;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t old_pos = 0;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_pos = pos;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pos += framer.ProcessInput(filename_contents.data() + pos,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               filename_contents.size() - pos);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (framer.Error() || pos == old_pos) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unable to make forward progress, or error"
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        " framing file: " << filename;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (framer.Error()) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(INFO) << "********************************************ERROR!";
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (framer.MessageFullyRead()) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If no Content-Length or Transfer-Encoding was captured in the
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // file, then the rest of the data is the body.  Many of the captures
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // from within Chrome don't have content-lengths.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!visitor.body.length())
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        visitor.body = filename_contents.substr(pos);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.headers.RemoveAllOfHeader("content-length");
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.headers.RemoveAllOfHeader("transfer-encoding");
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.headers.RemoveAllOfHeader("connection");
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.headers.AppendHeader("transfer-encoding", "chunked");
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.headers.AppendHeader("connection", "keep-alive");
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Experiment with changing headers for forcing use of cached
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // versions of content.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mbelshe) REMOVE ME
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mbelshe) append current date.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.headers.RemoveAllOfHeader("date");
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visitor.headers.HasHeader("expires")) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.headers.RemoveAllOfHeader("expires");
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.headers.AppendHeader("expires",
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               "Fri, 30 Aug, 2019 12:00:00 GMT");
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK_GE(std::string(filename).size(), cwd_.size() + 1);
196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK_EQ(std::string(filename).substr(0, cwd_.size()), cwd_);
197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK_EQ(filename[cwd_.size()], '/');
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string filename_stripped = std::string(filename).substr(cwd_.size() + 1);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Adding file (" << visitor.body.length() << " bytes): "
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << filename_stripped;
201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  size_t slash_pos = filename_stripped.find('/');
202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (slash_pos == std::string::npos) {
203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    slash_pos = filename_stripped.size();
204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  InsertFile(&visitor.headers,
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             filename_stripped.substr(0, slash_pos),
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             visitor.body);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileData* MemoryCache::GetFileData(const std::string& filename) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Files::iterator fi = files_.end();
212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (EndsWith(filename, ".html", true)) {
213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    fi = files_.find(filename.substr(0, filename.size() - 5) + ".http");
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fi == files_.end())
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi = files_.find(filename);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fi == files_.end()) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return fi->second;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MemoryCache::AssignFileData(const std::string& filename,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 MemCacheIter* mci) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mci->file_data = GetFileData(filename);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mci->file_data == NULL) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not find file data for " << filename;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MemoryCache::InsertFile(const BalsaHeaders* headers,
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             const std::string& filename,
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             const std::string& body) {
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  InsertFile(new FileData(headers, filename, body));
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MemoryCache::InsertFile(FileData* file_data) {
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Files::iterator it = files_.find(file_data->filename());
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (it != files_.end()) {
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delete it->second;
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    it->second = file_data;
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    files_.insert(std::make_pair(file_data->filename(), file_data));
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid MemoryCache::ClearFiles() {
251ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (Files::const_iterator i = files_.begin(); i != files_.end(); ++i) {
252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    delete i->second;
253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  files_.clear();
255ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace net
258