-
I have a service serving files from AWS S3. I can now stream files from S3 to the client. But the problem is when the client disconnects. The handler is still running (By checking the CPU usage, it's still around 60%.). What I want is when the client disconnects. I want it to cancel the stream. Here is my code sample. use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
use aws_sdk_s3::{config, Client, Credentials, Endpoint, Region};
use http::Uri;
// -- constants
const REGION: &str = "ap-southeast-1";
const ENDPOINT_URL: &str = "http://localhost:9000";
const ACCESS_KEY_ID: &str = "user";
const SECRET_ACCESS_KEY: &str = "password";
const BUCKET_NAME: &str = "test";
const OBJECT_KEY: &str = "test.txt";
struct Context {
s3_client: Client,
}
fn get_aws_client() -> Client {
// build the aws cred
let cred = Credentials::new(ACCESS_KEY_ID, SECRET_ACCESS_KEY, None, None, "static");
// build the aws client
let region = Region::new(REGION);
let endpoint = Endpoint::immutable(Uri::from_static(ENDPOINT_URL));
let conf_builder = config::Builder::new()
.region(region)
.endpoint_resolver(endpoint)
.credentials_provider(cred);
let conf = conf_builder.build();
// build aws client
let client = Client::from_conf(conf);
return client;
}
#[get("/")]
async fn file(ctx: web::Data<Context>) -> impl Responder {
let result = ctx
.s3_client
.get_object()
.bucket(BUCKET_NAME)
.key(OBJECT_KEY)
.send()
.await;
if result.is_err() {
let sdk_error = result.unwrap_err();
match sdk_error {
aws_sdk_s3::types::SdkError::ServiceError { err, .. } if err.is_no_such_key() => {
return HttpResponse::NotFound().finish();
}
_ => {
eprintln!("{}", sdk_error);
return HttpResponse::InternalServerError().finish();
}
}
}
let stream = result.unwrap().body;
return HttpResponse::Ok()
.insert_header(("Content-Disposition", "attachment; filename=\"test.txt\""))
.streaming(stream);
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let s3_client = get_aws_client();
let context = web::Data::new(Context { s3_client });
HttpServer::new(move || App::new().app_data(context.clone()).service(file))
.bind(("0.0.0.0", 4000))?
.run()
.await
} |
Beta Was this translation helpful? Give feedback.
Answered by
robjtede
Sep 11, 2022
Replies: 1 comment 2 replies
-
I will try to reproduce with the sample code provided. How are you testing this behavior (eg: |
Beta Was this translation helpful? Give feedback.
2 replies
Answer selected by
vimutti77
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I will try to reproduce with the sample code provided. How are you testing this behavior (eg:
curl
/browser
/postman
)?