Browse Source

implement response parser features, add request struct

CPP-GTK4
yggverse 2 months ago
parent
commit
a478e31bd5
  1. 113
      src/app/browser/main/tab/page.cpp
  2. 45
      src/app/browser/main/tab/page.hpp

113
src/app/browser/main/tab/page.cpp

@ -323,7 +323,7 @@ void Page::navigation_reload(
if (Socket::Connection::is_active(socket__connection)) // @TODO if (Socket::Connection::is_active(socket__connection)) // @TODO
{ {
// Build gemini protocol request // Build gemini protocol request
const auto REQUEST = Socket::Client::Gemini::get_request_from_uri( const auto REQUEST = Socket::Client::Gemini::Request::create_from_uri(
uri uri
); );
@ -370,20 +370,41 @@ void Page::navigation_reload(
action__update->activate(); action__update->activate();
// Parse meta // Parse meta
auto meta = Glib::Regex::split_simple( Socket::Client::Gemini::Response::Status status;
R"regex(^(\d+)?\s([\w]+\/[\w]+)?)regex",
buffer Socket::Client::Gemini::Response::Match::meta(
buffer,
status,
mime
); );
// Route by status code // Try detect mime by file extension on still undefined @TODO
if (meta[1] == "20") if (mime == MIME::UNDEFINED)
{ {
// Route by mime type or path extension if (Glib::str_has_suffix(g_uri_get_path(uri), ".gmi"))
if (meta[2] == "text/gemini" || Glib::str_has_suffix(g_uri_get_path(uri), ".gmi"))
{ {
// Update
mime = MIME::TEXT_GEMINI; mime = MIME::TEXT_GEMINI;
}
else
{
// Update
title = _("Oops");
description = _("MIME type not supported");
progress_fraction = 1;
action__update->activate();
}
}
// Route by status code
switch (status)
{
case Socket::Client::Gemini::Response::Status::SUCCESS:
// Update
title = _("Done"); // @TODO page title title = _("Done"); // @TODO page title
description = g_uri_get_host( description = g_uri_get_host(
@ -406,36 +427,24 @@ void Page::navigation_reload(
} }
action__update->activate(); action__update->activate();
}
else break;
{
// @TODO other statuses..
default:
// Update // Update
title = _("Oops"); title = _("Oops");
description = _("MIME type not supported"); description = _("Response code not supported");
progress_fraction = 1; progress_fraction = 1;
action__update->activate(); action__update->activate();
}
}
else
{
// Update
title = _("Oops");
description = Glib::ustring::sprintf(
_("Response code %s not supported"),
meta[1]
);
progress_fraction = 1;
action__update->activate();
} }
// Finalize request
Socket::Connection::close( Socket::Connection::close(
socket__connection socket__connection
); );
@ -672,7 +681,7 @@ Glib::RefPtr<Gio::SocketClient> Page::Socket::Client::Gemini::create()
/* /*
* Build request string for Gemini protocol from GUri pointer * Build request string for Gemini protocol from GUri pointer
*/ */
Glib::ustring Page::Socket::Client::Gemini::get_request_from_uri( Glib::ustring Page::Socket::Client::Gemini::Request::create_from_uri(
GUri * uri GUri * uri
) { ) {
return Glib::ustring::sprintf( return Glib::ustring::sprintf(
@ -683,6 +692,50 @@ Glib::ustring Page::Socket::Client::Gemini::get_request_from_uri(
); );
} }
/*
* Parse meta data from response buffer
*/
bool Page::Socket::Client::Gemini::Response::Match::meta(
const Glib::ustring & RESPONSE,
Status & status,
MIME & mime
) {
// Parse response string
const auto MATCH = Glib::Regex::split_simple(
R"regex(^(\d+)?\s([\w]+\/[\w]+)?)regex",
RESPONSE
);
// Detect status code @TODO
if (MATCH[1] == "20")
{
status = Status::SUCCESS;
}
else
{
status = Status::UNDEFINED;
}
// Detect MIME @TODO
if (MATCH[2] == "text/gemini")
{
mime = MIME::TEXT_GEMINI;
}
else if (MATCH[2] == "text/plain")
{
mime = MIME::TEXT_PLAIN;
}
else
{
mime = MIME::UNDEFINED;
}
return true; // @TODO
}
/* /*
* Check socket connection active according to page class implementation * Check socket connection active according to page class implementation
*/ */

45
src/app/browser/main/tab/page.hpp

@ -96,13 +96,52 @@ namespace app::browser::main::tab
struct Gemini struct Gemini
{ {
// Defaults
static const int DEFAULT_PORT = 1965; static const int DEFAULT_PORT = 1965;
// Actions
static Glib::RefPtr<Gio::SocketClient> create(); static Glib::RefPtr<Gio::SocketClient> create();
static Glib::ustring get_request_from_uri( struct Request
GUri * uri {
); static Glib::ustring create_from_uri(
GUri * uri
);
};
struct Response
{
/*
* Status codes
*
* 10-19 Input expected
* 20-29 Success
* 30-39 Redirection
* 40-49 Temporary failure
* 50-59 Permanent failure
* 60-69 Client certificates
*
* https://geminiprotocol.net/docs/protocol-specification.gmi#status-codes
*/
enum class Status
{
SUCCESS,
REDIRECT,
TEMPORARY_FAILURE,
PERMANENT_FAILURE,
CERTIFICATE,
UNDEFINED
}; // @TODO explain code groups
struct Match
{
static bool meta(
const Glib::ustring & RESPONSE,
Status & status,
MIME & mime
);
};
};
}; };
}; };

Loading…
Cancel
Save