Line data Source code
1 : use std::sync::Arc;
2 :
3 : use axum::extract::State;
4 : use axum::response::{IntoResponse, Response};
5 : use http::StatusCode;
6 : use serde::Deserialize;
7 :
8 : use crate::compute::ComputeNode;
9 : use crate::http::JsonResponse;
10 : use crate::http::extract::{Path, Query};
11 :
12 0 : #[derive(Debug, Clone, Deserialize)]
13 : pub(in crate::http) struct ExtensionServerParams {
14 : #[serde(default)]
15 : is_library: bool,
16 : }
17 :
18 : /// Download a remote extension.
19 0 : pub(in crate::http) async fn download_extension(
20 0 : Path(filename): Path<String>,
21 0 : ext_server_params: Query<ExtensionServerParams>,
22 0 : State(compute): State<Arc<ComputeNode>>,
23 0 : ) -> Response {
24 0 : // Don't even try to download extensions if no remote storage is configured
25 0 : if compute.params.ext_remote_storage.is_none() {
26 0 : return JsonResponse::error(
27 0 : StatusCode::PRECONDITION_FAILED,
28 0 : "remote storage is not configured",
29 0 : );
30 0 : }
31 :
32 0 : let ext = {
33 0 : let state = compute.state.lock().unwrap();
34 0 : let pspec = state.pspec.as_ref().unwrap();
35 0 : let spec = &pspec.spec;
36 :
37 0 : let remote_extensions = match spec.remote_extensions.as_ref() {
38 0 : Some(r) => r,
39 : None => {
40 0 : return JsonResponse::error(
41 0 : StatusCode::CONFLICT,
42 0 : "information about remote extensions is unavailable",
43 0 : );
44 : }
45 : };
46 :
47 0 : remote_extensions.get_ext(
48 0 : &filename,
49 0 : ext_server_params.is_library,
50 0 : &compute.params.build_tag,
51 0 : &compute.params.pgversion,
52 0 : )
53 0 : };
54 0 :
55 0 : match ext {
56 0 : Ok((ext_name, ext_path)) => match compute.download_extension(ext_name, ext_path).await {
57 0 : Ok(_) => StatusCode::OK.into_response(),
58 0 : Err(e) => JsonResponse::error(StatusCode::INTERNAL_SERVER_ERROR, e),
59 : },
60 0 : Err(e) => JsonResponse::error(StatusCode::NOT_FOUND, e),
61 : }
62 0 : }
|