提交qiming-mcp-proxy
This commit is contained in:
105
qiming-mcp-proxy/oss-client/examples/basic_usage.rs
Normal file
105
qiming-mcp-proxy/oss-client/examples/basic_usage.rs
Normal file
@@ -0,0 +1,105 @@
|
||||
//! 基本使用示例
|
||||
|
||||
use oss_client::{OssConfig, PrivateOssClient, format_file_size, generate_random_filename};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== Basic usage examples of OSS client ===\\n");
|
||||
|
||||
// 显示库信息
|
||||
println!("Library name: {}", oss_client::name());
|
||||
println!("Version: {}", oss_client::version());
|
||||
println!("Description: {}\\n", oss_client::description());
|
||||
|
||||
// 方式1:从环境变量创建客户端(推荐)
|
||||
println!("1. Try creating a client from environment variables...");
|
||||
let oss_config = oss_client::OssConfig::new(
|
||||
oss_client::defaults::ENDPOINT.to_string(),
|
||||
oss_client::defaults::PUBLIC_BUCKET.to_string(),
|
||||
"demo_access_key_id".to_string(),
|
||||
"demo_access_key_secret".to_string(),
|
||||
oss_client::defaults::REGION.to_string(),
|
||||
oss_client::defaults::UPLOAD_DIRECTORY.to_string(),
|
||||
);
|
||||
let client = PrivateOssClient::new(oss_config);
|
||||
match client {
|
||||
Ok(client) => {
|
||||
println!("✓ Successful creation of client from environment variables");
|
||||
println!("Base URL: {}", client.get_base_url());
|
||||
|
||||
// 演示工具函数
|
||||
demonstrate_utilities(&client)?;
|
||||
|
||||
// 注意:实际的文件操作需要有效的OSS凭证
|
||||
println!(
|
||||
"\\nNote: To perform actual file operations, set the following environment variables:"
|
||||
);
|
||||
println!(" export OSS_ACCESS_KEY_ID=\"your_access_key_id\"");
|
||||
println!(" export OSS_ACCESS_KEY_SECRET=\"your_access_key_secret\"");
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✗ Failed to create client from environment variable: {e}");
|
||||
println!(
|
||||
"Please set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables"
|
||||
);
|
||||
|
||||
// 方式2:手动创建配置(演示用)
|
||||
println!("\\n2. Create a client using the sample configuration...");
|
||||
let config = OssConfig::new(
|
||||
oss_client::defaults::ENDPOINT.to_string(),
|
||||
oss_client::defaults::PUBLIC_BUCKET.to_string(),
|
||||
"demo_access_key_id".to_string(),
|
||||
"demo_access_key_secret".to_string(),
|
||||
oss_client::defaults::REGION.to_string(),
|
||||
oss_client::defaults::UPLOAD_DIRECTORY.to_string(),
|
||||
);
|
||||
let client = PrivateOssClient::new(config)?;
|
||||
println!("✓ Successful creation of client using sample configuration");
|
||||
println!("Base URL: {}", client.get_base_url());
|
||||
|
||||
// 演示工具函数
|
||||
demonstrate_utilities(&client)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn demonstrate_utilities(client: &PrivateOssClient) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("\\n=== Tool function demonstration ===");
|
||||
|
||||
// 文件名处理
|
||||
let random_filename = generate_random_filename(Some("txt"));
|
||||
println!("Random file name: {random_filename}");
|
||||
|
||||
// 文件大小格式化
|
||||
let sizes = vec![1024, 1024 * 1024, 1024 * 1024 * 1024];
|
||||
for size in sizes {
|
||||
println!("File size {} bytes = {}", size, format_file_size(size));
|
||||
}
|
||||
|
||||
// MIME类型检测
|
||||
let files = vec!["test.jpg", "document.pdf", "data.xlsx", "video.mp4"];
|
||||
for file in files {
|
||||
println!(
|
||||
"MIME type of file {}: {}",
|
||||
file,
|
||||
oss_client::detect_mime_type(file)
|
||||
);
|
||||
}
|
||||
|
||||
// 签名URL生成(演示,不会实际调用OSS)
|
||||
println!("\\n=== Signed URL function demonstration ===");
|
||||
println!("Note: The following features require valid OSS credentials to work properly");
|
||||
|
||||
// 演示API调用(但不实际执行,因为可能没有有效凭证)
|
||||
println!("Available API methods:");
|
||||
println!(" - client.upload_file(local_path, object_key)");
|
||||
println!(" - client.upload_content(content, object_key, content_type)");
|
||||
println!(" - client.download_file(object_key, local_path)");
|
||||
println!(" - client.delete_file(object_key)");
|
||||
println!(" - client.file_exists(object_key)");
|
||||
println!(" - client.generate_upload_url(object_key, expires_in, content_type)");
|
||||
println!(" - client.generate_download_url(object_key, expires_in)");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
69
qiming-mcp-proxy/oss-client/examples/domain_replacement.rs
Normal file
69
qiming-mcp-proxy/oss-client/examples/domain_replacement.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
//! OSS域名替换示例
|
||||
//!
|
||||
//! 展示如何使用域名替换功能来解决跨域问题
|
||||
|
||||
use oss_client::{replace_oss_domain, replace_oss_domains_batch};
|
||||
|
||||
fn main() {
|
||||
println!("=== OSS domain name replacement example ===\\n");
|
||||
|
||||
// 示例1: 单个URL替换
|
||||
let original_url = "https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/image.jpg";
|
||||
let replaced_url = replace_oss_domain(original_url);
|
||||
|
||||
println!("Original URL: {original_url}");
|
||||
println!("After replacement: {replaced_url}\\n");
|
||||
|
||||
// 示例2: 带路径的URL替换
|
||||
let original_url_with_path =
|
||||
"https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/folder/subfolder/image.png";
|
||||
let replaced_url_with_path = replace_oss_domain(original_url_with_path);
|
||||
|
||||
println!("Original URL with path: {original_url_with_path}");
|
||||
println!("After replacement: {replaced_url_with_path}\\n");
|
||||
|
||||
// 示例3: 带查询参数的URL替换
|
||||
let original_url_with_query =
|
||||
"https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/image.jpg?version=1.0&size=large";
|
||||
let replaced_url_with_query = replace_oss_domain(original_url_with_query);
|
||||
|
||||
println!("Original URL with query parameters: {original_url_with_query}");
|
||||
println!("After replacement: {replaced_url_with_query}\\n");
|
||||
|
||||
// 示例4: 不匹配的域名保持不变
|
||||
let other_url = "https://other-domain.com/image.jpg";
|
||||
let unchanged_url = replace_oss_domain(other_url);
|
||||
|
||||
println!("Other domain name URL: {other_url}");
|
||||
println!("Remain unchanged: {unchanged_url}\\n");
|
||||
|
||||
// 示例5: 批量替换
|
||||
let urls = vec![
|
||||
"https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/image1.jpg".to_string(),
|
||||
"https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/image2.jpg".to_string(),
|
||||
"https://other-domain.com/image3.jpg".to_string(),
|
||||
"https://nuwa-packages.oss-rg-china-mainland.aliyuncs.com/folder/image4.png".to_string(),
|
||||
];
|
||||
|
||||
println!("URLs before batch replacement:");
|
||||
for (i, url) in urls.iter().enumerate() {
|
||||
println!(" {}: {}", i + 1, url);
|
||||
}
|
||||
|
||||
let replaced_urls = replace_oss_domains_batch(&urls);
|
||||
|
||||
println!("\\nURLs after batch replacement:");
|
||||
for (i, url) in replaced_urls.iter().enumerate() {
|
||||
println!(" {}: {}", i + 1, url);
|
||||
}
|
||||
|
||||
println!("\\n=== Usage scenario description ===");
|
||||
println!(
|
||||
"1. Solve the cross-domain problem: Replace the Alibaba Cloud OSS domain name with a custom domain name"
|
||||
);
|
||||
println!("2. Image preview: Normally display images stored in OSS on the web page");
|
||||
println!(
|
||||
"3. Batch processing: Process the domain name replacement of multiple URLs at one time"
|
||||
);
|
||||
println!("4. Maintain compatibility: Unmatched domain names remain unchanged");
|
||||
}
|
||||
143
qiming-mcp-proxy/oss-client/examples/signed_url.rs
Normal file
143
qiming-mcp-proxy/oss-client/examples/signed_url.rs
Normal file
@@ -0,0 +1,143 @@
|
||||
//! 签名URL使用示例
|
||||
|
||||
use oss_client::{OssClientTrait, PrivateOssClient};
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== Example of using OSS signed URL ===\\n");
|
||||
|
||||
// 从环境变量创建客户端
|
||||
|
||||
let oss_config = oss_client::OssConfig::new(
|
||||
oss_client::defaults::ENDPOINT.to_string(),
|
||||
oss_client::defaults::PUBLIC_BUCKET.to_string(),
|
||||
"demo_access_key_id".to_string(),
|
||||
"demo_access_key_secret".to_string(),
|
||||
oss_client::defaults::REGION.to_string(),
|
||||
oss_client::defaults::UPLOAD_DIRECTORY.to_string(),
|
||||
);
|
||||
let client = PrivateOssClient::new(oss_config);
|
||||
|
||||
match client {
|
||||
Ok(client) => {
|
||||
println!("✓ OSS client created successfully");
|
||||
println!("Base URL: {}\\n", client.get_base_url());
|
||||
|
||||
// 演示签名URL生成
|
||||
demonstrate_signed_urls(&client)?;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✗ Failed to create OSS client: {e}");
|
||||
println!("Please set the following environment variables:");
|
||||
println!(" export OSS_ACCESS_KEY_ID=\"your_access_key_id\"");
|
||||
println!(" export OSS_ACCESS_KEY_SECRET=\"your_access_key_secret\"");
|
||||
println!("\\nContinue with demo configuration...\\n");
|
||||
|
||||
// 使用演示配置(显式提供全部参数)
|
||||
let config = oss_client::OssConfig::new(
|
||||
oss_client::defaults::ENDPOINT.to_string(),
|
||||
oss_client::defaults::PUBLIC_BUCKET.to_string(),
|
||||
"demo_access_key_id".to_string(),
|
||||
"demo_access_key_secret".to_string(),
|
||||
oss_client::defaults::REGION.to_string(),
|
||||
oss_client::defaults::UPLOAD_DIRECTORY.to_string(),
|
||||
);
|
||||
let client = PrivateOssClient::new(config)?;
|
||||
demonstrate_signed_urls(&client)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn demonstrate_signed_urls(client: &dyn OssClientTrait) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== Signed URL generation demo ===");
|
||||
|
||||
// 生成上传签名URL
|
||||
println!("1. Generate upload signature URL");
|
||||
let object_key = "uploads/document.pdf";
|
||||
let expires_in = Duration::from_secs(4 * 3600); // 4小时有效
|
||||
|
||||
println!("Object key: {object_key}");
|
||||
println!("Validity period: {} hours", expires_in.as_secs() / 3600);
|
||||
println!("Content type: application/pdf");
|
||||
|
||||
match client.generate_upload_url(object_key, expires_in, Some("application/pdf")) {
|
||||
Ok(upload_url) => {
|
||||
println!("✓ Upload URL generated successfully:");
|
||||
println!(" {upload_url}");
|
||||
println!("How to use:");
|
||||
println!(" curl -X PUT \"{upload_url}\" \\");
|
||||
println!(" -H \"Content-Type: application/pdf\" \\");
|
||||
println!(" --data-binary @local_file.pdf");
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✗ Failed to generate upload URL: {e}");
|
||||
println!("NOTE: Valid OSS credentials are required to generate signed URLs");
|
||||
}
|
||||
}
|
||||
|
||||
println!();
|
||||
|
||||
// 生成下载签名URL(4小时有效)
|
||||
println!("2. Generate download signature URL (valid for 4 hours)");
|
||||
match client.generate_download_url(object_key, Some(expires_in)) {
|
||||
Ok(download_url) => {
|
||||
println!("✓ Download URL generated successfully:");
|
||||
println!(" {download_url}");
|
||||
println!("How to use:");
|
||||
println!(" curl \"{download_url}\" -o downloaded_file.pdf");
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✗ Download URL generation failed: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
println!();
|
||||
|
||||
// 生成永久下载URL(实际上是4小时有效,因为我们的实现中没有真正的永久URL)
|
||||
println!("3. Generate download signature URL (valid for 1 hour by default)");
|
||||
match client.generate_download_url(object_key, None) {
|
||||
Ok(download_url) => {
|
||||
println!("✓ Download URL generated successfully:");
|
||||
println!(" {download_url}");
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✗ Download URL generation failed: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
println!();
|
||||
|
||||
// 演示不同文件类型的上传URL
|
||||
println!("4. Upload URLs for different file types");
|
||||
let file_examples = vec![
|
||||
("uploads/image.jpg", "image/jpeg"),
|
||||
(
|
||||
"uploads/document.docx",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
),
|
||||
("uploads/data.json", "application/json"),
|
||||
("uploads/video.mp4", "video/mp4"),
|
||||
];
|
||||
|
||||
for (key, content_type) in file_examples {
|
||||
println!("File: {key} ({content_type})");
|
||||
match client.generate_upload_url(key, Duration::from_secs(3600), Some(content_type)) {
|
||||
Ok(url) => println!(" ✓ URL: {url}"),
|
||||
Err(e) => println!("✗ Failure: {e}"),
|
||||
}
|
||||
}
|
||||
|
||||
println!("\\n=== Usage Tips ===");
|
||||
println!(
|
||||
"1. Uploading a signed URL allows the client to directly upload files to OSS without exposing the access key."
|
||||
);
|
||||
println!("2. Downloading signed URLs allows temporary access to private files");
|
||||
println!("3. The signed URL is time-sensitive and needs to be regenerated after expiration.");
|
||||
println!(
|
||||
"4. In a production environment, it is recommended to set an appropriate expiration time based on actual needs."
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
122
qiming-mcp-proxy/oss-client/examples/trait_usage.rs
Normal file
122
qiming-mcp-proxy/oss-client/examples/trait_usage.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
//! 展示如何使用统一的 OssClientTrait 接口
|
||||
//!
|
||||
//! 这个示例展示了如何通过 trait 接口统一使用私有bucket和公有bucket客户端
|
||||
|
||||
use oss_client::{OssClientTrait, OssConfig, PrivateOssClient, PublicOssClient};
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("=== Example of using the OSS client unified interface ===\\n");
|
||||
|
||||
// 创建配置
|
||||
let config = OssConfig::new(
|
||||
oss_client::defaults::ENDPOINT.to_string(),
|
||||
oss_client::defaults::PUBLIC_BUCKET.to_string(),
|
||||
"your_access_key_id".to_string(),
|
||||
"your_access_key_secret".to_string(),
|
||||
oss_client::defaults::REGION.to_string(),
|
||||
oss_client::defaults::UPLOAD_DIRECTORY.to_string(),
|
||||
);
|
||||
|
||||
// 创建两个客户端
|
||||
let private_client = PrivateOssClient::new(config.clone())?;
|
||||
let public_client = PublicOssClient::new(config.clone())?;
|
||||
|
||||
println!("1. Use private bucket client through unified interface:");
|
||||
demonstrate_client_usage(&private_client, "私有bucket").await?;
|
||||
|
||||
println!("\\n2. Use the public bucket client through the unified interface:");
|
||||
demonstrate_client_usage(&public_client, "公有bucket").await?;
|
||||
|
||||
println!("\\n3. Examples of polymorphic usage:");
|
||||
demonstrate_polymorphic_usage(&private_client, &public_client).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 演示客户端的基本使用
|
||||
async fn demonstrate_client_usage(
|
||||
client: &dyn OssClientTrait,
|
||||
client_type: &str,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Client type: {client_type}");
|
||||
println!("Configuration information: {:?}", client.get_config());
|
||||
println!("Base URL: {}", client.get_base_url());
|
||||
|
||||
// 生成上传签名URL
|
||||
let expires_in = Duration::from_secs(3600); // 1小时
|
||||
match client.generate_upload_url("documents/test.pdf", expires_in, Some("application/pdf")) {
|
||||
Ok(url) => println!("Upload signature URL: {url}"),
|
||||
Err(e) => println!("Failed to generate upload signature URL: {e}"),
|
||||
}
|
||||
|
||||
// 生成下载签名URL
|
||||
match client.generate_download_url("documents/test.pdf", Some(expires_in)) {
|
||||
Ok(url) => println!("Download signature URL: {url}"),
|
||||
Err(e) => println!("Failed to generate download signature URL: {e}"),
|
||||
}
|
||||
|
||||
// 生成唯一对象键
|
||||
let object_key = client.generate_object_key("documents", Some("manual.pdf"));
|
||||
println!("Generated object key: {object_key}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 演示多态使用
|
||||
async fn demonstrate_polymorphic_usage(
|
||||
private_client: &dyn OssClientTrait,
|
||||
public_client: &dyn OssClientTrait,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Polymorphic use - can handle different types of clients uniformly");
|
||||
|
||||
// 创建一个客户端列表
|
||||
let clients: Vec<&dyn OssClientTrait> = vec![private_client, public_client];
|
||||
|
||||
for (i, client) in clients.iter().enumerate() {
|
||||
println!("Client {}: {}", i + 1, client.get_base_url());
|
||||
|
||||
// 所有客户端都实现了相同的接口
|
||||
let object_key = client.generate_object_key("test", Some("file.txt"));
|
||||
println!("Generated object key: {object_key}");
|
||||
|
||||
// 测试连接(需要实际的OSS权限)
|
||||
println!("Test connection...");
|
||||
match client.test_connection().await {
|
||||
Ok(_) => println!("✅Connected successfully"),
|
||||
Err(e) => println!("❌ Connection failed: {e}"),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 通用的文件操作函数,接受任何实现了 OssClientTrait 的客户端
|
||||
async fn upload_file_generic(
|
||||
client: &dyn OssClientTrait,
|
||||
local_path: &str,
|
||||
object_key: &str,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
println!("Use the common interface to upload files: {local_path} -> {object_key}");
|
||||
|
||||
// 通过 trait 接口调用上传方法
|
||||
let url = client.upload_file(local_path, object_key).await?;
|
||||
println!("Upload successful, file URL: {url}");
|
||||
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
/// 通用的文件删除函数
|
||||
async fn delete_file_generic(
|
||||
client: &dyn OssClientTrait,
|
||||
object_key: &str,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Delete files using common interface: {object_key}");
|
||||
|
||||
// 通过 trait 接口调用删除方法
|
||||
client.delete_file(object_key).await?;
|
||||
println!("Delete successfully");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user