git_http_backend/actix/
objects_info_packs.rs

1use 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}