2 * Copyright (C) 2011-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #include "HttpResponse.h"
26 #define SEPARATOR ": "
27 #define LINEBREAK "\r\n"
29 #define HEADER_CONTENT_LENGTH "Content-Length"
31 std::map<HTTP::StatusCode, std::string> CHttpResponse::m_statusCodeText = CHttpResponse::createStatusCodes();
33 CHttpResponse::CHttpResponse(HTTP::Method method, HTTP::StatusCode status, HTTP::Version version /* = HTTPVersion1_1 */)
43 void CHttpResponse::AddHeader(const std::string &field, const std::string &value)
48 m_headers.push_back(std::pair<std::string, std::string>(field, value));
51 void CHttpResponse::SetContent(const char* data, unsigned int length)
55 if (m_content == NULL)
58 m_contentLength = length;
61 unsigned int CHttpResponse::Create(char *&response)
65 m_buffer.append("HTTP/");
68 case HTTP::Version1_0:
69 m_buffer.append("1.0");
72 case HTTP::Version1_1:
73 m_buffer.append("1.1");
81 sprintf(statusBuffer, "%d", (int)m_status);
82 m_buffer.append(SPACE);
83 m_buffer.append(statusBuffer);
85 m_buffer.append(SPACE);
86 m_buffer.append(m_statusCodeText.find(m_status)->second);
87 m_buffer.append(LINEBREAK);
89 bool hasContentLengthHeader = false;
90 for (unsigned int index = 0; index < m_headers.size(); index++)
92 m_buffer.append(m_headers[index].first);
93 m_buffer.append(SEPARATOR);
94 m_buffer.append(m_headers[index].second);
95 m_buffer.append(LINEBREAK);
97 if (m_headers[index].first.compare(HEADER_CONTENT_LENGTH) == 0)
98 hasContentLengthHeader = true;
101 if (!hasContentLengthHeader && m_content != NULL && m_contentLength > 0)
103 m_buffer.append(HEADER_CONTENT_LENGTH);
104 m_buffer.append(SEPARATOR);
105 char lengthBuffer[11];
106 sprintf(lengthBuffer, "%u", m_contentLength);
107 m_buffer.append(lengthBuffer);
108 m_buffer.append(LINEBREAK);
111 m_buffer.append(LINEBREAK);
112 if (m_content != NULL && m_contentLength > 0)
113 m_buffer.append(m_content, m_contentLength);
115 response = (char *)m_buffer.c_str();
116 return m_buffer.size();
119 std::map<HTTP::StatusCode, std::string> CHttpResponse::createStatusCodes()
121 std::map<HTTP::StatusCode, std::string> map;
122 map[HTTP::Continue] = "Continue";
123 map[HTTP::SwitchingProtocols] = "Switching Protocols";
124 map[HTTP::Processing] = "Processing";
125 map[HTTP::ConnectionTimedOut] = "Connection timed out";
126 map[HTTP::OK] = "OK";
127 map[HTTP::Created] = "Created";
128 map[HTTP::Accepted] = "Accepted";
129 map[HTTP::NonAuthoritativeInformation] = "Non-Authoritative Information";
130 map[HTTP::NoContent] = "No Content";
131 map[HTTP::ResetContent] = "Reset Content";
132 map[HTTP::PartialContent] = "Partial Content";
133 map[HTTP::MultiStatus] = "Multi-Status";
134 map[HTTP::MultipleChoices] = "Multiple Choices";
135 map[HTTP::MovedPermanently] = "Moved Permanently";
136 map[HTTP::Found] = "Found";
137 map[HTTP::SeeOther] = "See Other";
138 map[HTTP::NotModified] = "Not Modified";
139 map[HTTP::UseProxy] = "Use Proxy";
140 //map[HTTP::SwitchProxy] = "Switch Proxy";
141 map[HTTP::TemporaryRedirect] = "Temporary Redirect";
142 map[HTTP::BadRequest] = "Bad Request";
143 map[HTTP::Unauthorized] = "Unauthorized";
144 map[HTTP::PaymentRequired] = "Payment Required";
145 map[HTTP::Forbidden] = "Forbidden";
146 map[HTTP::NotFound] = "Not Found";
147 map[HTTP::MethodNotAllowed] = "Method Not Allowed";
148 map[HTTP::NotAcceptable] = "Not Acceptable";
149 map[HTTP::ProxyAuthenticationRequired] = "Proxy Authentication Required";
150 map[HTTP::RequestTimeout] = "Request Time-out";
151 map[HTTP::Conflict] = "Conflict";
152 map[HTTP::Gone] = "Gone";
153 map[HTTP::LengthRequired] = "Length Required";
154 map[HTTP::PreconditionFailed] = "Precondition Failed";
155 map[HTTP::RequestEntityTooLarge] = "Request Entity Too Large";
156 map[HTTP::RequestURITooLong] = "Request-URI Too Long";
157 map[HTTP::UnsupportedMediaType] = "Unsupported Media Type";
158 map[HTTP::RequestedRangeNotSatisfiable] = "Requested range not satisfiable";
159 map[HTTP::ExpectationFailed] = "Expectation Failed";
160 map[HTTP::ImATeapot] = "I'm a Teapot";
161 map[HTTP::TooManyConnections] = "There are too many connections from your internet address";
162 map[HTTP::UnprocessableEntity] = "Unprocessable Entity";
163 map[HTTP::Locked] = "Locked";
164 map[HTTP::FailedDependency] = "Failed Dependency";
165 map[HTTP::UnorderedCollection] = "UnorderedCollection";
166 map[HTTP::UpgradeRequired] = "Upgrade Required";
167 map[HTTP::InternalServerError] = "Internal Server Error";
168 map[HTTP::NotImplemented] = "Not Implemented";
169 map[HTTP::BadGateway] = "Bad Gateway";
170 map[HTTP::ServiceUnavailable] = "Service Unavailable";
171 map[HTTP::GatewayTimeout] = "Gateway Time-out";
172 map[HTTP::HTTPVersionNotSupported] = "HTTP Version not supported";
173 map[HTTP::VariantAlsoNegotiates] = "Variant Also Negotiates";
174 map[HTTP::InsufficientStorage] = "Insufficient Storage";
175 map[HTTP::BandwidthLimitExceeded] = "Bandwidth Limit Exceeded";
176 map[HTTP::NotExtended] = "Not Extended";