Skip to content

Commit

Permalink
Use get_subject
Browse files Browse the repository at this point in the history
  • Loading branch information
joepio committed Mar 11, 2023
1 parent 66e0c8d commit 56fdb2d
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 81 deletions.
33 changes: 3 additions & 30 deletions server/src/handlers/get_resource.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::{
appstate::AppState,
content_types::get_accept,
content_types::ContentType,
errors::AtomicServerResult,
helpers::{get_client_agent, try_extension},
helpers::{get_client_agent, get_subject},
};
use actix_web::{web, HttpResponse};
use atomic_lib::Storelike;
Expand All @@ -16,39 +15,13 @@ pub async fn handle_get_resource(
path: Option<web::Path<String>>,
appstate: web::Data<AppState>,
req: actix_web::HttpRequest,
conn: actix_web::dev::ConnectionInfo,
) -> AtomicServerResult<HttpResponse> {
let mut timer = Timer::new();

let headers = req.headers();
let mut content_type = get_accept(headers);
let server_url = &appstate.config.server_url;
// Get the subject from the path, or return the home URL
let subject = if let Some(subj_end) = path {
let mut subj_end_string = subj_end.as_str();
// If the request is for the root, return the home URL
if subj_end_string.is_empty() {
server_url.to_string()
} else {
if content_type == ContentType::Html {
if let Some((ext, path)) = try_extension(subj_end_string) {
content_type = ext;
subj_end_string = path;
}
}
// Check extensions and set datatype. Harder than it looks to get right...
// This might not be the best way of creating the subject. But I can't access the full URL from any actix stuff!
let querystring = if req.query_string().is_empty() {
"".to_string()
} else {
format!("?{}", req.query_string())
};
let subject = format!("{}/{}{}", server_url, subj_end_string, querystring);
subject
}
} else {
// There is no end string, so It's the root of the URL, the base URL!
String::from(server_url)
};
let (subject, content_type) = get_subject(&req, &conn, &appstate)?;

let store = &appstate.store;
timer.add("parse_headers");
Expand Down
33 changes: 3 additions & 30 deletions server/src/handlers/post_resource.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::{
appstate::AppState,
content_types::get_accept,
content_types::ContentType,
errors::AtomicServerResult,
helpers::{get_client_agent, try_extension},
helpers::{get_client_agent, get_subject},
};
use actix_web::{web, HttpResponse};
use atomic_lib::Storelike;
Expand All @@ -16,39 +15,13 @@ pub async fn handle_post_resource(
appstate: web::Data<AppState>,
req: actix_web::HttpRequest,
body: web::Bytes,
conn: actix_web::dev::ConnectionInfo,
) -> AtomicServerResult<HttpResponse> {
let mut timer = Timer::new();

let headers = req.headers();
let mut content_type = get_accept(headers);
let server_url = &appstate.config.server_url;
// Get the subject from the path, or return the home URL
let subject = if let Some(subj_end) = path {
let mut subj_end_string = subj_end.as_str();
// If the request is for the root, return the home URL
if subj_end_string.is_empty() {
server_url.to_string()
} else {
if content_type == ContentType::Html {
if let Some((ext, path)) = try_extension(subj_end_string) {
content_type = ext;
subj_end_string = path;
}
}
// Check extensions and set datatype. Harder than it looks to get right...
// This might not be the best way of creating the subject. But I can't access the full URL from any actix stuff!
let querystring = if req.query_string().is_empty() {
"".to_string()
} else {
format!("?{}", req.query_string())
};
let subject = format!("{}/{}{}", server_url, subj_end_string, querystring);
subject
}
} else {
// There is no end string, so It's the root of the URL, the base URL!
String::from(server_url)
};
let (subject, content_type) = get_subject(&req, &conn, &appstate)?;

let store = &appstate.store;
timer.add("parse_headers");
Expand Down
2 changes: 1 addition & 1 deletion server/src/handlers/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub async fn search_query(
let subjects = docs_to_subjects(top_docs, &fields, &searcher)?;

// Create a valid atomic data resource.
let subject: String = get_subject(&req, &conn, &appstate)?;
let (subject, _) = get_subject(&req, &conn, &appstate)?;

let mut results_resource = atomic_lib::plugins::search::search_endpoint().to_resource(store)?;
results_resource.set_subject(subject.clone());
Expand Down
7 changes: 6 additions & 1 deletion server/src/handlers/single_page_app.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fmt::Display;
use std::fmt::Formatter;

use crate::helpers::get_subject;
use crate::{appstate::AppState, errors::AtomicServerResult};
use actix_web::HttpResponse;

Expand All @@ -9,9 +10,13 @@ use actix_web::HttpResponse;
pub async fn single_page(
appstate: actix_web::web::Data<AppState>,
path: actix_web::web::Path<String>,
req: actix_web::HttpRequest,
conn: actix_web::dev::ConnectionInfo,
) -> AtomicServerResult<HttpResponse> {
let template = include_str!("../../app_assets/index.html");
let subject = format!("{}/{}", appstate.store.get_server_url(), path);
// We could check the extension and serialize the Resource in the response. However, I'm not sure this is a great idea.
let (subject, _content_type) = get_subject(&req, &conn, &appstate)?;

let meta_tags: MetaTags = if let Ok(resource) =
appstate
.store
Expand Down
2 changes: 1 addition & 1 deletion server/src/handlers/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub async fn upload_handler(
) -> AtomicServerResult<HttpResponse> {
let store = &appstate.store;
let parent = store.get_resource(&query.parent)?;
let subject = get_subject(&req, &conn, &appstate)?;
let (subject, _) = get_subject(&req, &conn, &appstate)?;
if let Some(agent) = get_client_agent(req.headers(), &appstate, subject)? {
check_write(store, &parent, &agent)?;
} else {
Expand Down
63 changes: 45 additions & 18 deletions server/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use atomic_lib::Storelike;
use percent_encoding::percent_decode_str;
use std::str::FromStr;

use crate::content_types::ContentType;
use crate::content_types::{get_accept, ContentType};
use crate::errors::{AppErrorType, AtomicServerError};
use crate::{appstate::AppState, errors::AtomicServerResult};

Expand Down Expand Up @@ -248,7 +248,9 @@ pub fn get_subject(
req: &actix_web::HttpRequest,
conn: &actix_web::dev::ConnectionInfo,
appstate: &AppState,
) -> AtomicServerResult<String> {
) -> AtomicServerResult<(String, ContentType)> {
let content_type = get_accept(req.headers());

let domain = &appstate.config.opts.domain;
let host = conn.host();
let subdomain = if let Some(index) = host.find(domain) {
Expand All @@ -267,23 +269,48 @@ pub fn get_subject(
}
let server_without_last_slash = subject_url.to_string().trim_end_matches('/').to_string();
let subject = format!("{}{}", server_without_last_slash, &req.uri().to_string());
Ok(subject)
// if let Some((ct, path)) = try_extension(req.path()) {
// content_type = ct;
// return Ok((path.to_string(), content_type));
// }
Ok((subject, content_type))
}

/// Finds the extension
pub fn try_extension(path: &str) -> Option<(ContentType, &str)> {
let items: Vec<&str> = path.split('.').collect();
if items.len() == 2 {
let path = items[0];
let content_type = match items[1] {
"json" => ContentType::Json,
"jsonld" => ContentType::JsonLd,
"jsonad" => ContentType::JsonAd,
"html" => ContentType::Html,
"ttl" => ContentType::Turtle,
_ => return None,
};
return Some((content_type, path));
/// Finds the extension of a supported serialization format.
/// Not used right now, see: https://github.com/atomicdata-dev/atomic-data-rust/issues/601
#[allow(dead_code)]
fn try_extension(path: &str) -> Option<(ContentType, &str)> {
// Check if path ends with one of the folliwing extensions
let extensions = [
".json",
".jsonld",
".jsonad",
".html",
".ttl",
".nt",
".nq",
".ntriples",
".nt",
];
let mut found = None;
for ext in extensions.iter() {
if path.ends_with(ext) {
println!("Found extension: {}", ext);
let path = &path[0..path.len() - ext.len()];
let content_type = match *ext {
".json" => Some(ContentType::Json),
".jsonld" => Some(ContentType::JsonLd),
".jsonad" => Some(ContentType::JsonAd),
".html" => Some(ContentType::Html),
".ttl" => Some(ContentType::Turtle),
".nt" => Some(ContentType::NTriples),
".ntriples" => Some(ContentType::NTriples),
_ => None,
};
if let Some(ct) = content_type {
found = Some((ct, path));
}
}
}
None
found
}

0 comments on commit 56fdb2d

Please sign in to comment.