Files
2019-06-04 00:03:37 +08:00

128 lines
3.2 KiB
C++

/*
* response.cpp
*
* Created on: May 16, 2019
* Author: cmy
*/
#include "response.h"
using namespace std;
namespace chttp {
constexpr char Headers::PlainText[];
constexpr char Headers::HtmlText[];
constexpr char Headers::CSSText[];
constexpr char Headers::JavascriptText[];
constexpr char Headers::GifImage[];
constexpr char Headers::PngImage[];
constexpr char Headers::JpegImage[];
constexpr char Headers::BmpImage[];
constexpr char Headers::WebpImage[];
constexpr char Headers::MidiAudio[];
constexpr char Headers::MpegAudio[];
constexpr char Headers::WebmAudio[];
constexpr char Headers::OggAudio[];
constexpr char Headers::WavAudio[];
constexpr char Headers::WebmVideo[];
constexpr char Headers::OggVideo[];
constexpr char Headers::XmlApplication[];
constexpr char Headers::PDFApplication[];
constexpr char HttpStatus::OK[];
constexpr char HttpStatus::BadRequest[];
constexpr char HttpStatus::Unauthorized[];
constexpr char HttpStatus::Forbidden[];
constexpr char HttpStatus::NotFound[];
constexpr char HttpStatus::Unavailable[];
constexpr char HttpVersionStr::Http1_0[];
constexpr char HttpVersionStr::Http1_1[];
constexpr char HttpVersionStr::Http2_0[];
string Response::NotFoundPage = "not_found.html";
Response::~Response() {
// TODO Auto-generated destructor stub
}
void Response::ServeHtml(const char* file_path) {
SendStatusLine(HttpVersionStr::Http1_1, HttpStatus::OK);
SetContentType(Headers::HtmlText);
SendHeader(header);
SendFile(clnt_sock, file_path);
CloseSocket(clnt_sock);
}
void Response::SendFile(Sock_type clnt_sock, const char* file_path, bool show_not_found) {
//#ifdef __linux__
FILE* file = fopen(file_path, "r");
if (file == NULL) {
if (show_not_found)
return NotFound();
else
return;
} else {
char buffer[buffer_size];
fgets(buffer, sizeof(buffer), file);
while (!feof(file)) {
WriteSocket(clnt_sock, buffer, strlen(buffer));
fgets(buffer, sizeof(buffer), file);
}
}
fclose(file);
//#endif
}
void Response::SendHeader(const Headers& headers) {
const auto content = headers.Content();
for (auto & header_pair : content) {
WriteSocket(clnt_sock, header_pair.first.c_str(), 0);
WriteSocket(clnt_sock, ": ", 2);
WriteSocket(clnt_sock, header_pair.second.c_str(), 0);
WriteSocket(clnt_sock, "\r\n", 0);
}
WriteSocket(clnt_sock, "\r\n", 0);
}
void Response::SendStatusLine(const char* http_version,
const char* http_status) {
WriteSocket(clnt_sock, http_version);
WriteSocket(clnt_sock, " ");
WriteSocket(clnt_sock, http_status);
WriteSocket(clnt_sock, "\r\n");
}
void Response::NotFound() {
SendStatusLine(HttpVersionStr::Http1_1, HttpStatus::NotFound);
SetContentType(Headers::HtmlText);
SendHeader(header);
SendFile(clnt_sock, NotFoundPage.c_str(), false);
}
void Response::WriteSocket(Sock_type sock, const char* buffer, size_t size,
int flags) {
int length = static_cast<int>(size);
if (size == 0)
length = static_cast<int>(strlen(buffer));
send(sock, buffer, length, flags);
#ifdef DEBUG
std::cout << "write to socket:";
for (size_t i = 0; i < length; ++i)
cout << buffer[i];
#endif // DEBUG
}
inline void Response::CloseSocket(Sock_type sock)
{
#ifdef __linux__
return close(sock);
#elif _MSC_VER
closesocket(sock);
return;
#endif
}
} /* namespace chttp */