mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 10:11:31 +00:00
add a few more clients for testing
This commit is contained in:
1 parent
671fe5892b
commit
6c053aba7c
4 files changed
+93
-8
No files matched your search
@@ -208,7 +208,8 @@ CREATE TABLE generic_inference_jobs (
|
||||
-- Multiple debug_logs rows can share the same event token.
|
||||
maybe_debug_log_event_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- The platform the enqueuing request came from ('web', 'desktop_app', 'curl'),
|
||||
-- The platform the enqueuing request came from ('web', 'desktop_app',
|
||||
-- 'curl', 'python_requests', 'postman'),
|
||||
-- inferred from the request's User-Agent header.
|
||||
platform_type VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ CREATE TABLE media_files (
|
||||
-- What service provided the generation (if any).
|
||||
maybe_generation_provider VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- The platform the creating request came from ('web', 'desktop_app', 'curl'),
|
||||
-- The platform the creating request came from ('web', 'desktop_app',
|
||||
-- 'curl', 'python_requests', 'postman'),
|
||||
-- inferred from the request's User-Agent header. Copied from the originating
|
||||
-- generic_inference_jobs row for inference results.
|
||||
platform_type VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
@@ -21,6 +21,8 @@ pub enum PlatformType {
|
||||
Web,
|
||||
DesktopApp,
|
||||
Curl,
|
||||
PythonRequests,
|
||||
Postman,
|
||||
}
|
||||
|
||||
impl_enum_display_and_debug_using_to_str!(PlatformType);
|
||||
@@ -33,6 +35,8 @@ impl PlatformType {
|
||||
Self::Web => "web",
|
||||
Self::DesktopApp => "desktop_app",
|
||||
Self::Curl => "curl",
|
||||
Self::PythonRequests => "python_requests",
|
||||
Self::Postman => "postman",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +45,8 @@ impl PlatformType {
|
||||
"web" => Ok(Self::Web),
|
||||
"desktop_app" => Ok(Self::DesktopApp),
|
||||
"curl" => Ok(Self::Curl),
|
||||
"python_requests" => Ok(Self::PythonRequests),
|
||||
"postman" => Ok(Self::Postman),
|
||||
_ => Err(EnumError::CouldNotConvertFromString(value.to_string())),
|
||||
}
|
||||
}
|
||||
@@ -51,6 +57,8 @@ impl PlatformType {
|
||||
Self::Web,
|
||||
Self::DesktopApp,
|
||||
Self::Curl,
|
||||
Self::PythonRequests,
|
||||
Self::Postman,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -69,6 +77,8 @@ mod tests {
|
||||
assert_serialization(PlatformType::Web, "web");
|
||||
assert_serialization(PlatformType::DesktopApp, "desktop_app");
|
||||
assert_serialization(PlatformType::Curl, "curl");
|
||||
assert_serialization(PlatformType::PythonRequests, "python_requests");
|
||||
assert_serialization(PlatformType::Postman, "postman");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -76,6 +86,8 @@ mod tests {
|
||||
assert_eq!(PlatformType::Web.to_str(), "web");
|
||||
assert_eq!(PlatformType::DesktopApp.to_str(), "desktop_app");
|
||||
assert_eq!(PlatformType::Curl.to_str(), "curl");
|
||||
assert_eq!(PlatformType::PythonRequests.to_str(), "python_requests");
|
||||
assert_eq!(PlatformType::Postman.to_str(), "postman");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -83,6 +95,8 @@ mod tests {
|
||||
assert_eq!(PlatformType::from_str("web").unwrap(), PlatformType::Web);
|
||||
assert_eq!(PlatformType::from_str("desktop_app").unwrap(), PlatformType::DesktopApp);
|
||||
assert_eq!(PlatformType::from_str("curl").unwrap(), PlatformType::Curl);
|
||||
assert_eq!(PlatformType::from_str("python_requests").unwrap(), PlatformType::PythonRequests);
|
||||
assert_eq!(PlatformType::from_str("postman").unwrap(), PlatformType::Postman);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -99,10 +113,12 @@ mod tests {
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = PlatformType::all_variants();
|
||||
assert_eq!(variants.len(), 3);
|
||||
assert_eq!(variants.len(), 5);
|
||||
assert_eq!(variants.pop_first(), Some(PlatformType::Web));
|
||||
assert_eq!(variants.pop_first(), Some(PlatformType::DesktopApp));
|
||||
assert_eq!(variants.pop_first(), Some(PlatformType::Curl));
|
||||
assert_eq!(variants.pop_first(), Some(PlatformType::PythonRequests));
|
||||
assert_eq!(variants.pop_first(), Some(PlatformType::Postman));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
+72
-5
@@ -9,11 +9,24 @@ const DESKTOP_CLIENT_USER_AGENT_PREFIX : &str = "storyteller-client";
|
||||
/// User-Agent prefix sent by the curl CLI tool, eg. "curl/8.7.1".
|
||||
const CURL_USER_AGENT_PREFIX : &str = "curl";
|
||||
|
||||
/// User-Agent prefix sent by the Python `requests` library.
|
||||
/// Modern releases send "python-requests/2.31.0" (optionally followed by
|
||||
/// "CPython/x.y.z OS/release" in older releases, eg.
|
||||
/// "python-requests/0.14.2 CPython/2.7.3 Linux/3.2.0"). Some early releases
|
||||
/// sent the bare "python-requests.org", which shares this prefix.
|
||||
const PYTHON_REQUESTS_USER_AGENT_PREFIX : &str = "python-requests";
|
||||
|
||||
/// User-Agent prefix sent by Postman, eg. "PostmanRuntime/7.36.0".
|
||||
/// All known Postman Runtime versions (2.x through 8.x) use this form.
|
||||
/// (Compared case-insensitively.)
|
||||
const POSTMAN_USER_AGENT_PREFIX : &str = "postmanruntime";
|
||||
|
||||
/// Infer the calling platform from the request's User-Agent header.
|
||||
///
|
||||
/// Returns `None` if the header is absent or unreadable. Otherwise, the ArtCraft
|
||||
/// desktop client identifies itself with a "storyteller-client" prefix, curl-like
|
||||
/// CLI callers are flagged as such, and anything else is assumed to be a browser.
|
||||
/// desktop client identifies itself with a "storyteller-client" prefix, known
|
||||
/// CLI/API tools (curl, python-requests, Postman) are flagged as such, and
|
||||
/// anything else is assumed to be a browser.
|
||||
pub fn get_request_platform_type(http_request: &HttpRequest) -> Option<PlatformType> {
|
||||
let user_agent_header_name = HeaderName::from_static("user-agent");
|
||||
let header_map : &HeaderMap = http_request.headers();
|
||||
@@ -32,9 +45,16 @@ fn platform_type_from_user_agent(user_agent: &str) -> Option<PlatformType> {
|
||||
if user_agent.starts_with(DESKTOP_CLIENT_USER_AGENT_PREFIX) {
|
||||
return Some(PlatformType::DesktopApp);
|
||||
}
|
||||
if user_agent.to_ascii_lowercase().starts_with(CURL_USER_AGENT_PREFIX) {
|
||||
let lowercase_user_agent = user_agent.to_ascii_lowercase();
|
||||
if lowercase_user_agent.starts_with(CURL_USER_AGENT_PREFIX) {
|
||||
return Some(PlatformType::Curl);
|
||||
}
|
||||
if lowercase_user_agent.starts_with(PYTHON_REQUESTS_USER_AGENT_PREFIX) {
|
||||
return Some(PlatformType::PythonRequests);
|
||||
}
|
||||
if lowercase_user_agent.starts_with(POSTMAN_USER_AGENT_PREFIX) {
|
||||
return Some(PlatformType::Postman);
|
||||
}
|
||||
Some(PlatformType::Web)
|
||||
}
|
||||
|
||||
@@ -69,6 +89,20 @@ mod tests {
|
||||
Some(PlatformType::Curl));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn python_requests_user_agent() {
|
||||
assert_eq!(
|
||||
platform_type_for_user_agent_header("python-requests/2.31.0"),
|
||||
Some(PlatformType::PythonRequests));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn postman_user_agent() {
|
||||
assert_eq!(
|
||||
platform_type_for_user_agent_header("PostmanRuntime/7.36.0"),
|
||||
Some(PlatformType::Postman));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn browser_user_agent() {
|
||||
assert_eq!(
|
||||
@@ -105,10 +139,43 @@ mod tests {
|
||||
assert_eq!(platform_type_from_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)"), Some(PlatformType::Web));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn python_requests_versions() {
|
||||
// Modern releases: bare "python-requests/<version>".
|
||||
assert_eq!(platform_type_from_user_agent("python-requests/2.31.0"), Some(PlatformType::PythonRequests));
|
||||
assert_eq!(platform_type_from_user_agent("python-requests/2.32.3"), Some(PlatformType::PythonRequests));
|
||||
// Older releases appended runtime and OS details.
|
||||
assert_eq!(
|
||||
platform_type_from_user_agent("python-requests/0.14.2 CPython/2.7.3 Linux/3.2.0-armv7l"),
|
||||
Some(PlatformType::PythonRequests));
|
||||
assert_eq!(
|
||||
platform_type_from_user_agent("python-requests/1.1.0 CPython/2.6.6 Linux/2.6.32-431.3.1.el6.x86_64"),
|
||||
Some(PlatformType::PythonRequests));
|
||||
// Some early releases sent the bare project domain.
|
||||
assert_eq!(platform_type_from_user_agent("python-requests.org"), Some(PlatformType::PythonRequests));
|
||||
// Case-insensitive.
|
||||
assert_eq!(platform_type_from_user_agent("Python-Requests/2.25.1"), Some(PlatformType::PythonRequests));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn postman_versions() {
|
||||
// Modern Postman Runtime 7.x/8.x.
|
||||
assert_eq!(platform_type_from_user_agent("PostmanRuntime/7.36.0"), Some(PlatformType::Postman));
|
||||
assert_eq!(platform_type_from_user_agent("PostmanRuntime/8.0.3"), Some(PlatformType::Postman));
|
||||
// Historical Postman Runtime versions.
|
||||
assert_eq!(platform_type_from_user_agent("PostmanRuntime/2.4.5"), Some(PlatformType::Postman));
|
||||
assert_eq!(platform_type_from_user_agent("PostmanRuntime/7.6.0"), Some(PlatformType::Postman));
|
||||
// Case-insensitive, with surrounding whitespace.
|
||||
assert_eq!(platform_type_from_user_agent(" postmanruntime/7.26.8 "), Some(PlatformType::Postman));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unknown_tools_are_web() {
|
||||
assert_eq!(platform_type_from_user_agent("python-requests/2.31.0"), Some(PlatformType::Web));
|
||||
assert_eq!(platform_type_from_user_agent("PostmanRuntime/7.36.0"), Some(PlatformType::Web));
|
||||
assert_eq!(platform_type_from_user_agent("Go-http-client/2.0"), Some(PlatformType::Web));
|
||||
assert_eq!(platform_type_from_user_agent("insomnia/8.6.1"), Some(PlatformType::Web));
|
||||
// Other Python HTTP clients are not the `requests` library.
|
||||
assert_eq!(platform_type_from_user_agent("python-httpx/0.27.0"), Some(PlatformType::Web));
|
||||
assert_eq!(platform_type_from_user_agent("Python-urllib/3.11"), Some(PlatformType::Web));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user