Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL shortener #820

Merged
merged 2 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions lib/device/sio/fuji.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "fujiCmd.h"
#include "httpService.h"
#ifdef BUILD_ATARI

#include "fuji.h"
Expand Down Expand Up @@ -2212,14 +2213,21 @@ void sioFuji::sio_qrcode_encode()

uint16_t aux = sio_get_aux();
qrManager.version = aux;
qrManager.ecc_mode = aux >> 8;
qrManager.ecc_mode = (aux >> 8) & 0b00000011;
bool shorten = (aux >> 12) & 0b00000001;

Debug_printf("FUJI: QRCODE ENCODE\n");
Debug_printf("QR Version: %d, ECC: %d\n", qrManager.version, qrManager.ecc_mode);
Debug_printf("QR Version: %d, ECC: %d, Shorten: %s\n", qrManager.version, qrManager.ecc_mode, shorten ? "Y" : "N");

std::string url = qrManager.in_buf;

if (shorten) {
url = fnHTTPD.shorten_url(url);
}

std::vector<uint8_t> p = QRManager::encode(
qrManager.in_buf.c_str(),
qrManager.in_buf.size(),
url.c_str(),
url.size(),
qrManager.version,
qrManager.ecc_mode,
&out_len
Expand Down
46 changes: 46 additions & 0 deletions lib/http/httpService.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

#include "fnHttpClient.h"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"

#include "httpService.h"
Expand Down Expand Up @@ -1183,6 +1184,44 @@ esp_err_t fnHttpService::get_handler_slot(httpd_req_t *req)
return ESP_OK;
}

std::string fnHttpService::shorten_url(std::string url)
{
int id = shortURLs.size();
shortURLs.push_back(url);

// Ideally would use hostname, but it doesn't include .local needed for mDNS devices
std::string shortened = "http://" + fnSystem.Net.get_ip4_address_str() + "/url/" + std::to_string(id);
Debug_printf("Short URL /url/%d registered for URL: %s\n", id, url.c_str());
return shortened;
}

esp_err_t fnHttpService::get_handler_shorturl(httpd_req_t *req)
{
// Strip the /url/ from the path
std::string id_str = std::string(req->uri).substr(5);
Debug_printf("Short URL handler: %s\n", id_str.c_str());

if (!std::all_of(id_str.begin(), id_str.end(), ::isdigit)) {
httpd_resp_set_status(req, "400 Bad Request");
httpd_resp_send(req, NULL, 0);
return ESP_FAIL;
}

int id = std::stoi(id_str);
if (id > fnHTTPD.shortURLs.size())
{
httpd_resp_set_status(req, "404 Not Found");
httpd_resp_send(req, NULL, 0);
}
else
{
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", fnHTTPD.shortURLs[id].c_str());
httpd_resp_send(req, NULL, 0);
}
return ESP_OK;
}

esp_err_t fnHttpService::post_handler_config(httpd_req_t *req)
{
#ifdef VERBOSE_HTTP
Expand Down Expand Up @@ -1441,6 +1480,13 @@ httpd_handle_t fnHttpService::start_server(serverstate &state)
.is_websocket = false,
.handle_ws_control_frames = false,
.supported_subprotocol = nullptr},
{.uri = "/url/*",
.method = HTTP_GET,
.handler = get_handler_shorturl,
.user_ctx = NULL,
.is_websocket = false,
.handle_ws_control_frames = false,
.supported_subprotocol = nullptr},
#ifdef BUILD_ADAM
{.uri = "/term",
.method = HTTP_GET,
Expand Down
15 changes: 10 additions & 5 deletions lib/http/httpService.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ If a file has an extention pre-determined to support parsing (see/update

* The entire file contents are loaded into an in-memory string.
* Anything with the pattern <%PARSE_TAG%> is replaced with an
* appropriate value as determined by the
* appropriate value as determined by the
* string substitute_tag(const string &tag)
* function.
*/
Expand All @@ -32,7 +32,6 @@ If a file has an extention pre-determined to support parsing (see/update
#include <map>
#include <string>


#include "fnFS.h"

#ifdef ESP_PLATFORM
Expand Down Expand Up @@ -60,7 +59,7 @@ If a file has an extention pre-determined to support parsing (see/update

#define PRINTER_BUSY_TIME 2000 // milliseconds to wait until printer is done

class fnHttpService
class fnHttpService
{
struct serverstate {
#ifdef ESP_PLATFORM
Expand All @@ -79,12 +78,14 @@ class fnHttpService
fnwserr_post_fail
};

std::vector<std::string> shortURLs;

#ifdef ESP_PLATFORM
struct queryparts {
std::string full_uri;
std::string path;
std::string query;
std::map<std::string, std::string> query_parsed;
std::map<std::string, std::string> query_parsed;
};

static void custom_global_ctx_free(void * ctx);
Expand Down Expand Up @@ -120,7 +121,7 @@ class fnHttpService

public:

std::string errMsg;
std::string errMsg;

std::string getErrMsg() { return errMsg; }
void clearErrMsg() { errMsg.clear(); }
Expand All @@ -138,6 +139,7 @@ class fnHttpService
static esp_err_t get_handler_eject(httpd_req_t *req);
static esp_err_t get_handler_dir(httpd_req_t *req);
static esp_err_t get_handler_slot(httpd_req_t *req);
static esp_err_t get_handler_shorturl(httpd_req_t *req);

#ifdef BUILD_ADAM
static esp_err_t get_handler_term(httpd_req_t *req);
Expand All @@ -156,11 +158,14 @@ class fnHttpService
static int post_handler_config(struct mg_connection *c, struct mg_http_message *hm);

static int get_handler_browse(mg_connection *c, mg_http_message *hm);
static int get_handler_shorturl(mg_connection *c, mg_http_message *hm);

void service();
// !ESP_PLATFORM
#endif

std::string shorten_url(std::string url);

void start();
void stop();
bool running(void) {
Expand Down
50 changes: 43 additions & 7 deletions lib/http/mgHttpService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
*/

#ifndef ESP_PLATFORM

#include <sstream>
#include <vector>
#include <map>


#include "fnSystem.h"
#include "fnConfig.h"
#include "fnWiFi.h"
Expand All @@ -17,6 +15,7 @@
#include "printer.h"
#include "fuji.h"

#include "mongoose.h"
#include "httpService.h"
#include "httpServiceConfigurator.h"
#include "httpServiceParser.h"
Expand Down Expand Up @@ -391,7 +390,7 @@ int fnHttpService::get_handler_browse(mg_connection *c, mg_http_message *hm)
{
mg_http_reply(c, 403, "", "Bad browse request\n");
}

return 0;
}

Expand All @@ -411,7 +410,7 @@ int fnHttpService::get_handler_mount(mg_connection *c, mg_http_message *hm)
{
// Mount all the things
Debug_printf("Mount all from webui\n");
#ifdef BUILD_ATARI
#ifdef BUILD_ATARI
theFuji.mount_all(false);
#else
theFuji.mount_all();
Expand All @@ -436,7 +435,7 @@ int fnHttpService::get_handler_eject(mg_connection *c, mg_http_message *hm)
else
{
#ifdef BUILD_APPLE
if(theFuji.get_disks(ds)->disk_dev.device_active) //set disk switched only if device was previosly mounted.
if(theFuji.get_disks(ds)->disk_dev.device_active) //set disk switched only if device was previosly mounted.
theFuji.get_disks(ds)->disk_dev.switched = true;
#endif
theFuji.get_disks(ds)->disk_dev.unmount();
Expand Down Expand Up @@ -484,6 +483,39 @@ int fnHttpService::get_handler_eject(mg_connection *c, mg_http_message *hm)
return 0;
}

std::string fnHttpService::shorten_url(std::string url)
{
int id = shortURLs.size();
shortURLs.push_back(url);

std::string shortened = "http://" + fnSystem.Net.get_hostname() + ":8000/url/" + std::to_string(id);
Debug_printf("Short URL /url/%d registered for URL: %s\n", id, url.c_str());
return shortened;
}

int fnHttpService::get_handler_shorturl(mg_connection *c, mg_http_message *hm)
{
// Strip the /url/ from the path
std::string id_str = std::string(hm->uri.ptr).substr(5, hm->uri.len-5);
Debug_printf("Short URL handler: %s\n", id_str.c_str());

if (!std::all_of(id_str.begin(), id_str.end(), ::isdigit)) {
mg_http_reply(c, 400, "", "Bad Request");
return 0;
}

int id = std::stoi(id_str);
if (id > fnHTTPD.shortURLs.size())
{
mg_http_reply(c, 404, "", "Not Found");
}
else
{
mg_printf(c, "HTTP/1.1 303 See Other\r\nLocation: %s\r\nContent-Length: 0\r\n\r\n", fnHTTPD.shortURLs[id].c_str());
}
return 0;
}

void fnHttpService::cb(struct mg_connection *c, int ev, void *ev_data)
{
static const char *s_root_dir = "data/www";
Expand Down Expand Up @@ -558,7 +590,7 @@ void fnHttpService::cb(struct mg_connection *c, int ev, void *ev_data)
// get "exit" query variable
char exit[10] = "";
mg_http_get_var(&hm->query, "exit", exit, sizeof(exit));
if (atoi(exit))
if (atoi(exit))
{
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 1); // send reply
fnSystem.reboot(500, false); // deferred exit with code 0
Expand All @@ -571,6 +603,10 @@ void fnHttpService::cb(struct mg_connection *c, int ev, void *ev_data)
fnSystem.reboot(500, true); // deferred exit with code 75 -> should be started again
}
}
else if (mg_http_match_uri(hm, "/url/*"))
{
get_handler_shorturl(c, hm);
}
else
// default handler, serve static content of www firectory
{
Expand Down Expand Up @@ -653,4 +689,4 @@ void fnHttpService::service()
mg_mgr_poll(state.hServer, 0);
}

#endif // !ESP_PLATFORM
#endif // !ESP_PLATFORM
Loading