Commit 38ed2ed9 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

httpmessage, http tests

parent bb424378
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ set(FNORDMETRIC_SOURCES
    stage/src/fnordmetric/ev/eventloop.cc
    stage/src/fnordmetric/http/httpinputstream.cc
    stage/src/fnordmetric/http/httpoutputstream.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
@@ -90,3 +91,7 @@ add_executable(tests/test-input-stream
add_executable(tests/test-csv-backend
    ${FNORDMETRIC_QUERY_SOURCES}
    stage/src/fnordmetric/query/backends/csv/csvbackend_test.cc)

add_executable(tests/test-http
    ${FNORDMETRIC_SOURCES}
    stage/src/fnordmetric/http/http_test.cc)

src/http/http_test.cc

0 → 100644
+118 −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 <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/http/httpinputstream.h>
#include <fnordmetric/util/unittest.h>
#include <fnordmetric/util/runtimeexception.h>

using namespace fnordmetric::http;

UNIT_TEST(HTTPTest);

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

  fnordmetric::util::StringInputStream is(req);
  fnordmetric::http::HTTPInputStream http_is(&is);
  fnordmetric::http::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";

  fnordmetric::util::StringInputStream is(req);
  fnordmetric::http::HTTPInputStream http_is(&is);
  fnordmetric::http::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";

  fnordmetric::util::StringInputStream is(req);
  fnordmetric::http::HTTPInputStream http_is(&is);
  fnordmetric::http::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";

  fnordmetric::util::StringInputStream is(req);
  fnordmetric::http::HTTPInputStream http_is(&is);
  fnordmetric::http::HTTPRequest request;
  request.readFromInputStream(&http_is);

  fnordmetric::http::HTTPResponse response;
  response.populateFromRequest(request);

  EXPECT_EQ(response.getVersion(), "HTTP/1.1");
  EXPECT_EQ(response.getHeader("Connection"), "keep-alive");
});

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

  fnordmetric::util::StringInputStream is(req);
  fnordmetric::http::HTTPInputStream http_is(&is);
  fnordmetric::http::HTTPRequest request;
  request.readFromInputStream(&http_is);

  fnordmetric::http::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";

  fnordmetric::util::StringInputStream is(req);
  fnordmetric::http::HTTPInputStream http_is(&is);
  fnordmetric::http::HTTPRequest request;
  request.readFromInputStream(&http_is);

  fnordmetric::http::HTTPResponse response;
  response.populateFromRequest(request);

  EXPECT_EQ(response.getVersion(), "HTTP/1.0");
  EXPECT_EQ(response.getHeader("Connection"), "keep-alive");
});
+46 −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/httpinputstream.h>
#include <fnordmetric/http/httprequest.h>

namespace fnordmetric {
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);
}

}
}

src/http/httpmessage.h

0 → 100644
+36 −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/>.
 */
#ifndef _FNORDMETRIC_WEB_HTTPMESSAGE_H
#define _FNORDMETRIC_WEB_HTTPMESSAGE_H
#include <vector>
#include <string>
#include <utility>

namespace fnordmetric {
namespace http {

class HTTPMessage {
public:
  const std::string& getVersion() const;
  void setVersion(const std::string& version);

  const std::vector<std::pair<std::string, std::string>>& getHeaders() const;
  const std::string& getHeader(const std::string& key) const;
  void addHeader(const std::string& key, const std::string& value);

protected:
  std::string version_;
  static std::string kEmptyHeader;
  std::vector<std::pair<std::string, std::string>> headers_;
};

}
}
#endif
+14 −3
Original line number Diff line number Diff line
@@ -18,13 +18,24 @@ void HTTPRequest::readFromInputStream(HTTPInputStream* input) {
  input->readHeaders(&headers_);
}

const std::string& HTTPRequest::getMethod() const {
  return method_;
}

const std::string& HTTPRequest::getUrl() const {
  return url_;
}

const std::vector<std::pair<std::string, std::string>>&
    HTTPRequest::getHeaders() const {
  return headers_;
const bool HTTPRequest::keepalive() const {
  if (getVersion() == "HTTP/1.1") {
    return true;
  }

  if (getHeader("Connection") == "keep-alive") {
    return true;
  }

  return false;
}

}
Loading