OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 #include "net/http/http_request_headers.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/string_util.h" | |
9 #include "net/http/http_util.h" | |
10 | |
11 namespace net { | |
12 | |
13 const char HttpRequestHeaders::kGetMethod[] = "GET"; | |
14 | |
15 const char HttpRequestHeaders::kCacheControl[] = "Cache-Control"; | |
16 const char HttpRequestHeaders::kConnection[] = "Connection"; | |
17 const char HttpRequestHeaders::kContentLength[] = "Content-Length"; | |
18 const char HttpRequestHeaders::kHost[] = "Host"; | |
19 const char HttpRequestHeaders::kPragma[] = "Pragma"; | |
20 const char HttpRequestHeaders::kProxyConnection[] = "Proxy-Connection"; | |
21 const char HttpRequestHeaders::kReferer[] = "Referer"; | |
22 const char HttpRequestHeaders::kUserAgent[] = "User-Agent"; | |
23 | |
24 HttpRequestHeaders::HttpRequestHeaders() {} | |
25 HttpRequestHeaders::~HttpRequestHeaders() {} | |
26 | |
27 void HttpRequestHeaders::SetRequestLine(const base::StringPiece& method, | |
28 const base::StringPiece& path, | |
29 const base::StringPiece& version) { | |
30 DCHECK(!method.empty()); | |
31 DCHECK(!path.empty()); | |
32 DCHECK(!version.empty()); | |
33 | |
34 method_.assign(method.data(), method.length()); | |
35 path_.assign(path.data(), path.length()); | |
36 version_.assign(version.data(), version.length()); | |
37 } | |
38 | |
39 void HttpRequestHeaders::SetHeader(const base::StringPiece& key, | |
40 const base::StringPiece& value) { | |
41 HeaderVector::iterator it = FindHeader(key); | |
42 if (it != headers_.end()) | |
43 it->value = value.as_string(); | |
44 else | |
45 headers_.push_back(HeaderKeyValuePair(key.as_string(), value.as_string())); | |
46 } | |
47 | |
48 void HttpRequestHeaders::RemoveHeader(const base::StringPiece& key) { | |
49 HeaderVector::iterator it = FindHeader(key); | |
50 if (it != headers_.end()) | |
51 headers_.erase(it); | |
52 } | |
53 | |
54 void HttpRequestHeaders::AddHeaderFromString( | |
55 const base::StringPiece& header_line) { | |
56 DCHECK_EQ(std::string::npos, header_line.find("\r\n")) | |
57 << "\"" << header_line << "\" contains CRLF."; | |
58 | |
59 const std::string::size_type key_end_index = header_line.find(":"); | |
60 if (key_end_index == std::string::npos) { | |
61 LOG(DFATAL) << "\"" << header_line << "\" is missing colon delimiter."; | |
62 return; | |
63 } | |
64 | |
65 if (key_end_index == 0) { | |
66 LOG(DFATAL) << "\"" << header_line << "\" is missing header key."; | |
67 return; | |
68 } | |
69 | |
70 const base::StringPiece header_key(header_line.data(), key_end_index); | |
71 | |
72 const std::string::size_type value_index = key_end_index + 1; | |
73 | |
74 if (value_index < header_line.size()) { | |
75 std::string header_value(header_line.data() + value_index, | |
76 header_line.size() - value_index); | |
77 std::string::const_iterator header_value_begin = | |
78 header_value.begin(); | |
79 std::string::const_iterator header_value_end = | |
80 header_value.end(); | |
81 HttpUtil::TrimLWS(&header_value_begin, &header_value_end); | |
82 SetHeader(header_key, | |
83 base::StringPiece(&*header_value_begin, | |
84 header_value_end - header_value_begin)); | |
85 } else if (value_index == header_line.size()) { | |
86 SetHeader(header_key, ""); | |
87 } else { | |
88 NOTREACHED(); | |
89 } | |
90 } | |
91 | |
92 void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) { | |
93 DCHECK(other.method_.empty()); | |
94 DCHECK(other.path_.empty()); | |
95 DCHECK(other.version_.empty()); | |
96 | |
97 for (HeaderVector::const_iterator it = other.headers_.begin(); | |
98 it != other.headers_.end(); ++it ) { | |
99 SetHeader(it->key, it->value); | |
100 } | |
101 } | |
102 | |
103 std::string HttpRequestHeaders::ToString() const { | |
104 std::string output; | |
105 if (!method_.empty()) { | |
106 DCHECK(!path_.empty()); | |
107 DCHECK(!version_.empty()); | |
108 output = StringPrintf( | |
109 "%s %s HTTP/%s\r\n", method_.c_str(), path_.c_str(), version_.c_str()); | |
110 } | |
111 for (HeaderVector::const_iterator it = headers_.begin(); | |
112 it != headers_.end(); ++it) { | |
113 if (!it->value.empty()) | |
114 StringAppendF(&output, "%s: %s\r\n", it->key.c_str(), it->value.c_str()); | |
115 else | |
116 StringAppendF(&output, "%s:\r\n", it->key.c_str()); | |
117 } | |
118 output.append("\r\n"); | |
119 return output; | |
120 } | |
121 | |
122 HttpRequestHeaders::HeaderVector::iterator | |
123 HttpRequestHeaders::FindHeader(const base::StringPiece& key) { | |
124 for (HeaderVector::iterator it = headers_.begin(); | |
125 it != headers_.end(); ++it) { | |
126 if (key.length() == it->key.length() && | |
127 !base::strncasecmp(key.data(), it->key.data(), key.length())) | |
128 return it; | |
129 } | |
130 | |
131 return headers_.end(); | |
132 } | |
133 | |
134 } // namespace net | |
OLD | NEW |