pixwhile/routes/guess_extension.cpp

47 lines
1.6 KiB
C++

#include <FastHash.h>
#include "routes.h"
#include "../servehelper.h"
#include "../pixivclient.h"
#include "../hiredis_wrapper.h"
static inline std::optional<std::string> guess_extension(const std::string& path, PixivClient& pixiv_client);
void guess_extension_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client, Redis* redis) {
using namespace std::string_literals;
std::string path = req.matches.str(1);
std::string cache_key = "pixwhile:i.pximg.net:ext:"s + std::to_string(FastHash(path.data(), path.size(), 0));
std::optional<std::string> extension = redis
? redis->get(cache_key)
: std::nullopt;
if (!extension) {
extension = guess_extension(path, pixiv_client);
if (!extension) {
res.status = 500;
serve_error(req, res, config, "500: Internal Server Error", "Failed to guess file extension for https://i.pximg.net"s + path);
return;
}
if (redis) {
redis->set(std::move(cache_key), *extension, 24 * 60 * 60);
}
}
serve_redirect(req, res, config, proxy_image_url(req, config, "https://i.pximg.net" + path + '.' + *extension), true);
}
static inline std::optional<std::string> guess_extension(const std::string& path, PixivClient& pixiv_client) {
auto guess_extension = [&](const char* extension) {
return pixiv_client.i_pximg_url_valid(path + '.' + extension);
};
if (guess_extension("png")) {
return "png";
} else if (guess_extension("jpg")) {
return "jpg";
} else {
return std::nullopt;
}
}