Commit ee6cbf15 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

Merge branch 'brokenx0' into fnordmetric2

parents 0c233ef6 44b69187
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -23,6 +23,10 @@ set(FNORDMETRIC_SOURCES
    stage/src/fnordmetric/io/pagemanager.cc
    stage/src/fnordmetric/net/udpserver.cc
    stage/src/fnordmetric/environment.cc
    stage/src/fnordmetric/http/httpmessage.cc
    stage/src/fnordmetric/http/httprequest.cc
    stage/src/fnordmetric/http/httpresponse.cc
    stage/src/fnordmetric/http/httpserver.cc
    stage/src/fnordmetric/sstable/cursor.cc
    stage/src/fnordmetric/sstable/fileheaderreader.cc
    stage/src/fnordmetric/sstable/fileheaderwriter.cc
+116 −0
Original line number Diff line number Diff line
/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fnordmetric/util/inputstream.h>
#include <fnordmetric/http/httprequest.h>
#include <fnordmetric/http/httpresponse.h>
#include <fnordmetric/util/unittest.h>
#include <fnordmetric/util/runtimeexception.h>

using namespace fnord::http;

UNIT_TEST(HTTPTest);

TEST_CASE(HTTPTest, ParseHTTP1dot0Request, [] () {
  auto req = "GET / HTTP/1.0\r\n" \
             "\r\n";

  fnord::httputil::StringInputStream is(req);
  fnord::httphttp::HTTPInputStream http_is(&is);
  fnord::httphttp::HTTPRequest request;
  request.readFromInputStream(&http_is);

  EXPECT_EQ(request.getMethod(), "GET");
  EXPECT_EQ(request.getUrl(), "/");
  EXPECT_EQ(request.getVersion(), "HTTP/1.0");
  EXPECT_EQ(request.keepalive(), false);
});

TEST_CASE(HTTPTest, ParseHTTP1dot0KeepaliveRequest, [] () {
  auto req = "GET / HTTP/1.0\r\n" \
             "Connection: keep-alive\r\n" \
             "\r\n";

  fnord::httputil::StringInputStream is(req);
  fnord::httphttp::HTTPInputStream http_is(&is);
  fnord::httphttp::HTTPRequest request;
  request.readFromInputStream(&http_is);

  EXPECT_EQ(request.getMethod(), "GET");
  EXPECT_EQ(request.getUrl(), "/");
  EXPECT_EQ(request.getVersion(), "HTTP/1.0");
  EXPECT_EQ(request.keepalive(), true);
});

TEST_CASE(HTTPTest, ParseHTTP1dot1Request, [] () {
  auto req = "GET / HTTP/1.1\r\n" \
             "\r\n";

  fnord::httputil::StringInputStream is(req);
  fnord::httphttp::HTTPInputStream http_is(&is);
  fnord::httphttp::HTTPRequest request;
  request.readFromInputStream(&http_is);

  EXPECT_EQ(request.getMethod(), "GET");
  EXPECT_EQ(request.getUrl(), "/");
  EXPECT_EQ(request.getVersion(), "HTTP/1.1");
  EXPECT_EQ(request.keepalive(), true);
});

TEST_CASE(HTTPTest, PopulateHTTPResponseFromHTTP1dot1Request, [] () {
  auto req = "GET / HTTP/1.1\r\n" \
             "\r\n";

  fnord::httputil::StringInputStream is(req);
  fnord::httphttp::HTTPInputStream http_is(&is);
  fnord::httphttp::HTTPRequest request;
  request.readFromInputStream(&http_is);
  EXPECT(request.keepalive() == true);

  fnord::httphttp::HTTPResponse response;
  response.populateFromRequest(request);

  EXPECT_EQ(response.getVersion(), "HTTP/1.1");
});

TEST_CASE(HTTPTest, PopulateHTTPResponseFromHTTP1dot0Request, [] () {
  auto req = "GET / HTTP/1.0\r\n" \
             "\r\n";

  fnord::httputil::StringInputStream is(req);
  fnord::httphttp::HTTPInputStream http_is(&is);
  fnord::httphttp::HTTPRequest request;
  request.readFromInputStream(&http_is);

  fnord::httphttp::HTTPResponse response;
  response.populateFromRequest(request);

  EXPECT_EQ(response.getVersion(), "HTTP/1.0");
  EXPECT_EQ(response.getHeader("Connection"), "close");
});

TEST_CASE(HTTPTest, PopulateHTTPResponseFromHTTP1dot0KeepaliveRequest, [] () {
  auto req = "GET / HTTP/1.0\r\n" \
             "Connection: keep-alive\r\n" \
             "\r\n";

  fnord::httputil::StringInputStream is(req);
  fnord::httphttp::HTTPInputStream http_is(&is);
  fnord::httphttp::HTTPRequest request;
  request.readFromInputStream(&http_is);

  fnord::httphttp::HTTPResponse response;
  response.populateFromRequest(request);

  EXPECT_EQ(response.getVersion(), "HTTP/1.0");
  EXPECT_EQ(response.getHeader("Connection"), "keep-alive");
});
+31 −0
Original line number Diff line number Diff line
/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#ifndef _FNORDMETRIC_HTTPHANDLER_H
#define _FNORDMETRIC_HTTPHANDLER_H
#include <fnordmetric/http/httprequest.h>
#include <fnordmetric/http/httpresponse.h>

namespace fnord {
namespace http {

class HTTPHandler {
public:

  virtual ~HTTPHandler() {}

  virtual bool handleHTTPRequest(
      HTTPRequest* request,
      HTTPResponse* response) = 0;

};

}
}
#endif
+81 −0
Original line number Diff line number Diff line
/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2011-2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnordmetric/http/httprequest.h>

using fnordmetric::util::InputStream;
using fnordmetric::util::OutputStream;
using fnordmetric::util::StringInputStream;
using fnordmetric::util::StringOutputStream;

namespace fnord {
namespace http {

std::string HTTPMessage::kEmptyHeader = "";

const std::string& HTTPMessage::getVersion() const {
  return version_;
}

void HTTPMessage::setVersion(const std::string& version) {
  version_ = version;
}

const std::vector<std::pair<std::string, std::string>>&
    HTTPMessage::getHeaders() const {
  return headers_;
}

const std::string& HTTPMessage::getHeader(const std::string& key) const {
  for (const auto& header : headers_) {
    if (header.first == key) {
      return header.second;
    }
  }

  return kEmptyHeader;
}

void HTTPMessage::addHeader(const std::string& key, const std::string& value) {
  headers_.emplace_back(key, value);
}

void HTTPMessage::setHeader(const std::string& key, const std::string& value) {
  for (auto& header : headers_) {
    if (header.first == key) {
      header.second = value;
      return;
    }
  }

  headers_.emplace_back(key, value);
}

const std::string& HTTPMessage::getBody() const {
  return body_;
}

void HTTPMessage::addBody(const std::string& body) {
  body_ = body;
}

void HTTPMessage::clearBody() {
  body_.clear();
}

std::unique_ptr<InputStream> HTTPMessage::getBodyInputStream() const {
  return StringInputStream::fromString(body_);
}

std::unique_ptr<OutputStream> HTTPMessage::getBodyOutputStream() {
  return StringOutputStream::fromString(&body_);
}

}
}
Loading