about summary refs log tree commit diff
path: root/server/src/routes.rs
blob: 0055b9250acf2db7fdf6fa94314f95415b7a9728 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use crate::database::{add_link_to_database_safely, get_link_from_database, PoolState};
use crate::messages::{ErrorResponse, ShortenRequest, ShortenResponse};
use crate::parsing::{get_hash_from_string, make_url};
use actix_files::NamedFile;
use actix_web::web::{Data, Json, Path};
use actix_web::{web, Responder};
use actix_web::{HttpRequest, HttpResponse};

pub async fn root(req: HttpRequest) -> impl Responder {
    NamedFile::open("./client/index.html")
        .unwrap()
        .into_response(&req)
        .unwrap()
}

pub async fn shorten(params: Json<ShortenRequest>, state: Data<PoolState>) -> HttpResponse {
    let user_url = match make_url(&params.url) {
        Ok(url) => url,
        Err(_) => {
            return HttpResponse::BadRequest().json(ErrorResponse::new(
                "The URL you entered does not follow the proper URL format.",
            ))
        }
    };

    let connection = state.get().expect("Could not get a connection from pool");

    // Generate the initial hash, this is almost always the same as the inserted hash, but not on collisions.
    let initial_hash = get_hash_from_string(&user_url);

    // Insert the URL
    let hash =
        match web::block(move || add_link_to_database_safely(initial_hash, &user_url, &connection))
            .await
        {
            Ok(hash) => hash,
            Err(e) => {
                error!("Error occurred on adding new link: {:?}", e);
                return HttpResponse::InternalServerError().finish();
            }
        };

    HttpResponse::Ok().json(ShortenResponse { hash })
}

pub async fn redirect(info: Path<String>, state: Data<PoolState>) -> impl Responder {
    let connection = state.get().expect("Could not get a connection from pool");
    let url_result = web::block(move || get_link_from_database(&info, &connection)).await;

    match url_result {
        Ok(found_url) => match found_url {
            Some(url) => HttpResponse::TemporaryRedirect()
                .header("Location", url)
                .finish(),
            None => HttpResponse::TemporaryRedirect()
                .header("Location", "/")
                .finish(),
        },
        Err(e) => {
            error!("Error when getting link: {:?}", e);
            HttpResponse::InternalServerError().finish()
        }
    }
}