git_http_backend/actix/
objects_info_packs.rs1use crate::GitConfig;
2use actix_files::NamedFile;
3use actix_web::cookie::time;
4use actix_web::cookie::time::format_description;
5use actix_web::http::header;
6use actix_web::http::header::HeaderValue;
7use actix_web::{web, HttpRequest, HttpResponse, Responder};
8use std::collections::HashMap;
9
10pub async fn objects_info_packs(
11 request: HttpRequest,
12 service: web::Data<impl GitConfig>,
13) -> impl Responder {
14 let uri = request.uri();
15 let path = uri.path().to_string();
16 let repo_path = service.rewrite(path).await;
17 let path = "objects/info/packs".to_string();
18 let mut map = HashMap::new();
19 let time = time::OffsetDateTime::now_utc();
20 let expires = time::OffsetDateTime::now_utc() + time::Duration::days(1);
21 map.insert(
22 "Date".to_string(),
23 time.format(&format_description::parse("%a, %d %b %Y %H:%M:%S GMT").unwrap())
24 .unwrap(),
25 );
26 map.insert(
27 "Expires".to_string(),
28 expires
29 .format(&format_description::parse("%a, %d %b %Y %H:%M:%S GMT").unwrap())
30 .unwrap(),
31 );
32 map.insert(
33 "Cache-Control".to_string(),
34 "public, max-age=86400".to_string(),
35 );
36 let req_file = repo_path.join(path);
37 if !req_file.exists() {
38 return HttpResponse::NotFound().body("File not found");
39 }
40 match NamedFile::open(req_file) {
41 Ok(mut named_file) => {
42 named_file = named_file.use_last_modified(true);
43 let mut response = named_file.into_response(&request);
44 for (k, v) in map.iter() {
45 response.headers_mut().insert(
46 k.to_string().parse().unwrap(),
47 HeaderValue::from_str(v).unwrap(),
48 );
49 }
50
51 response.headers_mut().insert(
52 header::CONTENT_TYPE,
53 HeaderValue::from_str("application/x-git-loose-object").unwrap(),
54 );
55 response
56 }
57 Err(_) => HttpResponse::InternalServerError().body("Failed to open file"),
58 }
59}