Put the request parsing into a dedicated file.

This commit is contained in:
tastytea 2018-11-26 04:07:43 +01:00
parent 76f45a0dd8
commit c0c31f5093
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
3 changed files with 73 additions and 32 deletions

57
src/http.cpp Normal file
View File

@ -0,0 +1,57 @@
/* 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 <cstdlib>
#include "libravatarserv.hpp"
using std::cout;
using std::cerr;
using global::avatar_dir;
using namespace http;
const Request http::parse_request(const string &request)
{
if (request.substr(0, 8) != "/avatar/" ||
request.find('/', 8) != std::string::npos)
{
cout << "Status: 404 Not Found\n\n";
cerr << "Error: Invalid URL.\n";
std::exit(0);
}
uint16_t size = 80;
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)
{
digest = digest.substr(0, pos_digest);
std::size_t pos_size = request.find("s=", pos_digest);
if (pos_size != std::string::npos)
{
size = static_cast<uint16_t>(std::stoul(request.substr(pos_size + 2)));
}
pos_size = request.find("size=", pos_digest);
if (pos_size != std::string::npos)
{
size = static_cast<uint16_t>(std::stoul(request.substr(pos_size + 5)));
}
}
return { digest, size };
}

View File

@ -33,14 +33,13 @@ fs::path global::avatar_dir = "";
int main()
{
const char *tmp = std::getenv("REQUEST_URI");
if (tmp == nullptr)
const char *request = std::getenv("REQUEST_URI");
if (request == nullptr)
{
cout << "Status: 404 Not Found\n\n";
cerr << "Error: ${REQUEST_URI} is empty.\n";
return 1;
}
const string request = tmp;
if (!find_avatar_dir())
{
@ -50,34 +49,9 @@ int main()
}
hash::fill_table();
if (request.substr(0, 8) != "/avatar/" ||
request.find('/', 8) != std::string::npos)
{
cout << "Status: 404 Not Found\n\n";
cerr << "Error: Invalid URL.\n";
return 1;
}
http::Request avatar = http::parse_request(request);
uint16_t size = 80;
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)
{
std::size_t pos_size = digest.find("s=", pos_digest);
if (pos_size != std::string::npos)
{
size = static_cast<uint16_t>(std::stoul(digest.substr(pos_size + 2)));
}
pos_size = digest.find("size=", pos_digest);
if (pos_size != std::string::npos)
{
size = static_cast<uint16_t>(std::stoul(digest.substr(pos_size + 5)));
}
digest = digest.substr(0, pos_digest);
}
image::Image answer = image::get(digest, size);
image::Image answer = image::get(avatar.digest, avatar.size);
if (answer.error == 0)
{
cout << "Content-type: image/png\n";
@ -85,7 +59,6 @@ int main()
cout << "Connection: close\n";
cout << "Server: libravatarserv/" << global::version << endl << endl;
cout.flush(); // We need to flush before we use /dev/stdout directly.
// answer.image.write("test.png");
answer.image.write("/dev/stdout");
}
else

View File

@ -43,6 +43,17 @@ namespace global
extern fs::path avatar_dir;
}
namespace http // http.cpp
{
struct Request
{
const string digest;
uint16_t size;
};
const Request parse_request(const string &request);
}
namespace hash // hash.cpp
{
extern std::map<const string, const string> table;
@ -52,7 +63,7 @@ namespace hash // hash.cpp
bool fill_table();
}
namespace image //image.cpp
namespace image // image.cpp
{
struct Image
{