feat: add head endpoint

This commit is contained in:
nazeh
2024-10-17 18:28:22 +03:00
parent 4067aedcee
commit ed06a4681e
4 changed files with 51 additions and 5 deletions

4
Cargo.lock generated
View File

@@ -1704,9 +1704,9 @@ dependencies = [
[[package]]
name = "pubky-timestamp"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d018cd110531645acddc6493bb9f07d1f4869205d53ceea69f2331d5ff7af"
checksum = "084b6e5bfcc186781b71257d636b660f20e94bb588c3ba52393fd9faf7a7bfda"
dependencies = [
"base32",
"document-features",

View File

@@ -18,7 +18,7 @@ crypto_secretbox = { version = "0.1.1", features = ["std"] }
argon2 = { version = "0.5.3", features = ["std"] }
serde = { workspace = true, optional = true }
pubky-timestamp = { version = "0.1.0", features = ["full"] }
pubky-timestamp = { version = "0.2.0", features = ["full"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3.69"

View File

@@ -1,6 +1,6 @@
use axum::{
extract::DefaultBodyLimit,
routing::{delete, get, post, put},
routing::{delete, get, head, post, put},
Router,
};
use tower_cookies::CookieManagerLayer;
@@ -25,6 +25,7 @@ fn base(state: AppState) -> Router {
.route("/:pubky/session", delete(auth::signout))
.route("/:pubky/*path", put(public::put))
.route("/:pubky/*path", get(public::get))
.route("/:pubky/*path", head(public::head))
.route("/:pubky/*path", delete(public::delete))
.route("/events/", get(feed::feed))
.layer(CookieManagerLayer::new())

View File

@@ -1,7 +1,7 @@
use axum::{
body::Body,
extract::State,
http::{header, Response, StatusCode},
http::{header, HeaderMap, HeaderValue, Response, StatusCode},
response::IntoResponse,
};
use futures_util::stream::StreamExt;
@@ -125,6 +125,26 @@ pub async fn get(
}
}
pub async fn head(
State(state): State<AppState>,
pubky: Pubky,
path: EntryPath,
) -> Result<impl IntoResponse> {
verify(path.as_str())?;
let rtxn = state.db.env.read_txn()?;
match state
.db
.get_entry(&rtxn, pubky.public_key(), path.as_str())?
.as_ref()
.map(HeaderMap::from)
{
Some(headers) => Ok(headers),
None => Err(Error::with_status(StatusCode::NOT_FOUND)),
}
}
pub async fn delete(
State(mut state): State<AppState>,
pubky: Pubky,
@@ -188,3 +208,28 @@ fn verify(path: &str) -> Result<()> {
Ok(())
}
impl From<&Entry> for HeaderMap {
fn from(entry: &Entry) -> Self {
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_LENGTH, entry.content_length().into());
headers.insert(header::LAST_MODIFIED, entry.timestamp().format_http_date());
headers.insert(
header::CONTENT_TYPE,
// TODO: when setting content type from user input, we should validate it as a HeaderValue
entry
.content_type()
.try_into()
.or(HeaderValue::from_str(""))
.expect("valid header value"),
);
headers.insert(
header::ETAG,
format!("\"{}\"", entry.content_hash())
.try_into()
.expect("hex string is valid"),
);
headers
}
}