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