1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
39 #include <anna/core/functions.hpp>
41 #include <anna/http/Header.hpp>
42 #include <anna/http/internal/Token.hpp>
47 const char* http::Header::st_names [http::Header::Type::End] = {
49 "Cache-Control", "Connection", "Date", "Pragma", "Trailer", "Transfer-Encoding", "Upgrade", "Via",
51 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Authorization", "Expect", "From",
52 "Host", "If-Match", "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Max-Forwards",
53 "Proxy-Authorization", "Range", "Referer", "TE", "User-Agent",
54 "Allow", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5",
55 "Content-Range", "Content-Type", "Expires", "Last-Modified",
56 "Accept-Ranges", "Age", "ETAG", "Location", "Proxy-Authenticate", "Retry-After", "Server", "Vary",
57 "WWW-Authenticate", "Unknown"
60 http::Header* http::Header::initialize(const Type::_v type)
61 throw(RuntimeException) {
62 if(type == Type::None || type >= Type::Unknown) {
63 string msg(asString());
65 msg += functions::asString((int) type);
66 msg += " | Invalid header initializer";
67 throw RuntimeException(msg, ANNA_FILE_LOCATION);
72 if(type >= Type::CacheControl && type <= Type::Warning)
73 a_category = Category::General;
74 else if(type >= Type::Accept && type <= Type::UserAgent)
75 a_category = Category::Request;
76 else if(type >= Type::Allow && type <= Type::LastModified)
77 a_category = Category::Entity;
78 else if(type >= Type::AcceptRanges && type <= Type::WWWAuthenticate)
79 a_category = Category::Response;
81 a_category = Category::Extension;
83 delete a_extensionName;
84 a_extensionName = NULL;
88 http::Header* http::Header::initialize(const string& name)
89 throw(RuntimeException) {
90 if(a_extensionName == NULL)
91 a_extensionName = new string(name);
93 *a_extensionName = name;
95 a_type = Type::Unknown;
96 a_category = Category::Extension;
100 const int http::Header::getIntegerValue() const
102 return atoi(a_value.c_str());
105 void http::Header::setValue(const http::Token* token)
110 a_value = token->getStringValue();
113 void http::Header::setValue(const int value)
115 a_value = anna::functions::asString(value);
118 http::Header& http::Header::operator = (const Header & other)
123 a_type = other.a_type;
124 a_value = other.a_value;
126 if(other.a_extensionName == NULL) {
127 delete a_extensionName;
128 a_extensionName = NULL;
130 if(a_extensionName == NULL)
131 a_extensionName = new string(*other.a_extensionName);
133 *a_extensionName = *other.a_extensionName;
139 int http::Header::compare(const char* str, const int flags) const
141 const char* p = a_value.c_str();
145 if(flags & Compare::LeftTrim) {
146 while(*p && *p == ' ')
150 if((flags & Compare::RightTrim) && *p != 0 && anna_strchr(p, ' ') != NULL) {
152 ww = dup = strdup(p);
153 p = const_cast <const char*>(dup);
154 ww += anna_strlen(ww) - 1;
156 while(ww >= dup && *ww == ' ')
162 result = (flags & Compare::NoCase) ? strcasecmp(p, str) : anna_strcmp(p, str);
170 std::string http::Header::asString() const
172 string result("http::Header { Type: ");
173 result += asLiteral(a_type);
175 if(a_extensionName != NULL) {
176 result += " | Name: ";
177 result += *a_extensionName;
180 result += " | Value: ";
187 return result += " }";
190 string http::Header::code() const
194 if(a_category == Category::Extension)
195 result = (a_extensionName == NULL) ? "None" : a_extensionName->c_str();
197 result = asLiteral(a_type);
199 if(a_value.length() > 0) {
207 http::Header::Type::_v http::Header::asType(const http::Token* token)
209 for(int i = Type::Begin; token != NULL && i != Type::End; i ++) {
210 if(token->match(st_names [i]) == true)
217 const char* http::Header::asLiteral(const http::Header::Type::_v type)
219 return (type < Type::End) ? st_names [type] : "Extension";