2022-05-04 23:13:57 +00:00
|
|
|
use std::time::Instant;
|
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
use actix_web::{
|
|
|
|
get, post, web,
|
|
|
|
HttpRequest, HttpResponse, Scope,
|
2022-04-08 18:52:13 +00:00
|
|
|
http::header::HeaderMap,
|
2021-04-09 00:22:17 +00:00
|
|
|
};
|
|
|
|
use serde::Deserialize;
|
2022-05-04 23:13:57 +00:00
|
|
|
use tokio::sync::Mutex;
|
2021-04-09 00:22:17 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
use crate::config::Config;
|
2022-12-03 21:23:52 +00:00
|
|
|
use crate::database::{get_database_client, DbPool};
|
2021-04-09 00:22:17 +00:00
|
|
|
use crate::errors::HttpError;
|
2021-11-13 23:56:15 +00:00
|
|
|
use crate::frontend::{get_post_page_url, get_profile_page_url};
|
2022-10-01 22:06:31 +00:00
|
|
|
use crate::models::posts::helpers::{add_related_posts, can_view_post};
|
|
|
|
use crate::models::posts::queries::{get_post_by_id, get_posts_by_author};
|
2022-10-27 22:12:54 +00:00
|
|
|
use crate::models::users::queries::{get_user_by_id, get_user_by_name};
|
2022-07-23 21:37:21 +00:00
|
|
|
use super::actors::types::{get_local_actor, get_instance_actor};
|
2022-06-15 11:10:41 +00:00
|
|
|
use super::builders::create_note::{build_note, build_create_note};
|
2021-12-23 21:51:01 +00:00
|
|
|
use super::collections::{
|
|
|
|
COLLECTION_PAGE_SIZE,
|
|
|
|
OrderedCollection,
|
|
|
|
OrderedCollectionPage,
|
|
|
|
};
|
2022-10-01 16:56:57 +00:00
|
|
|
use super::constants::{AP_MEDIA_TYPE, AS_MEDIA_TYPE};
|
2022-07-15 17:31:02 +00:00
|
|
|
use super::identifiers::{
|
|
|
|
local_actor_followers,
|
|
|
|
local_actor_following,
|
2022-10-27 22:12:54 +00:00
|
|
|
local_actor_id,
|
2022-07-15 17:31:02 +00:00
|
|
|
local_actor_subscribers,
|
|
|
|
local_actor_outbox,
|
2022-10-27 22:12:54 +00:00
|
|
|
local_object_id,
|
2022-07-15 17:31:02 +00:00
|
|
|
};
|
2021-04-09 00:22:17 +00:00
|
|
|
use super::receiver::receive_activity;
|
|
|
|
|
2021-12-29 18:36:49 +00:00
|
|
|
fn is_activitypub_request(headers: &HeaderMap) -> bool {
|
|
|
|
const CONTENT_TYPES: [&str; 4] = [
|
2022-10-01 16:56:57 +00:00
|
|
|
AP_MEDIA_TYPE,
|
|
|
|
AS_MEDIA_TYPE,
|
2021-11-13 23:56:15 +00:00
|
|
|
"application/ld+json",
|
|
|
|
"application/json",
|
|
|
|
];
|
2021-12-29 18:36:49 +00:00
|
|
|
if let Some(content_type) = headers.get("Accept") {
|
|
|
|
let content_type_str = content_type.to_str().ok()
|
|
|
|
// Take first content type if there are many
|
2021-12-31 17:15:00 +00:00
|
|
|
.and_then(|value| value.split(',').next())
|
2021-12-29 18:36:49 +00:00
|
|
|
.unwrap_or("");
|
2021-11-13 23:56:15 +00:00
|
|
|
return CONTENT_TYPES.contains(&content_type_str);
|
|
|
|
};
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
#[get("")]
|
2021-11-18 00:51:56 +00:00
|
|
|
async fn actor_view(
|
2021-04-09 00:22:17 +00:00
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2021-11-13 23:56:15 +00:00
|
|
|
request: HttpRequest,
|
2022-04-09 17:04:43 +00:00
|
|
|
username: web::Path<String>,
|
2021-04-09 00:22:17 +00:00
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let user = get_user_by_name(db_client, &username).await?;
|
2021-12-31 17:15:00 +00:00
|
|
|
if !is_activitypub_request(request.headers()) {
|
2021-12-12 19:11:04 +00:00
|
|
|
let page_url = get_profile_page_url(&config.instance_url(), &user.id);
|
2021-11-13 23:56:15 +00:00
|
|
|
let response = HttpResponse::Found()
|
2022-04-08 18:52:13 +00:00
|
|
|
.append_header(("Location", page_url))
|
2021-11-13 23:56:15 +00:00
|
|
|
.finish();
|
|
|
|
return Ok(response);
|
|
|
|
};
|
2021-11-12 23:41:03 +00:00
|
|
|
let actor = get_local_actor(&user, &config.instance_url())
|
2021-09-17 12:36:24 +00:00
|
|
|
.map_err(|_| HttpError::InternalError)?;
|
2021-04-09 00:22:17 +00:00
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-04-09 00:22:17 +00:00
|
|
|
.json(actor);
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/inbox")]
|
|
|
|
async fn inbox(
|
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2022-05-04 23:13:57 +00:00
|
|
|
inbox_mutex: web::Data<Mutex<()>>,
|
2021-04-09 00:22:17 +00:00
|
|
|
request: HttpRequest,
|
|
|
|
activity: web::Json<serde_json::Value>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
2021-12-21 00:14:12 +00:00
|
|
|
log::debug!("received activity: {}", activity);
|
2021-12-29 20:52:30 +00:00
|
|
|
let activity_type = activity["type"].as_str().unwrap_or("Unknown");
|
2022-05-30 17:35:43 +00:00
|
|
|
log::info!("received in {}: {}", request.uri().path(), activity_type);
|
2022-05-04 23:13:57 +00:00
|
|
|
let now = Instant::now();
|
|
|
|
// Store mutex guard in a variable to prevent it from being dropped immediately
|
|
|
|
let _guard = inbox_mutex.lock().await;
|
2022-05-06 19:55:28 +00:00
|
|
|
log::debug!(
|
2022-05-04 23:13:57 +00:00
|
|
|
"acquired inbox lock after waiting for {:.2?}: {}",
|
|
|
|
now.elapsed(),
|
|
|
|
activity["id"].as_str().unwrap_or_default(),
|
|
|
|
);
|
2022-02-23 23:07:51 +00:00
|
|
|
let db_client = &mut **get_database_client(&db_pool).await?;
|
|
|
|
receive_activity(&config, db_client, &request, &activity).await
|
2022-12-11 17:31:48 +00:00
|
|
|
.map_err(|error| {
|
|
|
|
log::warn!(
|
|
|
|
"failed to process activity ({}): {}",
|
|
|
|
error,
|
|
|
|
activity,
|
|
|
|
);
|
|
|
|
error
|
2021-12-06 21:19:23 +00:00
|
|
|
})?;
|
2021-11-20 21:07:03 +00:00
|
|
|
Ok(HttpResponse::Ok().finish())
|
2021-04-09 00:22:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct CollectionQueryParams {
|
2021-12-23 21:51:01 +00:00
|
|
|
page: Option<bool>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/outbox")]
|
|
|
|
async fn outbox(
|
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2022-04-09 17:04:43 +00:00
|
|
|
username: web::Path<String>,
|
2021-12-23 21:51:01 +00:00
|
|
|
query_params: web::Query<CollectionQueryParams>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
let instance = config.instance();
|
2022-07-15 17:31:02 +00:00
|
|
|
let collection_id = local_actor_outbox(&instance.url(), &username);
|
2021-12-23 21:51:01 +00:00
|
|
|
let first_page_id = format!("{}?page=true", collection_id);
|
|
|
|
if query_params.page.is_none() {
|
|
|
|
let collection = OrderedCollection::new(
|
|
|
|
collection_id,
|
|
|
|
Some(first_page_id),
|
2022-09-25 20:59:09 +00:00
|
|
|
None,
|
2021-12-23 21:51:01 +00:00
|
|
|
);
|
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-12-23 21:51:01 +00:00
|
|
|
.json(collection);
|
|
|
|
return Ok(response);
|
|
|
|
};
|
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let user = get_user_by_name(db_client, &username).await?;
|
2022-04-13 20:27:38 +00:00
|
|
|
// Posts are ordered by creation date
|
2022-10-01 22:06:31 +00:00
|
|
|
let mut posts = get_posts_by_author(
|
2022-01-07 01:10:41 +00:00
|
|
|
db_client,
|
|
|
|
&user.id,
|
|
|
|
None, // include only public posts
|
2022-04-13 20:27:38 +00:00
|
|
|
false, // exclude replies
|
|
|
|
false, // exclude reposts
|
2022-09-25 20:59:09 +00:00
|
|
|
None,
|
|
|
|
COLLECTION_PAGE_SIZE,
|
2021-12-23 21:51:01 +00:00
|
|
|
).await?;
|
2022-10-01 22:06:31 +00:00
|
|
|
add_related_posts(db_client, posts.iter_mut().collect()).await?;
|
2021-12-23 21:51:01 +00:00
|
|
|
let activities: Vec<_> = posts.iter().filter_map(|post| {
|
2022-04-13 20:27:38 +00:00
|
|
|
if post.in_reply_to_id.is_some() || post.repost_of_id.is_some() {
|
|
|
|
return None;
|
|
|
|
};
|
2022-06-15 11:10:41 +00:00
|
|
|
let activity = build_create_note(
|
2022-11-24 01:51:43 +00:00
|
|
|
&instance.hostname(),
|
2022-04-13 20:27:38 +00:00
|
|
|
&instance.url(),
|
|
|
|
post,
|
|
|
|
);
|
|
|
|
Some(activity)
|
2021-12-23 21:51:01 +00:00
|
|
|
}).collect();
|
|
|
|
let collection_page = OrderedCollectionPage::new(
|
|
|
|
first_page_id,
|
|
|
|
activities,
|
|
|
|
);
|
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-12-23 21:51:01 +00:00
|
|
|
.json(collection_page);
|
|
|
|
Ok(response)
|
2021-04-09 00:22:17 +00:00
|
|
|
}
|
|
|
|
|
2022-10-31 19:10:55 +00:00
|
|
|
#[post("/outbox")]
|
|
|
|
async fn outbox_client_to_server() -> HttpResponse {
|
|
|
|
HttpResponse::MethodNotAllowed().finish()
|
|
|
|
}
|
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
#[get("/followers")]
|
|
|
|
async fn followers_collection(
|
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2022-04-09 17:04:43 +00:00
|
|
|
username: web::Path<String>,
|
2021-04-09 00:22:17 +00:00
|
|
|
query_params: web::Query<CollectionQueryParams>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
if query_params.page.is_some() {
|
|
|
|
// Social graph is not available
|
|
|
|
return Err(HttpError::PermissionError);
|
2022-09-25 20:59:09 +00:00
|
|
|
};
|
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let user = get_user_by_name(db_client, &username).await?;
|
2022-07-15 17:31:02 +00:00
|
|
|
let collection_id = local_actor_followers(
|
|
|
|
&config.instance_url(),
|
|
|
|
&username,
|
|
|
|
);
|
2022-09-25 20:59:09 +00:00
|
|
|
let collection = OrderedCollection::new(
|
|
|
|
collection_id,
|
|
|
|
None,
|
|
|
|
Some(user.profile.follower_count),
|
|
|
|
);
|
2021-04-09 00:22:17 +00:00
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-04-09 00:22:17 +00:00
|
|
|
.json(collection);
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/following")]
|
|
|
|
async fn following_collection(
|
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2022-04-09 17:04:43 +00:00
|
|
|
username: web::Path<String>,
|
2021-04-09 00:22:17 +00:00
|
|
|
query_params: web::Query<CollectionQueryParams>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
if query_params.page.is_some() {
|
|
|
|
// Social graph is not available
|
|
|
|
return Err(HttpError::PermissionError);
|
2022-09-25 20:59:09 +00:00
|
|
|
};
|
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let user = get_user_by_name(db_client, &username).await?;
|
2022-07-15 17:31:02 +00:00
|
|
|
let collection_id = local_actor_following(
|
|
|
|
&config.instance_url(),
|
|
|
|
&username,
|
|
|
|
);
|
2022-09-25 20:59:09 +00:00
|
|
|
let collection = OrderedCollection::new(
|
|
|
|
collection_id,
|
|
|
|
None,
|
|
|
|
Some(user.profile.following_count),
|
|
|
|
);
|
2021-04-09 00:22:17 +00:00
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-04-09 00:22:17 +00:00
|
|
|
.json(collection);
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
2022-01-15 23:21:13 +00:00
|
|
|
#[get("/subscribers")]
|
|
|
|
async fn subscribers_collection(
|
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2022-04-09 17:04:43 +00:00
|
|
|
username: web::Path<String>,
|
2022-01-15 23:21:13 +00:00
|
|
|
query_params: web::Query<CollectionQueryParams>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
if query_params.page.is_some() {
|
|
|
|
// Subscriber list is hidden
|
|
|
|
return Err(HttpError::PermissionError);
|
2022-09-25 20:59:09 +00:00
|
|
|
};
|
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let user = get_user_by_name(db_client, &username).await?;
|
2022-07-15 17:31:02 +00:00
|
|
|
let collection_id = local_actor_subscribers(
|
|
|
|
&config.instance_url(),
|
|
|
|
&username,
|
|
|
|
);
|
2022-09-25 20:59:09 +00:00
|
|
|
let collection = OrderedCollection::new(
|
|
|
|
collection_id,
|
|
|
|
None,
|
|
|
|
Some(user.profile.subscriber_count),
|
|
|
|
);
|
2022-01-15 23:21:13 +00:00
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2022-01-15 23:21:13 +00:00
|
|
|
.json(collection);
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
2021-11-18 00:51:56 +00:00
|
|
|
pub fn actor_scope() -> Scope {
|
2021-04-09 00:22:17 +00:00
|
|
|
web::scope("/users/{username}")
|
2021-11-18 00:51:56 +00:00
|
|
|
.service(actor_view)
|
2021-04-09 00:22:17 +00:00
|
|
|
.service(inbox)
|
2021-12-23 21:51:01 +00:00
|
|
|
.service(outbox)
|
2022-10-31 19:10:55 +00:00
|
|
|
.service(outbox_client_to_server)
|
2021-04-09 00:22:17 +00:00
|
|
|
.service(followers_collection)
|
|
|
|
.service(following_collection)
|
2022-01-15 23:21:13 +00:00
|
|
|
.service(subscribers_collection)
|
2021-04-09 00:22:17 +00:00
|
|
|
}
|
|
|
|
|
2021-11-20 21:07:03 +00:00
|
|
|
#[get("")]
|
|
|
|
async fn instance_actor_view(
|
2021-11-18 00:51:56 +00:00
|
|
|
config: web::Data<Config>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
let actor = get_instance_actor(&config.instance())
|
|
|
|
.map_err(|_| HttpError::InternalError)?;
|
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-11-18 00:51:56 +00:00
|
|
|
.json(actor);
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
2021-11-20 21:07:03 +00:00
|
|
|
#[post("/inbox")]
|
|
|
|
async fn instance_actor_inbox(
|
|
|
|
activity: web::Json<serde_json::Value>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
2021-11-22 22:38:47 +00:00
|
|
|
log::info!(
|
|
|
|
"received in instance inbox: {}",
|
|
|
|
activity["type"].as_str().unwrap_or("Unknown"),
|
|
|
|
);
|
2021-11-20 21:07:03 +00:00
|
|
|
Ok(HttpResponse::Ok().finish())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn instance_actor_scope() -> Scope {
|
|
|
|
web::scope("/actor")
|
|
|
|
.service(instance_actor_view)
|
|
|
|
.service(instance_actor_inbox)
|
|
|
|
}
|
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
#[get("/objects/{object_id}")]
|
2021-11-18 00:51:56 +00:00
|
|
|
pub async fn object_view(
|
2021-10-08 18:15:04 +00:00
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2021-11-13 23:56:15 +00:00
|
|
|
request: HttpRequest,
|
2022-04-09 17:04:43 +00:00
|
|
|
internal_object_id: web::Path<Uuid>,
|
2021-04-09 00:22:17 +00:00
|
|
|
) -> Result<HttpResponse, HttpError> {
|
2021-10-08 18:15:04 +00:00
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
2022-04-09 17:04:43 +00:00
|
|
|
let internal_object_id = internal_object_id.into_inner();
|
2022-06-15 12:08:53 +00:00
|
|
|
// Try to find local post by ID,
|
|
|
|
// return 404 if not found, or not public, or it is a repost
|
2022-10-01 22:06:31 +00:00
|
|
|
let mut post = get_post_by_id(db_client, &internal_object_id).await?;
|
2022-11-21 18:55:06 +00:00
|
|
|
if !post.is_local() || !can_view_post(db_client, None, &post).await? {
|
2022-10-01 22:06:31 +00:00
|
|
|
return Err(HttpError::NotFoundError("post"));
|
|
|
|
};
|
2021-12-31 17:15:00 +00:00
|
|
|
if !is_activitypub_request(request.headers()) {
|
2021-12-12 19:11:04 +00:00
|
|
|
let page_url = get_post_page_url(&config.instance_url(), &post.id);
|
2021-11-13 23:56:15 +00:00
|
|
|
let response = HttpResponse::Found()
|
2022-04-08 18:52:13 +00:00
|
|
|
.append_header(("Location", page_url))
|
2021-11-13 23:56:15 +00:00
|
|
|
.finish();
|
|
|
|
return Ok(response);
|
|
|
|
};
|
2022-10-01 22:06:31 +00:00
|
|
|
add_related_posts(db_client, vec![&mut post]).await?;
|
2022-06-15 11:10:41 +00:00
|
|
|
let object = build_note(
|
2022-11-24 01:51:43 +00:00
|
|
|
&config.instance().hostname(),
|
2021-11-11 21:51:47 +00:00
|
|
|
&config.instance().url(),
|
2021-12-31 17:15:00 +00:00
|
|
|
&post,
|
2021-11-11 21:51:47 +00:00
|
|
|
);
|
2021-10-08 18:15:04 +00:00
|
|
|
let response = HttpResponse::Ok()
|
2022-10-01 16:56:57 +00:00
|
|
|
.content_type(AP_MEDIA_TYPE)
|
2021-10-08 18:15:04 +00:00
|
|
|
.json(object);
|
2021-04-09 00:22:17 +00:00
|
|
|
Ok(response)
|
|
|
|
}
|
2021-12-29 18:36:49 +00:00
|
|
|
|
2022-10-27 22:12:54 +00:00
|
|
|
#[get("/profile/{profile_id}")]
|
|
|
|
pub async fn frontend_profile_redirect(
|
|
|
|
config: web::Data<Config>,
|
2022-12-03 21:23:52 +00:00
|
|
|
db_pool: web::Data<DbPool>,
|
2022-10-27 22:12:54 +00:00
|
|
|
profile_id: web::Path<Uuid>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
let db_client = &**get_database_client(&db_pool).await?;
|
|
|
|
let user = get_user_by_id(db_client, &profile_id).await?;
|
|
|
|
let actor_id = local_actor_id(
|
|
|
|
&config.instance_url(),
|
|
|
|
&user.profile.username,
|
|
|
|
);
|
|
|
|
let response = HttpResponse::Found()
|
|
|
|
.append_header(("Location", actor_id))
|
|
|
|
.finish();
|
2022-10-28 15:29:48 +00:00
|
|
|
Ok(response)
|
2022-10-27 22:12:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/post/{object_id}")]
|
|
|
|
pub async fn frontend_post_redirect(
|
|
|
|
config: web::Data<Config>,
|
|
|
|
internal_object_id: web::Path<Uuid>,
|
|
|
|
) -> Result<HttpResponse, HttpError> {
|
|
|
|
let object_id = local_object_id(
|
|
|
|
&config.instance_url(),
|
|
|
|
&internal_object_id,
|
|
|
|
);
|
|
|
|
let response = HttpResponse::Found()
|
|
|
|
.append_header(("Location", object_id))
|
|
|
|
.finish();
|
2022-10-28 15:29:48 +00:00
|
|
|
Ok(response)
|
2022-10-27 22:12:54 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 18:36:49 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2022-04-08 18:52:13 +00:00
|
|
|
use actix_web::http::{
|
|
|
|
header,
|
|
|
|
header::{HeaderMap, HeaderValue},
|
|
|
|
};
|
2021-12-29 18:36:49 +00:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_activitypub_request_mastodon() {
|
|
|
|
let mut request_headers = HeaderMap::new();
|
|
|
|
request_headers.insert(
|
|
|
|
header::ACCEPT,
|
|
|
|
HeaderValue::from_static(r#"application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams", text/html;q=0.1"#),
|
|
|
|
);
|
|
|
|
let result = is_activitypub_request(&request_headers);
|
|
|
|
assert_eq!(result, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_activitypub_request_pleroma() {
|
|
|
|
let mut request_headers = HeaderMap::new();
|
|
|
|
request_headers.insert(
|
|
|
|
header::ACCEPT,
|
|
|
|
HeaderValue::from_static("application/activity+json"),
|
|
|
|
);
|
|
|
|
let result = is_activitypub_request(&request_headers);
|
|
|
|
assert_eq!(result, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_activitypub_request_browser() {
|
|
|
|
let mut request_headers = HeaderMap::new();
|
|
|
|
request_headers.insert(
|
|
|
|
header::ACCEPT,
|
|
|
|
HeaderValue::from_static("text/html"),
|
|
|
|
);
|
|
|
|
let result = is_activitypub_request(&request_headers);
|
|
|
|
assert_eq!(result, false);
|
|
|
|
}
|
|
|
|
}
|