]> git.sesse.net Git - cubemap/blobdiff - parse.cpp
Support quoted spaces in configuration files.
[cubemap] / parse.cpp
index eed7d19572a8af588bb4230c4a1b0bee01c6ffa9..9c7fd10b2f0c87a4f01e1e6112d683c07ccd3e18 100644 (file)
--- a/parse.cpp
+++ b/parse.cpp
@@ -1,11 +1,9 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include <ctype.h>
-#include <assert.h>
-#include <vector>
+#include <string.h>
 #include <string>
+#include <vector>
 
+#include "log.h"
 #include "parse.h"
 
 using namespace std;
@@ -15,8 +13,23 @@ vector<string> split_tokens(const string &line)
        vector<string> ret;
        string current_token;
 
+       bool in_quote = false;
+
        for (size_t i = 0; i < line.size(); ++i) {
-               if (isspace(line[i])) {
+               // Handle all escaped characters.
+               if (line[i] == '\\' && i < line.size() - 1) {
+                       current_token.push_back(line[++i]);
+                       continue;
+               }
+
+               // Handle start and end quote.
+               if (line[i] == '"') {
+                       in_quote = !in_quote;
+                       continue;
+               }
+
+               // Handle break.
+               if (isspace(line[i]) && !in_quote) {
                        if (!current_token.empty()) {
                                ret.push_back(current_token);
                        }
@@ -58,6 +71,32 @@ vector<string> split_lines(const string &str)
        return ret;
 }
 
+HTTPHeaderMultimap extract_headers(const vector<string> &lines, const string &log_context)
+{
+       HTTPHeaderMultimap 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] == ' ' || lines[i][split] == '\t'));
+
+               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)
@@ -76,7 +115,7 @@ RequestParseStatus wait_for_double_newline(string *existing_data, const char *ne
        const char *ptr = reinterpret_cast<char *>(
                memmem(existing_data->data() + start_at, existing_data->size() - start_at,
                       "\r\n\r\n", 4));
-       if (ptr == NULL) {
+       if (ptr == nullptr) {
                return RP_NOT_FINISHED_YET;
        }
        if (ptr != existing_data->data() + existing_data->size() - 4) {