Exemplo n.º 1
0
void doEmptyHeaderValueTest(Codec1& ingressCodec, Codec2& egressCodec) {
  uint8_t version = ingressCodec.getVersion();
  bool emptyAllowed = version != 2;
  FakeHTTPCodecCallback callbacks;
  ingressCodec.setCallback(&callbacks);
  HTTPMessage toSend;
  toSend.setMethod("GET");
  toSend.setURL("http://www.foo.com");
  auto& headers = toSend.getHeaders();
  headers.set("Host", "www.foo.com");
  headers.set("Pragma", "");
  headers.set("X-Test1", "yup");
  HTTPHeaderSize size;
  auto toParse = getSynStream(egressCodec, 1, toSend, 0, false, &size);
  ingressCodec.onIngress(*toParse);

  EXPECT_EQ(callbacks.sessionErrors, 0);
  EXPECT_EQ(callbacks.streamErrors, 0);
  ASSERT_NE(callbacks.msg.get(), nullptr);
  const auto& parsed = callbacks.msg->getHeaders();
  EXPECT_EQ(parsed.exists("Pragma"), emptyAllowed);
  EXPECT_EQ(parsed.exists("pragma"), emptyAllowed);
  EXPECT_EQ(parsed.getSingleOrEmpty("X-Test1"), "yup");
  // All codecs add the accept-encoding header
  EXPECT_EQ(parsed.exists("accept-encoding"), true);
  // SPDY/2 subtracts the Host header, but it should infer it from the host:port
  // portion of the requested url and present it in the headers
  EXPECT_EQ(parsed.exists("host"), true);
  EXPECT_EQ(callbacks.msg->getURL(), "http://www.foo.com");
  EXPECT_EQ(parsed.size(), emptyAllowed ? 4 : 3);
  EXPECT_TRUE(size.uncompressed > 0);
  EXPECT_TRUE(size.compressed > 0);
}
Exemplo n.º 2
0
// Test serializing and deserializing a header that has many values
TEST(SPDYCodecTest, HeaderWithManyValues) {
  const std::string kMultiValued = "X-Multi-Valued";
  const unsigned kNumValues = 1000;

  FakeHTTPCodecCallback callbacks;
  SPDYCodec egressCodec(TransportDirection::UPSTREAM,
                        SPDYVersion::SPDY3);
  SPDYCodec ingressCodec(TransportDirection::DOWNSTREAM,
                         SPDYVersion::SPDY3);
  ingressCodec.setCallback(&callbacks);

  HTTPMessage req;
  req.setMethod("GET");
  req.getHeaders().set("HOST", "www.foo.com");
  req.setURL("https://www.foo.com");
  for (unsigned i = 0; i < kNumValues; ++i) {
    req.getHeaders().add(kMultiValued, folly::to<string>("Value", i));
  }
  auto syn = getSynStream(egressCodec, 1, req);
  ingressCodec.onIngress(*syn);
  EXPECT_EQ(callbacks.messageBegin, 1);
  EXPECT_EQ(callbacks.headersComplete, 1);
  EXPECT_EQ(callbacks.messageComplete, 0);
  EXPECT_EQ(callbacks.streamErrors, 0);
  EXPECT_EQ(callbacks.sessionErrors, 0);
  CHECK_NOTNULL(callbacks.msg.get());
  EXPECT_EQ(callbacks.msg->getHeaders().getNumberOfValues(kMultiValued),
            kNumValues);
}
Exemplo n.º 3
0
HTTPMessage getGetRequest(const std::string& url) {
  HTTPMessage req;
  req.setMethod("GET");
  req.setURL(url);
  req.setHTTPVersion(1, 1);
  req.getHeaders().set(HTTP_HEADER_HOST, "www.foo.com");
  return req;
}
Exemplo n.º 4
0
unique_ptr<folly::IOBuf> getSynStream(Codec& egressCodec,
                                      uint32_t streamID) {
  HTTPMessage msg;
  msg.setMethod("GET");
  msg.getHeaders().set("HOST", "www.foo.com");
  msg.setURL("https://www.foo.com");
  return getSynStream(egressCodec, streamID, msg);
}
Exemplo n.º 5
0
void testPathAndQuery(const string& url,
                      const string& expectedPath,
                      const string& expectedQuery) {
  HTTPMessage msg;
  msg.setURL(url);

  EXPECT_EQ(msg.getURL(), url);
  EXPECT_EQ(msg.getPath(), expectedPath);
  EXPECT_EQ(msg.getQueryString(), expectedQuery);
}
Exemplo n.º 6
0
void testRemoveQueryParam(const string& url,
                          const string& queryParam,
                          const string& expectedUrl,
                          const string& expectedQuery) {
  HTTPMessage msg;
  msg.setURL(url);
  bool expectedChange = (url != expectedUrl);
  EXPECT_EQ(msg.removeQueryParam(queryParam), expectedChange);

  EXPECT_EQ(msg.getURL(), expectedUrl);
  EXPECT_EQ(msg.getQueryString(), expectedQuery);
}
Exemplo n.º 7
0
HTTPMessage getBigGetRequest(const std::string& url) {
  HTTPMessage req;
  req.setMethod("GET");
  req.setURL(url);
  req.setHTTPVersion(1, 1);
  req.getHeaders().set(HTTP_HEADER_HOST, "www.foo.com");
  req.getHeaders().add(HTTP_HEADER_USER_AGENT, "coolio");
  req.getHeaders().add(
      "x-huge-header",
      std::string(http2::kMaxFramePayloadLengthMin, '!'));
  return req;
}
Exemplo n.º 8
0
TEST(SPDYCodecTest, SegmentedHeaderBlock) {
  SPDYCodec egressCodec(TransportDirection::UPSTREAM,
                        SPDYVersion::SPDY3_1_HPACK);
  SPDYCodec ingressCodec(TransportDirection::DOWNSTREAM,
                         SPDYVersion::SPDY3_1_HPACK);
  // generate huge string to use as a header value
  string huge;
  uint32_t size = 20000;
  char ch = 'a';
  for (uint32_t i = 0; i < size; i++) {
    huge.push_back(ch);
    if (ch == 'z') {
      ch = 'a';
    } else {
      ch++;
    }
  }
  HTTPMessage req;
  req.setMethod("GET");
  req.setURL("http://www.facebook.com");
  auto& reqHeaders = req.getHeaders();
  reqHeaders.set("HOST", "www.facebook.com");
  // setting this huge header value will cause allocation of a separate IOBuf
  reqHeaders.set("X-FB-Huge", huge);
  auto buf = getSynStream(egressCodec, 1, req);
  FakeHTTPCodecCallback callbacks;
  ingressCodec.setCallback(&callbacks);
  ingressCodec.onIngress(*buf);
  EXPECT_EQ(callbacks.streamErrors, 0);
  EXPECT_EQ(callbacks.sessionErrors, 0);
  EXPECT_EQ(callbacks.headersComplete, 1);
  EXPECT_EQ(callbacks.msg->getHeaders().getSingleOrEmpty("x-fb-huge").size(),
            size);

  // do it for responses
  HTTPMessage resp;
  resp.setStatusCode(200);
  resp.setStatusMessage("OK");
  auto& respHeaders = resp.getHeaders();
  respHeaders.set("X-FB-Huge", huge);
  auto buf2 = getSynStream(ingressCodec, 1, resp);
  callbacks.reset();
  egressCodec.setCallback(&callbacks);
  egressCodec.onIngress(*buf2);
  EXPECT_EQ(callbacks.streamErrors, 0);
  EXPECT_EQ(callbacks.sessionErrors, 0);
  EXPECT_EQ(callbacks.headersComplete, 1);
  EXPECT_EQ(callbacks.msg->getHeaders().getSingleOrEmpty("x-fb-huge").size(),
            size);
}
Exemplo n.º 9
0
TEST(HTTPMessage, TestParseQueryParamsComplex) {
  HTTPMessage msg;
  std::vector<std::vector<std::string>> input = {
    {"", "", ""},
    {"key_and_equal_but_no_value", "=", ""},
    {"only_key", "", ""},
    {"key_and_value", "=", "value"},
    {"key_and_value_2", "=", "value2"},
    {"key_and_value_3", "=", "value3"}
  };

  for (int i = 0; i < (1 << input.size()); ++i) {
    std::vector<std::vector<std::string>> sub;
    for (size_t j = 0; j < input.size(); ++j) {
      if ((i & (1 << j))) {
        sub.push_back(input[j]);
      }
    }

    sort(sub.begin(), sub.end());
    do {
      bool first = true;
      std::string url = "/test?";
      for (const auto& val: sub) {
        if (first) {
          first = false;
        } else {
          url += "&";
        }

        url += val[0] + val[1] + val[2];
      }

      msg.setURL(url);
      for (const auto& val: sub) {
        if (val[0].empty()) {
          continue;
        }

        EXPECT_EQ(val[2], msg.getQueryParam(val[0]));
      }

    } while (next_permutation(sub.begin(), sub.end()));
  }
}
Exemplo n.º 10
0
TEST(HTTPMessage, TestParseQueryParamsSimple) {
  HTTPMessage msg;
  string url = "/test?seq=123456&userid=1256679245&dup=1&dup=2&helloWorld"
               "&second=was+it+clear+%28already%29%3F";

  msg.setURL(url);
  EXPECT_EQ(msg.getQueryParam("seq"), "123456");
  EXPECT_EQ(msg.getQueryParam("userid"), "1256679245");
  EXPECT_EQ(msg.getQueryParam("dup"), "2");
  EXPECT_EQ(msg.getQueryParam("helloWorld"), "");
  EXPECT_EQ(msg.getIntQueryParam("dup", 5), 2);
  EXPECT_EQ(msg.getIntQueryParam("abc", 5), 5);
  EXPECT_EQ(msg.getDecodedQueryParam("second"), "was it clear (already)?");
  EXPECT_EQ(msg.getDecodedQueryParam("seq"), "123456");
  EXPECT_EQ(msg.hasQueryParam("seq"), true);
  EXPECT_EQ(msg.hasQueryParam("seq1"), false);
  EXPECT_EQ(msg.getIntQueryParam("dup"), 2);
  EXPECT_ANY_THROW(msg.getIntQueryParam("abc"));
  EXPECT_ANY_THROW(msg.getIntQueryParam("second"));
}
Exemplo n.º 11
0
TEST(SPDYCodecTest, ServerPush) {
  FakeHTTPCodecCallback callbacks;
  SPDYCodec egressCodec(TransportDirection::DOWNSTREAM,
                        SPDYVersion::SPDY3);
  SPDYCodec ingressCodec(TransportDirection::UPSTREAM,
                         SPDYVersion::SPDY3);
  ingressCodec.setCallback(&callbacks);

  HTTPMessage push;
  push.getHeaders().set("HOST", "www.foo.com");
  push.setURL("https://www.foo.com/");
  auto syn = getSynStream(egressCodec, 2, push, 1);
  ingressCodec.onIngress(*syn);
  EXPECT_EQ(callbacks.messageBegin, 1);
  EXPECT_EQ(callbacks.headersComplete, 1);
  EXPECT_EQ(callbacks.messageComplete, 0);
  EXPECT_EQ(callbacks.streamErrors, 0);
  EXPECT_EQ(callbacks.sessionErrors, 0);
  EXPECT_EQ(callbacks.assocStreamId, 1);
}
Exemplo n.º 12
0
TEST_P(ConnectionHeaderTest, TestConnectionHeaders) {
  HTTP1xCodec upstream(TransportDirection::UPSTREAM);
  HTTP1xCodec downstream(TransportDirection::DOWNSTREAM);
  HTTP1xCodecCallback callbacks;
  downstream.setCallback(&callbacks);
  HTTPMessage req;
  req.setMethod(HTTPMethod::GET);
  req.setURL("/");
  auto val = GetParam();
  for (auto header: val.first) {
    req.getHeaders().add(HTTP_HEADER_CONNECTION, header);
  }
  folly::IOBufQueue writeBuf(folly::IOBufQueue::cacheChainLength());
  upstream.generateHeader(writeBuf, upstream.createStream(), req);
  downstream.onIngress(*writeBuf.front());
  EXPECT_EQ(callbacks.headersComplete, 1);
  auto& headers = callbacks.msg_->getHeaders();
  EXPECT_EQ(headers.getSingleOrEmpty(HTTP_HEADER_CONNECTION),
            val.second);
}
Exemplo n.º 13
0
TEST(HTTP1xCodecTest, Test09Resp) {
  HTTP1xCodec codec(TransportDirection::UPSTREAM);
  HTTP1xCodecCallback callbacks;
  HTTPMessage req;
  auto id = codec.createStream();
  req.setHTTPVersion(0, 9);
  req.setMethod(HTTPMethod::GET);
  req.setURL("/");
  codec.setCallback(&callbacks);
  folly::IOBufQueue buf;
  codec.generateHeader(buf, id, req, 0, true);
  auto buffer = folly::IOBuf::copyBuffer(
    string("iamtheverymodelofamodernmajorgeneral"));
  codec.onIngress(*buffer);
  EXPECT_EQ(callbacks.headersComplete, 1);
  EXPECT_EQ(callbacks.bodyLen, buffer->computeChainDataLength());
  EXPECT_EQ(callbacks.messageComplete, 0);
  codec.onIngressEOF();
  EXPECT_EQ(callbacks.messageComplete, 1);
}
Exemplo n.º 14
0
TEST(SPDYCodecTest, HeaderWithFin) {
  FakeHTTPCodecCallback callbacks;
  SPDYCodec egressCodec(TransportDirection::UPSTREAM,
                        SPDYVersion::SPDY3);
  SPDYCodec ingressCodec(TransportDirection::DOWNSTREAM,
                         SPDYVersion::SPDY3);
  ingressCodec.setCallback(&callbacks);

  HTTPMessage req;
  req.setMethod("GET");
  req.getHeaders().set("HOST", "www.foo.com");
  req.setURL("https://www.foo.com/");
  auto syn = getSynStream(egressCodec, 1, req, 0, true /* eom */);
  ingressCodec.onIngress(*syn);
  EXPECT_EQ(callbacks.messageBegin, 1);
  EXPECT_EQ(callbacks.headersComplete, 1);
  EXPECT_EQ(callbacks.messageComplete, 1);
  EXPECT_EQ(callbacks.streamErrors, 0);
  EXPECT_EQ(callbacks.sessionErrors, 0);
  EXPECT_EQ(callbacks.assocStreamId, 0);
}
Exemplo n.º 15
0
TEST(HTTP1xCodecTest, TestChunkedUpstream) {
  HTTP1xCodec codec(TransportDirection::UPSTREAM);

  auto txnID = codec.createStream();

  HTTPMessage msg;
  msg.setHTTPVersion(1, 1);
  msg.setURL("https://www.facebook.com/");
  msg.getHeaders().set(HTTP_HEADER_HOST, "www.facebook.com");
  msg.getHeaders().set(HTTP_HEADER_TRANSFER_ENCODING, "chunked");
  msg.setIsChunked(true);

  HTTPHeaderSize size;

  folly::IOBufQueue buf(folly::IOBufQueue::cacheChainLength());
  codec.generateHeader(buf, txnID, msg, 0, false, &size);
  auto headerFromBuf = buf.split(buf.chainLength());

  string req1("Hello");
  auto body1 = folly::IOBuf::copyBuffer(req1);

  string req2("World");
  auto body2 = folly::IOBuf::copyBuffer(req2);

  codec.generateBody(buf, txnID, std::move(body1), HTTPCodec::NoPadding,
                     false);

  auto bodyFromBuf = buf.split(buf.chainLength());
  ASSERT_EQ("5\r\nHello\r\n", bodyFromBuf->moveToFbString());

  codec.generateBody(buf, txnID, std::move(body2), HTTPCodec::NoPadding,
                     true);
  LOG(WARNING) << "len chain" << buf.chainLength();

  auto eomFromBuf = buf.split(buf.chainLength());
  ASSERT_EQ("5\r\nWorld\r\n0\r\n\r\n", eomFromBuf->moveToFbString());
}