libravatarserv/src/http.cpp

136 lines
3.7 KiB
C++
Raw Permalink Normal View History

/* This file is part of libravatarserv.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include "libravatarserv.hpp"
using std::cout;
using std::cerr;
using std::endl;
using namespace http;
const Request http::parse_request(const string &request)
{
2018-11-28 17:29:08 +01:00
if (request.substr(0, 8) == "/favicon")
{
cout << "Status: 404 Not Found\n\n";
std::exit(1);
2018-11-28 17:29:08 +01:00
}
if (request.substr(0, 8) != "/avatar/" ||
request.find("..", 8) != std::string::npos)
{
cout << "Status: 400 Bad Request\n\n";
cerr << "Error: Invalid URL.\n";
std::exit(1);
}
uint16_t size = 80;
string fallback;
string digest = request.substr(8);
std::transform(digest.begin(), digest.end(), digest.begin(), ::tolower);
std::size_t pos_digest = digest.find('?');
if (pos_digest != std::string::npos)
{
2018-11-26 04:17:34 +01:00
string answer;
{
answer = get_parameter(request, "s");
2018-11-26 04:17:34 +01:00
if (!answer.empty())
{
2018-11-26 05:29:39 +01:00
try
{
size = static_cast<uint16_t>(std::stoul(answer));
} catch (const std::exception &) {}
2018-11-26 04:17:34 +01:00
}
else
{
answer = get_parameter(request, "size");
if (!answer.empty())
{
2018-11-26 05:29:39 +01:00
try
{
size = static_cast<uint16_t>(std::stoul(answer));
} catch (const std::exception &) {}
}
}
if (size > 512)
{
size = 512;
}
2018-11-29 13:43:56 +01:00
if (size == 0)
{
2018-11-29 13:43:56 +01:00
size = 80;
}
}
2018-11-26 04:20:27 +01:00
{
answer = get_parameter(request, "d");
if (!answer.empty())
{
fallback = answer;
}
else
{
answer = get_parameter(request, "default");
if (!answer.empty())
{
fallback = answer;
}
}
2018-11-26 04:20:27 +01:00
}
}
digest = digest.substr(0, pos_digest);
pos_digest = digest.find('.');
if (pos_digest != std::string::npos)
{
digest = digest.substr(0, pos_digest);
}
return { digest, size, fallback };
}
2018-11-26 04:17:34 +01:00
const string http::get_parameter(const string &request, const string &parameter)
{
std::size_t pos = request.find(parameter + "=");
if (pos != std::string::npos)
{
pos += (1 + parameter.length());
2018-11-26 04:17:34 +01:00
return request.substr(pos, request.find('&', pos));
}
return "";
}
void http::send_redirect(const Request &request)
{
const char *env = std::getenv("HTTPS");
string baseurl;
if (env != nullptr && env[1] == 'n')
{ // "on"
baseurl = "https://seccdn.libravatar.org";
}
else
{
baseurl = "http://cdn.libravatar.org";
}
cout << "Status: 307 Temporary Redirect\n";
cout << "Location: " << baseurl << "/avatar/"
<< request.digest << "?s=" << request.size
<< "&d=" << request.fallback << endl << endl;
}