switched framework to actix-web
This commit is contained in:
parent
89a9303321
commit
d2a7090033
File diff suppressed because it is too large
Load Diff
|
@ -6,9 +6,11 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = { version = "0.5.0-rc.1", features = ["json"], default-features = false }
|
# using beta due to this: https://github.com/actix/actix-web/issues/2155
|
||||||
|
actix-web = "4.0.0-beta.10"
|
||||||
|
actix-cors = "0.6.0-beta.3"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
reqwest = { version = "0.11", features = ["json", "rustls-tls", "cookies", "gzip"], default-features = false }
|
reqwest = { version = "0.11", features = ["json", "rustls-tls", "cookies", "gzip"], default-features = false }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
regex = "1"
|
env_logger = "0.9"
|
2
Procfile
2
Procfile
|
@ -1 +1 @@
|
||||||
web: ROCKET_ADDRESS=0.0.0.0 ROCKET_PORT=$PORT ROCKET_KEEP_ALIVE=0 ./target/release/dzmedia
|
web: ./target/release/dzmedia
|
95
src/main.rs
95
src/main.rs
|
@ -1,17 +1,14 @@
|
||||||
#[macro_use] extern crate rocket;
|
use actix_web::{App, HttpResponse, HttpServer, Responder, get, post, web, middleware, http::header};
|
||||||
|
use actix_cors::Cors;
|
||||||
use rocket::{serde::{Deserialize, json::Json}, State, http::Status};
|
|
||||||
use rocket::http::Header;
|
|
||||||
use rocket::{Request, Response};
|
|
||||||
use rocket::fairing::{Fairing, Info, Kind};
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use serde::Deserialize;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
use api::{APIClient, APIError, Format};
|
use api::{APIClient, APIError, Format};
|
||||||
|
|
||||||
struct StateData {
|
struct AppState {
|
||||||
client: APIClient
|
client: RwLock<APIClient>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -26,7 +23,7 @@ struct DeezerTrack {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn index() -> &'static str {
|
async fn index() -> &'static str {
|
||||||
"marecchione gay af"
|
"marecchione gay af"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,32 +33,27 @@ struct RequestParams {
|
||||||
ids: Vec<u32>,
|
ids: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/get_url", format = "json", data = "<req>")]
|
#[post("/get_url")]
|
||||||
async fn get_url(req: Json<RequestParams>, state_data: &State<RwLock<StateData>>) -> (Status, String) {
|
async fn get_url(req: web::Json<RequestParams>, data: web::Data<AppState>) -> impl Responder {
|
||||||
if req.formats.is_empty() {
|
if req.formats.is_empty() {
|
||||||
return (Status::BadRequest, "Format list cannot be empty".to_string());
|
return HttpResponse::BadRequest().body("Format list cannot be empty");
|
||||||
}
|
}
|
||||||
if req.ids.is_empty() {
|
if req.ids.is_empty() {
|
||||||
return (Status::BadRequest, "ID list cannot be empty".to_string());
|
return HttpResponse::BadRequest().body("ID list cannot be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut client: APIClient;
|
let mut client = data.client.read().unwrap().clone();
|
||||||
let old_license: String;
|
let old_license = client.license_token.clone();
|
||||||
{
|
|
||||||
let state_data_read = state_data.read().unwrap();
|
|
||||||
old_license = state_data_read.client.license_token.clone();
|
|
||||||
client = state_data_read.client.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
let resp: Result<DeezerTrackList, APIError> = client.api_call("song.getListData", &json!({"sng_ids":req.ids,"array_default":["SNG_ID","TRACK_TOKEN"]})).await;
|
let resp: Result<DeezerTrackList, APIError> = client.api_call("song.getListData", &json!({"sng_ids":req.ids,"array_default":["SNG_ID","TRACK_TOKEN"]})).await;
|
||||||
let track_list;
|
let track_list;
|
||||||
match resp {
|
match resp {
|
||||||
Ok(t) => track_list = t,
|
Ok(t) => track_list = t,
|
||||||
Err(e) => return (Status::InternalServerError, e.to_string()),
|
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if track_list.data.is_empty() {
|
if track_list.data.is_empty() {
|
||||||
return (Status::BadRequest, "No valid IDs found".to_string())
|
return HttpResponse::BadRequest().body("No valid IDs found");
|
||||||
}
|
}
|
||||||
|
|
||||||
let track_tokens: Vec<&str> = track_list.data.iter().map(|t| t.TRACK_TOKEN.as_str()).collect();
|
let track_tokens: Vec<&str> = track_list.data.iter().map(|t| t.TRACK_TOKEN.as_str()).collect();
|
||||||
|
@ -70,43 +62,46 @@ async fn get_url(req: Json<RequestParams>, state_data: &State<RwLock<StateData>>
|
||||||
let media_resp;
|
let media_resp;
|
||||||
match media_result {
|
match media_result {
|
||||||
Ok(r) => media_resp = r,
|
Ok(r) => media_resp = r,
|
||||||
Err(_) => return (Status::InternalServerError, "Error while getting response from media.deezer.com".to_string())
|
Err(_) => return HttpResponse::InternalServerError().body("Error while getting response from media.deezer.com"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if client.license_token != old_license {
|
if client.license_token != old_license {
|
||||||
let mut state_data_write = state_data.write().unwrap();
|
let mut client_write = data.client.write().unwrap();
|
||||||
state_data_write.client = client;
|
*client_write = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
(Status::Ok, media_resp.text().await.unwrap())
|
HttpResponse::Ok()
|
||||||
|
.content_type("application/json")
|
||||||
|
.body(media_resp.text().await.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[options("/get_url")]
|
#[actix_web::main]
|
||||||
fn send_options() -> Status {
|
async fn main() -> std::io::Result<()> {
|
||||||
Status::Ok
|
let port = std::env::var("PORT").unwrap_or("8000".to_string());
|
||||||
}
|
let port: u16 = port.parse().unwrap_or(8000);
|
||||||
|
|
||||||
pub struct CORS;
|
let client = web::Data::new(AppState {
|
||||||
|
client: RwLock::new(APIClient::new()),
|
||||||
|
});
|
||||||
|
|
||||||
#[rocket::async_trait]
|
env_logger::init();
|
||||||
impl Fairing for CORS {
|
|
||||||
fn info(&self) -> Info {
|
|
||||||
Info {
|
|
||||||
name: "Add CORS headers to responses",
|
|
||||||
kind: Kind::Response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
|
HttpServer::new(move || {
|
||||||
response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
|
let cors = Cors::default()
|
||||||
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
|
.allow_any_origin()
|
||||||
}
|
.allowed_methods(vec!["GET", "POST", "OPTIONS", "HEAD"])
|
||||||
}
|
.allowed_header(header::CONTENT_TYPE)
|
||||||
|
.max_age(3600);
|
||||||
|
|
||||||
#[launch]
|
App::new()
|
||||||
fn rocket() -> _ {
|
.wrap(middleware::Logger::default())
|
||||||
rocket::build()
|
.wrap(cors)
|
||||||
.manage(RwLock::new(StateData { client: APIClient::new() }))
|
.wrap(middleware::Compress::default())
|
||||||
.mount("/", routes![index, get_url, send_options])
|
.app_data(client.clone())
|
||||||
.attach(CORS)
|
.service(index)
|
||||||
|
.service(get_url)
|
||||||
|
})
|
||||||
|
.bind(format!("127.0.0.1:{}", port))?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
}
|
}
|
Loading…
Reference in New Issue