feat(registry): move to body bytes over multipart for uploading

This commit is contained in:
daimond113 2024-11-11 13:21:47 +01:00
parent 19aa5eb52c
commit b180bea063
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
7 changed files with 29 additions and 111 deletions

71
Cargo.lock generated
View file

@ -95,44 +95,6 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "actix-multipart"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5118a26dee7e34e894f7e85aa0ee5080ae4c18bf03c0e30d49a80e418f00a53"
dependencies = [
"actix-multipart-derive",
"actix-utils",
"actix-web",
"derive_more 0.99.18",
"futures-core",
"futures-util",
"httparse",
"local-waker",
"log",
"memchr",
"mime",
"rand",
"serde",
"serde_json",
"serde_plain",
"tempfile",
"tokio",
]
[[package]]
name = "actix-multipart-derive"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e11eb847f49a700678ea2fa73daeb3208061afa2b9d1a8527c03390f4c4a1c6b"
dependencies = [
"darling",
"parse-size",
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "actix-router" name = "actix-router"
version = "0.5.3" version = "0.5.3"
@ -3313,16 +3275,6 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@ -3667,12 +3619,6 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "parse-size"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.15" version = "1.0.15"
@ -3741,7 +3687,6 @@ version = "0.7.0"
dependencies = [ dependencies = [
"actix-cors", "actix-cors",
"actix-governor", "actix-governor",
"actix-multipart",
"actix-web", "actix-web",
"async-compression", "async-compression",
"async-stream", "async-stream",
@ -4147,7 +4092,6 @@ dependencies = [
"js-sys", "js-sys",
"log", "log",
"mime", "mime",
"mime_guess",
"native-tls", "native-tls",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
@ -4552,15 +4496,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_plain"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "serde_repr" name = "serde_repr"
version = "0.1.19" version = "0.1.19"
@ -5325,12 +5260,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "unicase"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df"
[[package]] [[package]]
name = "unicode-bom" name = "unicode-bom"
version = "2.0.3" version = "2.0.3"

View file

@ -15,7 +15,6 @@ bin = [
"dirs", "dirs",
"pretty_env_logger", "pretty_env_logger",
"reqwest/json", "reqwest/json",
"reqwest/multipart",
"indicatif", "indicatif",
"indicatif-log-bridge", "indicatif-log-bridge",
"inquire", "inquire",

View file

@ -7,7 +7,6 @@ publish = false
[dependencies] [dependencies]
actix-web = "4.9.0" actix-web = "4.9.0"
actix-multipart = "0.7.2"
actix-cors = "0.7.0" actix-cors = "0.7.0"
actix-governor = "0.7.0" actix-governor = "0.7.0"
dotenvy = "0.15.7" dotenvy = "0.15.7"

View file

@ -157,7 +157,7 @@ pub async fn read_mw(
next.call(req).await.map(|res| res.map_into_left_body()) next.call(req).await.map(|res| res.map_into_left_body())
} }
pub fn get_auth_from_env(config: IndexConfig) -> Auth { pub fn get_auth_from_env(config: &IndexConfig) -> Auth {
if let Ok(token) = benv!("ACCESS_TOKEN") { if let Ok(token) = benv!("ACCESS_TOKEN") {
Auth::Token(token::TokenAuth { Auth::Token(token::TokenAuth {
token: *Sha256::digest(token.as_bytes()).as_ref(), token: *Sha256::digest(token.as_bytes()).as_ref(),
@ -167,6 +167,7 @@ pub fn get_auth_from_env(config: IndexConfig) -> Auth {
reqwest_client: make_reqwest(), reqwest_client: make_reqwest(),
client_id: config client_id: config
.github_oauth_client_id .github_oauth_client_id
.clone()
.expect("index isn't configured for GitHub"), .expect("index isn't configured for GitHub"),
client_secret, client_secret,
}) })

View file

@ -6,12 +6,11 @@ use crate::{
storage::StorageImpl, storage::StorageImpl,
AppState, AppState,
}; };
use actix_multipart::Multipart; use actix_web::{web, web::Bytes, HttpResponse, Responder};
use actix_web::{web, HttpResponse, Responder};
use async_compression::Level; use async_compression::Level;
use convert_case::{Case, Casing}; use convert_case::{Case, Casing};
use fs_err::tokio as fs; use fs_err::tokio as fs;
use futures::{future::join_all, join, StreamExt}; use futures::{future::join_all, join};
use git2::{Remote, Repository, Signature}; use git2::{Remote, Repository, Signature};
use pesde::{ use pesde::{
manifest::Manifest, manifest::Manifest,
@ -69,23 +68,13 @@ struct DocEntryInfo {
pub async fn publish_package( pub async fn publish_package(
app_state: web::Data<AppState>, app_state: web::Data<AppState>,
mut body: Multipart, bytes: Bytes,
user_id: web::ReqData<UserId>, user_id: web::ReqData<UserId>,
) -> Result<impl Responder, Error> { ) -> Result<impl Responder, Error> {
let source = app_state.source.lock().await; let source = app_state.source.lock().await;
source.refresh(&app_state.project).await.map_err(Box::new)?; source.refresh(&app_state.project).await.map_err(Box::new)?;
let config = source.config(&app_state.project).await?; let config = source.config(&app_state.project).await?;
let bytes = body
.next()
.await
.ok_or(Error::InvalidArchive)?
.map_err(|_| Error::InvalidArchive)?
.bytes(config.max_archive_size)
.await
.map_err(|_| Error::InvalidArchive)?
.map_err(|_| Error::InvalidArchive)?;
let package_dir = tempfile::tempdir()?; let package_dir = tempfile::tempdir()?;
{ {

View file

@ -1,9 +1,16 @@
use crate::{
auth::{get_auth_from_env, Auth, UserIdExtractor},
search::make_search,
storage::{get_storage_from_env, Storage},
};
use actix_cors::Cors; use actix_cors::Cors;
use actix_governor::{Governor, GovernorConfigBuilder}; use actix_governor::{Governor, GovernorConfigBuilder};
use actix_web::{ use actix_web::{
middleware::{from_fn, Compress, Logger, NormalizePath, TrailingSlash}, middleware::{from_fn, Compress, Logger, NormalizePath, TrailingSlash},
rt::System, rt::System,
web, App, HttpServer, web,
web::PayloadConfig,
App, HttpServer,
}; };
use fs_err::tokio as fs; use fs_err::tokio as fs;
use log::info; use log::info;
@ -13,12 +20,6 @@ use pesde::{
}; };
use std::{env::current_dir, path::PathBuf}; use std::{env::current_dir, path::PathBuf};
use crate::{
auth::{get_auth_from_env, Auth, UserIdExtractor},
search::make_search,
storage::{get_storage_from_env, Storage},
};
mod auth; mod auth;
mod endpoints; mod endpoints;
mod error; mod error;
@ -105,6 +106,10 @@ async fn run() -> std::io::Result<()> {
.refresh(&project) .refresh(&project)
.await .await
.expect("failed to refresh source"); .expect("failed to refresh source");
let config = source
.config(&project)
.await
.expect("failed to get index config");
let (search_reader, search_writer, query_parser) = make_search(&project, &source).await; let (search_reader, search_writer, query_parser) = make_search(&project, &source).await;
@ -115,12 +120,7 @@ async fn run() -> std::io::Result<()> {
storage storage
}, },
auth: { auth: {
let auth = get_auth_from_env( let auth = get_auth_from_env(&config);
source
.config(&project)
.await
.expect("failed to get index config"),
);
info!("auth: {auth}"); info!("auth: {auth}");
auth auth
}, },
@ -176,12 +176,16 @@ async fn run() -> std::io::Result<()> {
.to(endpoints::package_version::get_package_version) .to(endpoints::package_version::get_package_version)
.wrap(from_fn(auth::read_mw)), .wrap(from_fn(auth::read_mw)),
) )
.route( .service(
"/packages", web::scope("/packages")
web::post() .app_data(PayloadConfig::new(config.max_archive_size))
.to(endpoints::publish_version::publish_package) .route(
.wrap(Governor::new(&publish_governor_config)) "",
.wrap(from_fn(auth::write_mw)), web::post()
.to(endpoints::publish_version::publish_package)
.wrap(Governor::new(&publish_governor_config))
.wrap(from_fn(auth::write_mw)),
),
), ),
) )
}) })

View file

@ -530,10 +530,7 @@ impl PublishCommand {
let mut request = reqwest let mut request = reqwest
.post(format!("{}/v0/packages", config.api())) .post(format!("{}/v0/packages", config.api()))
.multipart(reqwest::multipart::Form::new().part( .body(archive);
"tarball",
reqwest::multipart::Part::bytes(archive).file_name("package.tar.gz"),
));
if let Some(token) = project.auth_config().tokens().get(index_url) { if let Some(token) = project.auth_config().tokens().get(index_url) {
log::debug!("using token for {index_url}"); log::debug!("using token for {index_url}");