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 : #[serde(default)]
21 : is_library: bool,
22 : }
23 :
24 : /// Download a remote extension.
25 0 : pub(in crate::http) async fn download_extension(
26 0 : Path(filename): Path<String>,
27 0 : params: Query<ExtensionServerParams>,
28 0 : State(compute): State<Arc<ComputeNode>>,
29 0 : ) -> Response {
30 0 : // Don't even try to download extensions if no remote storage is configured
31 0 : if compute.ext_remote_storage.is_none() {
32 0 : return JsonResponse::error(
33 0 : StatusCode::PRECONDITION_FAILED,
34 0 : "remote storage is not configured",
35 0 : );
36 0 : }
37 :
38 0 : let ext = {
39 0 : let state = compute.state.lock().unwrap();
40 0 : let pspec = state.pspec.as_ref().unwrap();
41 0 : let spec = &pspec.spec;
42 :
43 0 : let remote_extensions = match spec.remote_extensions.as_ref() {
44 0 : Some(r) => r,
45 : None => {
46 0 : return JsonResponse::error(
47 0 : StatusCode::CONFLICT,
48 0 : "information about remote extensions is unavailable",
49 0 : );
50 : }
51 : };
52 :
53 0 : remote_extensions.get_ext(
54 0 : &filename,
55 0 : params.is_library,
56 0 : &compute.build_tag,
57 0 : &compute.pgversion,
58 0 : )
59 0 : };
60 0 :
61 0 : match ext {
62 0 : Ok((ext_name, ext_path)) => match compute.download_extension(ext_name, ext_path).await {
63 0 : Ok(_) => StatusCode::OK.into_response(),
64 0 : Err(e) => JsonResponse::error(StatusCode::INTERNAL_SERVER_ERROR, e),
65 : },
66 0 : Err(e) => JsonResponse::error(StatusCode::NOT_FOUND, e),
67 : }
68 0 : }
|