Skip to content

Commit f858835

Browse files
chore(sourcemaps): Remove support for non-chunked uploads (#2957)
### Description Remove support for non-chunked sourcemaps uploads. ### Issues - Resolves #2949 - Resolves [CLI-226](https://linear.app/getsentry/issue/CLI-226/remove-support-for-non-chunked-sourcemap-uploads)
1 parent 96e19ab commit f858835

File tree

3 files changed

+6
-488
lines changed

3 files changed

+6
-488
lines changed

src/api/mod.rs

Lines changed: 2 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ mod pagination;
1414
use std::borrow::Cow;
1515
use std::cell::RefCell;
1616
use std::collections::HashMap;
17-
use std::ffi::OsStr;
1817
use std::fs::File;
1918
use std::io::{self, Read as _, Write};
20-
use std::path::Path;
2119
use std::rc::Rc;
2220
use std::sync::Arc;
2321
use std::{fmt, thread};
@@ -46,8 +44,7 @@ use uuid::Uuid;
4644

4745
use crate::api::errors::{ProjectRenamedError, RetryError};
4846
use crate::config::{Auth, Config};
49-
use crate::constants::{ARCH, DEFAULT_URL, EXT, PLATFORM, RELEASE_REGISTRY_LATEST_URL, VERSION};
50-
use crate::utils::file_upload::LegacyUploadContext;
47+
use crate::constants::{ARCH, EXT, PLATFORM, RELEASE_REGISTRY_LATEST_URL, VERSION};
5148
use crate::utils::http::{self, is_absolute_url};
5249
use crate::utils::non_empty::NonEmptySlice;
5350
use crate::utils::progress::{ProgressBar, ProgressBarMode};
@@ -87,11 +84,6 @@ pub struct AuthenticatedApi<'a> {
8784
api: &'a Api,
8885
}
8986

90-
pub struct RegionSpecificApi<'a> {
91-
api: &'a AuthenticatedApi<'a>,
92-
region_url: Option<Box<str>>,
93-
}
94-
9587
/// Represents an HTTP method that is used by the API.
9688
#[derive(Eq, PartialEq, Debug)]
9789
pub enum Method {
@@ -446,7 +438,7 @@ impl Api {
446438
}
447439
}
448440

449-
impl<'a> AuthenticatedApi<'a> {
441+
impl AuthenticatedApi<'_> {
450442
// Pass through low-level methods to API.
451443

452444
/// Convenience method to call self.api.get.
@@ -482,110 +474,6 @@ impl<'a> AuthenticatedApi<'a> {
482474
self.get("/")?.convert()
483475
}
484476

485-
/// Lists release files for the given `release`, filtered by a set of checksums.
486-
/// When empty checksums list is provided, fetches all possible artifacts.
487-
pub fn list_release_files_by_checksum(
488-
&self,
489-
org: &str,
490-
project: Option<&str>,
491-
release: &str,
492-
checksums: &[String],
493-
) -> ApiResult<Vec<Artifact>> {
494-
let mut rv = vec![];
495-
let mut cursor = "".to_owned();
496-
loop {
497-
let mut path = if let Some(project) = project {
498-
format!(
499-
"/projects/{}/{}/releases/{}/files/?cursor={}",
500-
PathArg(org),
501-
PathArg(project),
502-
PathArg(release),
503-
QueryArg(&cursor),
504-
)
505-
} else {
506-
format!(
507-
"/organizations/{}/releases/{}/files/?cursor={}",
508-
PathArg(org),
509-
PathArg(release),
510-
QueryArg(&cursor),
511-
)
512-
};
513-
514-
let mut checksums_qs = String::new();
515-
for checksum in checksums.iter() {
516-
checksums_qs.push_str(&format!("&checksum={}", QueryArg(checksum)));
517-
}
518-
// We have a 16kb buffer for reach request configured in nginx,
519-
// so do not even bother trying if it's too long.
520-
// (16_384 limit still leaves us with 384 bytes for the url itself).
521-
if !checksums_qs.is_empty() && checksums_qs.len() <= 16_000 {
522-
path.push_str(&checksums_qs);
523-
}
524-
525-
let resp = self.get(&path)?;
526-
if resp.status() == 404 || (resp.status() == 400 && !cursor.is_empty()) {
527-
if rv.is_empty() {
528-
return Err(ApiErrorKind::ReleaseNotFound.into());
529-
} else {
530-
break;
531-
}
532-
}
533-
534-
let pagination = resp.pagination();
535-
rv.extend(resp.convert::<Vec<Artifact>>()?);
536-
if let Some(next) = pagination.into_next_cursor() {
537-
cursor = next;
538-
} else {
539-
break;
540-
}
541-
}
542-
Ok(rv)
543-
}
544-
545-
/// Lists all the release files for the given `release`.
546-
pub fn list_release_files(
547-
&self,
548-
org: &str,
549-
project: Option<&str>,
550-
release: &str,
551-
) -> ApiResult<Vec<Artifact>> {
552-
self.list_release_files_by_checksum(org, project, release, &[])
553-
}
554-
555-
/// Deletes a single release file. Returns `true` if the file was
556-
/// deleted or `false` otherwise.
557-
pub fn delete_release_file(
558-
&self,
559-
org: &str,
560-
project: Option<&str>,
561-
version: &str,
562-
file_id: &str,
563-
) -> ApiResult<bool> {
564-
let path = if let Some(project) = project {
565-
format!(
566-
"/projects/{}/{}/releases/{}/files/{}/",
567-
PathArg(org),
568-
PathArg(project),
569-
PathArg(version),
570-
PathArg(file_id)
571-
)
572-
} else {
573-
format!(
574-
"/organizations/{}/releases/{}/files/{}/",
575-
PathArg(org),
576-
PathArg(version),
577-
PathArg(file_id)
578-
)
579-
};
580-
581-
let resp = self.delete(&path)?;
582-
if resp.status() == 404 {
583-
Ok(false)
584-
} else {
585-
resp.into_result().map(|_| true)
586-
}
587-
}
588-
589477
/// Creates a new release.
590478
pub fn new_release(&self, org: &str, release: &NewRelease) -> ApiResult<ReleaseInfo> {
591479
// for single project releases use the legacy endpoint that is project bound.
@@ -1181,50 +1069,6 @@ impl<'a> AuthenticatedApi<'a> {
11811069
}
11821070
Ok(rv)
11831071
}
1184-
1185-
fn get_region_url(&self, org: &str) -> ApiResult<String> {
1186-
self.get(&format!("/organizations/{org}/region/"))
1187-
.and_then(|resp| resp.convert::<Region>())
1188-
.map(|region| region.url)
1189-
}
1190-
1191-
pub fn region_specific(&'a self, org: &'a str) -> RegionSpecificApi<'a> {
1192-
let base_url = self.api.config.get_base_url();
1193-
if base_url.is_err()
1194-
|| base_url.expect("base_url should not be error") != DEFAULT_URL.trim_end_matches('/')
1195-
{
1196-
// Do not specify a region URL unless the URL is configured to https://sentry.io (i.e. the default).
1197-
return RegionSpecificApi {
1198-
api: self,
1199-
region_url: None,
1200-
};
1201-
}
1202-
1203-
let region_url = match self
1204-
.api
1205-
.config
1206-
.get_auth()
1207-
.expect("auth should not be None for authenticated API!")
1208-
{
1209-
Auth::Token(token) => match token.payload() {
1210-
Some(payload) => Some(payload.region_url.clone().into()),
1211-
None => {
1212-
let region_url = self.get_region_url(org);
1213-
if let Err(err) = &region_url {
1214-
log::warn!("Failed to get region URL due to following error: {err}");
1215-
log::info!("Failling back to the default region.");
1216-
}
1217-
1218-
region_url.ok().map(|url| url.into())
1219-
}
1220-
},
1221-
};
1222-
1223-
RegionSpecificApi {
1224-
api: self,
1225-
region_url,
1226-
}
1227-
}
12281072
}
12291073

12301074
/// Available datasets for fetching organization events
@@ -1298,73 +1142,6 @@ impl FetchEventsOptions<'_> {
12981142
}
12991143
}
13001144

1301-
impl RegionSpecificApi<'_> {
1302-
fn request(&self, method: Method, url: &str) -> ApiResult<ApiRequest> {
1303-
self.api
1304-
.api
1305-
.request(method, url, self.region_url.as_deref())
1306-
}
1307-
1308-
/// Uploads a new release file. The file is loaded directly from the file
1309-
/// system and uploaded as `name`.
1310-
pub fn upload_release_file(
1311-
&self,
1312-
context: &LegacyUploadContext,
1313-
contents: &[u8],
1314-
name: &str,
1315-
headers: Option<&[(String, String)]>,
1316-
progress_bar_mode: ProgressBarMode,
1317-
) -> ApiResult<Option<Artifact>> {
1318-
let path = if let Some(project) = context.project() {
1319-
format!(
1320-
"/projects/{}/{}/releases/{}/files/",
1321-
PathArg(context.org()),
1322-
PathArg(project),
1323-
PathArg(context.release())
1324-
)
1325-
} else {
1326-
format!(
1327-
"/organizations/{}/releases/{}/files/",
1328-
PathArg(context.org()),
1329-
PathArg(context.release())
1330-
)
1331-
};
1332-
1333-
let mut form = curl::easy::Form::new();
1334-
1335-
let filename = Path::new(name)
1336-
.file_name()
1337-
.and_then(OsStr::to_str)
1338-
.unwrap_or("unknown.bin");
1339-
form.part("file")
1340-
.buffer(filename, contents.to_vec())
1341-
.add()?;
1342-
form.part("name").contents(name.as_bytes()).add()?;
1343-
if let Some(dist) = context.dist() {
1344-
form.part("dist").contents(dist.as_bytes()).add()?;
1345-
}
1346-
1347-
if let Some(headers) = headers {
1348-
for (key, value) in headers {
1349-
form.part("header")
1350-
.contents(format!("{key}:{value}").as_bytes())
1351-
.add()?;
1352-
}
1353-
}
1354-
1355-
let resp = self
1356-
.request(Method::Post, &path)?
1357-
.with_form_data(form)?
1358-
.progress_bar_mode(progress_bar_mode)
1359-
.send()?;
1360-
if resp.status() == 409 {
1361-
Ok(None)
1362-
} else {
1363-
resp.convert_rnf(ApiErrorKind::ReleaseNotFound)
1364-
}
1365-
}
1366-
}
1367-
13681145
fn send_req<W: Write>(
13691146
handle: &mut curl::easy::Easy,
13701147
out: &mut W,
@@ -1858,14 +1635,6 @@ pub struct AuthInfo {
18581635
pub user: Option<User>,
18591636
}
18601637

1861-
/// A release artifact
1862-
#[derive(Clone, Deserialize, Debug)]
1863-
pub struct Artifact {
1864-
pub id: String,
1865-
pub name: String,
1866-
pub dist: Option<String>,
1867-
}
1868-
18691638
/// Information for new releases
18701639
#[derive(Debug, Serialize, Default)]
18711640
pub struct NewRelease {

src/utils/auth_token/org_auth_token.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub struct OrgAuthToken {
1414
/// Represents the payload data of an org auth token.
1515
#[derive(Clone, Debug, Deserialize)]
1616
pub struct AuthTokenPayload {
17-
pub region_url: String,
1817
pub org: String,
1918

2019
// URL may be missing from some old auth tokens, see getsentry/sentry#57123

0 commit comments

Comments
 (0)