1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_TOOLS_QUIC_TEST_TOOLS_TEST_TOOLS_HTTP_MESSAGE_H_
6#define NET_TOOLS_QUIC_TEST_TOOLS_TEST_TOOLS_HTTP_MESSAGE_H_
7
8#include <string>
9#include <vector>
10
11#include "base/strings/string_piece.h"
12#include "net/tools/balsa/balsa_enums.h"
13#include "net/tools/balsa/balsa_headers.h"
14
15namespace net {
16namespace tools {
17namespace test {
18
19class HttpConstants {
20 public:
21  enum Version {
22    HTTP_UNKNOWN = 0,
23    HTTP_0_9,
24    HTTP_1_0,
25    HTTP_1_1
26  };
27
28  enum Method {
29    UNKNOWN_METHOD = 0,
30    OPTIONS,
31    GET,
32    HEAD,
33    POST,
34    PUT,
35    DELETE,
36    TRACE,
37    CONNECT,
38
39    MKCOL,
40    UNLOCK,
41  };
42};
43
44// Stripped down wrapper class which basically contains headers and a body.
45class HTTPMessage {
46 public:
47  typedef HttpConstants::Version Version;
48  typedef HttpConstants::Method Method;
49
50  // Convenient functions to map strings into enums. The string passed in is
51  // not assumed to be NULL-terminated.
52  static Version StringToVersion(base::StringPiece str);
53  static Method StringToMethod(base::StringPiece str);
54
55  static const char* MethodToString(Method method);
56  static const char* VersionToString(Version version);
57
58  // Default constructor makes an empty HTTP/1.1 GET request. This is typically
59  // used to construct a message that will be Initialize()-ed.
60  HTTPMessage();
61
62  // Build a request message
63  HTTPMessage(Version version, Method request, const std::string& path);
64
65  virtual ~HTTPMessage();
66
67  const std::string& body() const { return body_; }
68
69  // Adds a header line to the message.
70  void AddHeader(const std::string& header, const std::string& value);
71
72  // Removes a header line from the message.
73  void RemoveHeader(const std::string& header);
74
75  // A utility function which calls RemoveHeader followed by AddHeader.
76  void ReplaceHeader(const std::string& header, const std::string& value);
77
78  // Adds a body and the optional content-length header field (omitted to test
79  // read until close test case). To generate a message that has a header field
80  // of 0 content-length, call AddBody("", true).
81  // Multiple calls to AddBody()/AddChunkedBody() has the effect of overwriting
82  // the previous entry without warning.
83  void AddBody(const std::string& body, bool add_content_length);
84
85  bool has_complete_message() const { return has_complete_message_; }
86  void set_has_complete_message(bool value) { has_complete_message_ = value; }
87
88  // Do some basic http message consistency checks like:
89  // - Valid transfer-encoding header
90  // - Valid content-length header
91  // - Messages we expect to be complete are complete.
92  // This check can be disabled by setting skip_message_validation.
93  void ValidateMessage() const;
94
95  bool skip_message_validation() const { return skip_message_validation_; }
96  void set_skip_message_validation(bool value) {
97    skip_message_validation_ = value;
98  }
99
100  // Allow direct access to the body string.  This should be used with caution:
101  // it will not update the request headers like AddBody and AddChunkedBody do.
102  void set_body(const std::string& body) { body_ = body; }
103
104  const BalsaHeaders* headers() const { return &headers_; }
105  BalsaHeaders* headers() { return &headers_; }
106
107 protected:
108  BalsaHeaders headers_;
109
110  std::string body_;  // the body with chunked framing/gzip compression
111
112  bool is_request_;
113
114  // True if the message should be considered complete during serialization.
115  // Used by SPDY and Streamed RPC clients to decide wherever or not
116  // to include fin flags and during message validation (if enabled).
117  bool has_complete_message_;
118
119  // Allows disabling message validation when creating test messages
120  // that are intentionally invalid.
121  bool skip_message_validation_;
122
123 private:
124  void InitializeFields();
125
126  DISALLOW_COPY_AND_ASSIGN(HTTPMessage);
127};
128
129}  // namespace test
130}  // namespace tools
131}  // namespace net
132
133#endif  // NET_TOOLS_QUIC_TEST_TOOLS_TEST_TOOLS_HTTP_MESSAGE_H_
134