c-rust / src /common /client.rs
kevin
rust
cd872f9
use crate::app::{
constant::{
CONTENT_TYPE_CONNECT_PROTO, CURSOR_API2_HOST, CURSOR_HOST, CURSOR_SETTINGS_URL,
HEADER_NAME_GHOST_MODE, TRUE,
},
lazy::{
CURSOR_API2_CHAT_URL, CURSOR_API2_STRIPE_URL, CURSOR_USAGE_API_URL, CURSOR_USER_API_URL,
REVERSE_PROXY_HOST, USE_PROXY,
},
};
use reqwest::header::{
ACCEPT, ACCEPT_ENCODING, ACCEPT_LANGUAGE, CACHE_CONTROL, CONNECTION, CONTENT_TYPE, COOKIE, DNT,
HOST, ORIGIN, PRAGMA, REFERER, TE, TRANSFER_ENCODING, USER_AGENT,
};
use reqwest::{Client, RequestBuilder};
use uuid::Uuid;
use super::utils::generate_hash;
macro_rules! def_const {
($name:ident, $value:expr) => {
const $name: &'static str = $value;
};
}
def_const!(SEC_FETCH_DEST, "sec-fetch-dest");
def_const!(SEC_FETCH_MODE, "sec-fetch-mode");
def_const!(SEC_FETCH_SITE, "sec-fetch-site");
def_const!(SEC_GPC, "sec-gpc");
def_const!(PRIORITY, "priority");
def_const!(ONE, "1");
def_const!(ENCODINGS, "gzip,br");
def_const!(VALUE_ACCEPT, "*/*");
def_const!(VALUE_LANGUAGE, "zh-CN");
def_const!(EMPTY, "empty");
def_const!(CORS, "cors");
def_const!(NO_CACHE, "no-cache");
def_const!(UA_WIN, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36");
def_const!(SAME_ORIGIN, "same-origin");
def_const!(KEEP_ALIVE, "keep-alive");
def_const!(TRAILERS, "trailers");
def_const!(U_EQ_4, "u=4");
def_const!(PROXY_HOST, "x-co");
/// 返回预构建的 Cursor API 客户端
///
/// # 参数
///
/// * `auth_token` - 授权令牌
/// * `checksum` - 校验和
/// * `endpoint` - API 端点路径
///
/// # 返回
///
/// * `reqwest::RequestBuilder` - 配置好的请求构建器
pub fn build_client(auth_token: &str, checksum: &str) -> RequestBuilder {
let trace_id = Uuid::new_v4().to_string();
let client = if *USE_PROXY {
Client::new()
.post(&*CURSOR_API2_CHAT_URL)
.header(HOST, &*REVERSE_PROXY_HOST)
.header(PROXY_HOST, CURSOR_API2_HOST)
} else {
Client::new()
.post(&*CURSOR_API2_CHAT_URL)
.header(HOST, CURSOR_API2_HOST)
};
client
.header(CONTENT_TYPE, CONTENT_TYPE_CONNECT_PROTO)
.bearer_auth(auth_token)
.header("connect-accept-encoding", ENCODINGS)
.header("connect-protocol-version", ONE)
.header(USER_AGENT, "connect-es/1.6.1")
.header("x-amzn-trace-id", format!("Root={}", trace_id))
.header("x-client-key", generate_hash())
.header("x-cursor-checksum", checksum)
.header("x-cursor-client-version", "0.42.5")
.header("x-cursor-timezone", "Asia/Shanghai")
.header(HEADER_NAME_GHOST_MODE, TRUE)
.header("x-request-id", trace_id)
.header(CONNECTION, KEEP_ALIVE)
.header(TRANSFER_ENCODING, "chunked")
}
/// 返回预构建的获取 Stripe 账户信息的 Cursor API 客户端
///
/// # 参数
///
/// * `auth_token` - 授权令牌
///
/// # 返回
///
/// * `reqwest::RequestBuilder` - 配置好的请求构建器
pub fn build_profile_client(auth_token: &str) -> RequestBuilder {
let client = if *USE_PROXY {
Client::new()
.get(&*CURSOR_API2_STRIPE_URL)
.header(HOST, &*REVERSE_PROXY_HOST)
.header(PROXY_HOST, CURSOR_API2_HOST)
} else {
Client::new()
.get(&*CURSOR_API2_STRIPE_URL)
.header(HOST, CURSOR_API2_HOST)
};
client
.header("sec-ch-ua", "\"Not-A.Brand\";v=\"99\", \"Chromium\";v=\"124\"")
.header(HEADER_NAME_GHOST_MODE, TRUE)
.header("sec-ch-ua-mobile", "?0")
.bearer_auth(auth_token)
.header(
USER_AGENT,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Cursor/0.42.5 Chrome/124.0.6367.243 Electron/30.4.0 Safari/537.36",
)
.header("sec-ch-ua-platform", "\"Windows\"")
.header(ACCEPT, VALUE_ACCEPT)
.header(ORIGIN, "vscode-file://vscode-app")
.header(SEC_FETCH_SITE, "cross-site")
.header(SEC_FETCH_MODE, CORS)
.header(SEC_FETCH_DEST, EMPTY)
.header(ACCEPT_ENCODING, ENCODINGS)
.header(ACCEPT_LANGUAGE, VALUE_LANGUAGE)
.header(PRIORITY, "u=1, i")
}
/// 返回预构建的获取使用情况的 Cursor API 客户端
///
/// # 参数
///
/// * `user_id` - 用户 ID
/// * `auth_token` - 授权令牌
///
/// # 返回
///
/// * `reqwest::RequestBuilder` - 配置好的请求构建器
pub fn build_usage_client(user_id: &str, auth_token: &str) -> RequestBuilder {
let session_token = format!("{}%3A%3A{}", user_id, auth_token);
let client = if *USE_PROXY {
Client::new()
.get(&*CURSOR_USAGE_API_URL)
.header(HOST, &*REVERSE_PROXY_HOST)
.header(PROXY_HOST, CURSOR_HOST)
} else {
Client::new()
.get(&*CURSOR_USAGE_API_URL)
.header(HOST, CURSOR_HOST)
};
client
.header(USER_AGENT, UA_WIN)
.header(ACCEPT, VALUE_ACCEPT)
.header(ACCEPT_LANGUAGE, VALUE_LANGUAGE)
.header(ACCEPT_ENCODING, ENCODINGS)
.header(REFERER, CURSOR_SETTINGS_URL)
.header(DNT, ONE)
.header(SEC_GPC, ONE)
.header(SEC_FETCH_DEST, EMPTY)
.header(SEC_FETCH_MODE, CORS)
.header(SEC_FETCH_SITE, SAME_ORIGIN)
.header(CONNECTION, KEEP_ALIVE)
.header(PRAGMA, NO_CACHE)
.header(CACHE_CONTROL, NO_CACHE)
.header(TE, TRAILERS)
.header(PRIORITY, U_EQ_4)
.header(
COOKIE,
&format!("WorkosCursorSessionToken={}", session_token),
)
.query(&[("user", user_id)])
}
/// 返回预构建的获取用户信息的 Cursor API 客户端
///
/// # 参数
///
/// * `user_id` - 用户 ID
/// * `auth_token` - 授权令牌
///
/// # 返回
///
/// * `reqwest::RequestBuilder` - 配置好的请求构建器
pub fn build_userinfo_client(user_id: &str, auth_token: &str) -> RequestBuilder {
let session_token = format!("{}%3A%3A{}", user_id, auth_token);
let client = if *USE_PROXY {
Client::new()
.get(&*CURSOR_USER_API_URL)
.header(HOST, &*REVERSE_PROXY_HOST)
.header(PROXY_HOST, CURSOR_HOST)
} else {
Client::new()
.get(&*CURSOR_USER_API_URL)
.header(HOST, CURSOR_HOST)
};
client
.header(USER_AGENT, UA_WIN)
.header(ACCEPT, VALUE_ACCEPT)
.header(ACCEPT_LANGUAGE, VALUE_LANGUAGE)
.header(ACCEPT_ENCODING, ENCODINGS)
.header(REFERER, CURSOR_SETTINGS_URL)
.header(DNT, ONE)
.header(SEC_GPC, ONE)
.header(SEC_FETCH_DEST, EMPTY)
.header(SEC_FETCH_MODE, CORS)
.header(SEC_FETCH_SITE, SAME_ORIGIN)
.header(CONNECTION, KEEP_ALIVE)
.header(PRAGMA, NO_CACHE)
.header(CACHE_CONTROL, NO_CACHE)
.header(TE, TRAILERS)
.header(PRIORITY, U_EQ_4)
.header(
COOKIE,
&format!("WorkosCursorSessionToken={}", session_token),
)
.query(&[("user", user_id)])
}