return false;
}
- multimap<string, string> parameters;
- for (size_t i = 1; i < lines.size(); ++i) {
- size_t split = lines[i].find(":");
- if (split == string::npos) {
- log(WARNING, "[%s] Ignoring malformed HTTP response line '%s'",
- url.c_str(), lines[i].c_str());
- continue;
- }
-
- string key(lines[i].begin(), lines[i].begin() + split);
-
- // Skip any spaces after the colon.
- do {
- ++split;
- } while (split < lines[i].size() && lines[i][split] == ' ');
+ multimap<string, string> parameters = extract_headers(lines, url);
- string value(lines[i].begin() + split, lines[i].end());
-
- // Remove “Content-encoding: metacube”.
- // TODO: Make case-insensitive.
- if (key == "Content-encoding" && value == "metacube") {
- continue;
- }
-
- parameters.insert(make_pair(key, value));
+ // Remove “Content-encoding: metacube”.
+ // TODO: Make case-insensitive.
+ multimap<string, string>::iterator encoding_it =
+ parameters.find("Content-encoding");
+ if (encoding_it != parameters.end() && encoding_it->second == "metacube") {
+ parameters.erase(encoding_it);
}
// Change “Server: foo” to “Server: metacube/0.1 (reflecting: foo)”
#include <string>
#include <vector>
+#include "log.h"
#include "parse.h"
using namespace std;
return ret;
}
+multimap<string, string> extract_headers(const vector<string> &lines, const string &log_context)
+{
+ multimap<string, string> parameters;
+ for (size_t i = 1; i < lines.size(); ++i) {
+ size_t split = lines[i].find(":");
+ if (split == string::npos) {
+ log(WARNING, "[%s] Ignoring malformed HTTP response line '%s'",
+ log_context.c_str(), lines[i].c_str());
+ continue;
+ }
+
+ string key(lines[i].begin(), lines[i].begin() + split);
+
+ // Skip any spaces after the colon.
+ do {
+ ++split;
+ } while (split < lines[i].size() && lines[i][split] == ' ');
+
+ string value(lines[i].begin() + split, lines[i].end());
+
+ parameters.insert(make_pair(key, value));
+ }
+
+ return parameters;
+}
+
#define MAX_REQUEST_SIZE 16384 /* 16 kB. */
RequestParseStatus wait_for_double_newline(string *existing_data, const char *new_data, size_t new_data_size)
// Various routines that deal with parsing; both HTTP requests and more generic text.
#include <stddef.h>
+#include <map>
#include <string>
#include <vector>
// Split a string on \n or \r\n, e.g. "foo\nbar\r\n\nbaz\r\n\r\n" -> {"foo", "bar", "baz"}.
std::vector<std::string> split_lines(const std::string &str);
+// Extract HTTP headers from a request or response. Ignores the first line,
+// where the verb or the return code is.
+std::multimap<std::string, std::string> extract_headers(
+ const std::vector<std::string> &lines, const std::string &log_context);
+
// Add the new data to an existing string, looking for \r\n\r\n
// (typical of HTTP requests and/or responses). Will return one
// of the given statuses.