1
0
mirror of https://github.com/actix/examples synced 2024-12-03 18:22:14 +01:00

fix: demonstrate HEAD responses

This commit is contained in:
Rob Ede 2024-07-04 15:14:22 +01:00
parent e838c8f494
commit 10aff3cdb1
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933

View File

@ -1,14 +1,21 @@
use std::fs; use std::{fs, io};
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
use actix_web::{ use actix_web::{
body::SizedStream, delete, error, get, middleware::Logger, post, web, App, Error, HttpResponse, body::SizedStream,
HttpServer, Responder, delete, error, get,
http::Method,
middleware::Logger,
post, route,
web::{self},
App, Error, HttpResponse, HttpServer, Responder,
}; };
use actix_web_lab::{extract::Path, respond::Html}; use actix_web_lab::{extract::Path, respond::Html};
use aws_config::{meta::region::RegionProviderChain, BehaviorVersion}; use aws_config::{meta::region::RegionProviderChain, BehaviorVersion};
use dotenvy::dotenv; use dotenvy::dotenv;
use futures_util::{stream, StreamExt as _};
use serde_json::json; use serde_json::json;
use tokio_util::io::ReaderStream;
mod client; mod client;
mod upload_file; mod upload_file;
@ -46,9 +53,10 @@ async fn upload_to_s3(
}))) })))
} }
#[get("/file/{s3_key}*")] #[route("/file/{s3_key}*", method = "GET", method = "HEAD")]
async fn fetch_from_s3( async fn fetch_from_s3(
s3_client: web::Data<Client>, s3_client: web::Data<Client>,
method: Method,
Path((s3_key,)): Path<(String,)>, Path((s3_key,)): Path<(String,)>,
) -> Result<impl Responder, Error> { ) -> Result<impl Responder, Error> {
let (file_size, file_stream) = s3_client let (file_size, file_stream) = s3_client
@ -56,10 +64,19 @@ async fn fetch_from_s3(
.await .await
.ok_or_else(|| error::ErrorNotFound("file with specified key not found"))?; .ok_or_else(|| error::ErrorNotFound("file with specified key not found"))?;
Ok(HttpResponse::Ok().body(SizedStream::new( let stream = match method {
file_size, // data stream for GET requests
tokio_util::io::ReaderStream::new(file_stream.into_async_read()), Method::GET => ReaderStream::new(file_stream.into_async_read()).boxed_local(),
)))
// empty stream for HEAD requests
Method::HEAD => stream::empty::<Result<_, io::Error>>().boxed_local(),
_ => unreachable!(),
};
Ok(HttpResponse::Ok()
.no_chunking(file_size)
.body(SizedStream::new(file_size, stream)))
} }
#[delete("/file/{s3_key}*")] #[delete("/file/{s3_key}*")]
@ -104,12 +121,12 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(move || { HttpServer::new(move || {
App::new() App::new()
.app_data(web::Data::new(s3_client.clone()))
.service(index) .service(index)
.service(upload_to_s3) .service(upload_to_s3)
.service(fetch_from_s3) .service(fetch_from_s3)
.service(delete_from_s3) .service(delete_from_s3)
.wrap(Logger::default()) .wrap(Logger::default())
.app_data(web::Data::new(s3_client.clone()))
}) })
.workers(2) .workers(2)
.bind(("127.0.0.1", 8080))? .bind(("127.0.0.1", 8080))?