From 2b9fafe440a8045717305e7db71abdc63f2cc19e Mon Sep 17 00:00:00 2001 From: SinTan1729 Date: Wed, 8 Jan 2025 20:09:24 +0530 Subject: [PATCH] new: Got the expand API path working It replies with info for a single shortlink. May be useful for applications using json interface. --- actix/src/database.rs | 10 ++++++---- actix/src/main.rs | 1 + actix/src/services.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- actix/src/utils.rs | 6 +++--- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/actix/src/database.rs b/actix/src/database.rs index ab0277a..09145f2 100644 --- a/actix/src/database.rs +++ b/actix/src/database.rs @@ -13,14 +13,16 @@ pub struct DBRow { } // Find a single URL -pub fn find_url(shortlink: &str, db: &Connection) -> Option { +pub fn find_url(shortlink: &str, db: &Connection) -> (Option, Option) { let mut statement = db - .prepare_cached("SELECT long_url FROM urls WHERE short_url = ?1") + .prepare_cached("SELECT long_url,hits FROM urls WHERE short_url = ?1") .expect("Error preparing SQL statement for find_url."); - statement + let longlink = statement .query_row([shortlink], |row| row.get("long_url")) - .ok() + .ok(); + let hits = statement.query_row([shortlink], |row| row.get("hits")).ok(); + (longlink, hits) } // Get all URLs in DB diff --git a/actix/src/main.rs b/actix/src/main.rs index 825ab4a..f9dd507 100644 --- a/actix/src/main.rs +++ b/actix/src/main.rs @@ -82,6 +82,7 @@ async fn main() -> Result<()> { .service(services::delete_link) .service(services::login) .service(services::logout) + .service(services::expand) .service(Files::new("/", "./resources/").index_file("index.html")) .default_service(actix_web::web::get().to(services::error404)) }) diff --git a/actix/src/services.rs b/actix/src/services.rs index a5c80db..4c99d81 100644 --- a/actix/src/services.rs +++ b/actix/src/services.rs @@ -31,7 +31,7 @@ struct Response { reason: String, } -// Needs to return the short URL to make it easier for programs leveraging the API +// Needed to return the short URL to make it easier for programs leveraging the API #[derive(Serialize)] struct CreatedURL { success: bool, @@ -39,6 +39,15 @@ struct CreatedURL { shorturl: String, } +// Struct for returning information about a shortlink +#[derive(Serialize)] +struct LinkInfo { + success: bool, + error: bool, + longurl: String, + hits: i64, +} + // Define the routes // Add new links @@ -123,6 +132,35 @@ pub async fn getall( } } +// Get information about a single shortlink +#[post("/api/expand")] +pub async fn expand(req: String, data: web::Data, http: HttpRequest) -> HttpResponse { + let result = utils::is_api_ok(http); + if result.success { + let linkinfo = utils::get_longurl(req, &data.db); + if let Some(longlink) = linkinfo.0 { + let body = LinkInfo { + success: true, + error: false, + longurl: longlink, + hits: linkinfo + .1 + .expect("Error getting hit count for existing shortlink."), + }; + HttpResponse::Ok().json(body) + } else { + let body = Response { + success: false, + error: true, + reason: "The shortlink does not exist on the server.".to_string(), + }; + HttpResponse::Unauthorized().json(body) + } + } else { + HttpResponse::Unauthorized().json(result) + } +} + // Get the site URL #[get("/api/siteurl")] pub async fn siteurl() -> HttpResponse { @@ -154,7 +192,7 @@ pub async fn link_handler( data: web::Data, ) -> impl Responder { let shortlink_str = shortlink.to_string(); - if let Some(longlink) = utils::get_longurl(shortlink_str, &data.db) { + if let Some(longlink) = utils::get_longurl(shortlink_str, &data.db).0 { let redirect_method = env::var("redirect_method").unwrap_or(String::from("PERMANENT")); database::add_hit(shortlink.as_str(), &data.db); if redirect_method == "TEMPORARY" { diff --git a/actix/src/utils.rs b/actix/src/utils.rs index c548907..2534b3f 100644 --- a/actix/src/utils.rs +++ b/actix/src/utils.rs @@ -80,11 +80,11 @@ pub fn is_api_ok(http: HttpRequest) -> Response { } // Request the DB for searching an URL -pub fn get_longurl(shortlink: String, db: &Connection) -> Option { +pub fn get_longurl(shortlink: String, db: &Connection) -> (Option, Option) { if validate_link(&shortlink) { database::find_url(shortlink.as_str(), db) } else { - None + (None, None) } } @@ -124,7 +124,7 @@ pub fn add_link(req: String, db: &Connection) -> (bool, String) { } if validate_link(chunks.shortlink.as_str()) - && get_longurl(chunks.shortlink.clone(), db).is_none() + && get_longurl(chunks.shortlink.clone(), db).0.is_none() { ( database::add_link(chunks.shortlink.clone(), chunks.longlink, db),