Skip to content

Commit c464a30

Browse files
feat(ide): avoid GET url length issues (#756)
## What problem are you trying to solve? See #754 for more details. Essentially, the problem we may encounter is URL length being a problem for some of the GET endpoints. ## What is your solution? Added a v2 version for some GET endpoints that were expecting a base64 representation of a file content as URL path. We also added a new version for the POST rulesets endpoint just because the naming was more convenient. ## Alternatives considered ## What the reviewer should know This is a continuation of #754 The idea is to remove the v1 endpoints in 6 months (or re-evaluate). IDE-4957
1 parent bd79c4c commit c464a30

File tree

4 files changed

+550
-28
lines changed

4 files changed

+550
-28
lines changed

crates/bins/src/bin/datadog_static_analyzer_server/ide/configuration_file/endpoints.rs

Lines changed: 146 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use std::path::PathBuf;
22

3+
use crate::datadog_static_analyzer_server::ide::configuration_file::models::{
4+
CanOnboardRequest, GetRulesetsRequest,
5+
};
6+
37
use super::error::ConfigFileError;
48
use super::models::{AddRuleSetsRequest, IgnoreRuleRequest};
59
use super::static_analysis_config_file::StaticAnalysisConfigFile;
@@ -9,13 +13,23 @@ use rocket::response::status::Custom;
913
use rocket::serde::json::Json;
1014
use tracing::instrument;
1115

16+
// TODO: Review DEPRECATED endpoints in 6 months from now: 2025-09-03
17+
// Considering if we want to support those endpoints for more than 6 months.
18+
// If not, feel free to remove them.
19+
20+
/// Ignores a rule in the static analysis configuration file.
21+
///
22+
/// # Arguments
23+
/// * `request` - The request containing the rule to ignore and the configuration file (base64).
1224
#[instrument()]
1325
#[rocket::post(
1426
"/v1/config/ignore-rule",
1527
format = "application/json",
1628
data = "<request>"
1729
)]
18-
pub fn ignore_rule(request: Json<IgnoreRuleRequest>) -> Result<String, Custom<ConfigFileError>> {
30+
pub fn post_ignore_rule(
31+
request: Json<IgnoreRuleRequest>,
32+
) -> Result<String, Custom<ConfigFileError>> {
1933
let IgnoreRuleRequest {
2034
rule,
2135
configuration_base64,
@@ -27,9 +41,110 @@ pub fn ignore_rule(request: Json<IgnoreRuleRequest>) -> Result<String, Custom<Co
2741
to_response_result(result, encoded)
2842
}
2943

44+
/// Checks if onboarding is allowed for the configuration file (deprecated).
45+
///
46+
/// # Deprecation
47+
/// Deprecated: Use [`post_can_onboard_v2`] instead.
48+
///
49+
/// # Arguments
50+
/// * `content` - The path to the configuration file.
51+
#[instrument()]
52+
#[rocket::get("/v1/config/can-onboard/<content..>")]
53+
pub fn get_can_onboard(content: PathBuf) -> Result<Json<bool>, Custom<ConfigFileError>> {
54+
let content_str = content.to_string_lossy().into_owned();
55+
can_onboard(content_str)
56+
}
57+
58+
/// Checks if onboarding is allowed for the configuration file (v2).
59+
///
60+
/// # Arguments
61+
/// * `request` - The request containing the configuration file (base64).
62+
#[instrument()]
63+
#[rocket::post(
64+
"/v2/config/can-onboard",
65+
format = "application/json",
66+
data = "<request>"
67+
)]
68+
pub fn post_can_onboard_v2(
69+
request: Json<CanOnboardRequest>,
70+
) -> Result<Json<bool>, Custom<ConfigFileError>> {
71+
let CanOnboardRequest {
72+
configuration_base64,
73+
..
74+
} = request.into_inner();
75+
can_onboard(configuration_base64)
76+
}
77+
78+
/// Gets the rulesets from the static analysis configuration file (deprecated).
79+
///
80+
/// # Deprecation
81+
/// Deprecated: Use [`post_get_rulesets_v2`] instead.
82+
///
83+
/// # Arguments
84+
/// * `content` - The path to the configuration file.
85+
#[instrument()]
86+
#[rocket::get("/v1/config/rulesets/<content..>")]
87+
pub fn get_get_rulesets(content: PathBuf) -> Json<Vec<String>> {
88+
let content_str = content.to_string_lossy().into_owned();
89+
get_rulesets(content_str)
90+
}
91+
92+
/// Gets the rulesets from the static analysis configuration file (v2).
93+
///
94+
/// # Arguments
95+
/// * `request` - The request containing the configuration file (base64).
96+
#[instrument()]
97+
#[rocket::post(
98+
"/v2/config/get-rulesets",
99+
format = "application/json",
100+
data = "<request>"
101+
)]
102+
pub fn post_get_rulesets_v2(request: Json<GetRulesetsRequest>) -> Json<Vec<String>> {
103+
let GetRulesetsRequest {
104+
configuration_base64,
105+
..
106+
} = request.into_inner();
107+
get_rulesets(configuration_base64)
108+
}
109+
110+
/// Adds rulesets to the static analysis configuration file (deprecated).
111+
///
112+
/// # Deprecation
113+
/// Deprecated: Use [`post_add_rulesets_v2`] instead.
114+
///
115+
/// # Arguments
116+
/// * `request` - The request containing rulesets and configuration file (base64).
30117
#[instrument()]
31118
#[rocket::post("/v1/config/rulesets", format = "application/json", data = "<request>")]
32-
pub fn post_rulesets(request: Json<AddRuleSetsRequest>) -> Result<String, Custom<ConfigFileError>> {
119+
pub fn post_add_rulesets(
120+
request: Json<AddRuleSetsRequest>,
121+
) -> Result<String, Custom<ConfigFileError>> {
122+
add_rulesets(request)
123+
}
124+
125+
/// Adds rulesets to the static analysis configuration file (v2).
126+
///
127+
/// # Arguments
128+
/// * `request` - The request containing rulesets and configuration file (base64).
129+
#[instrument()]
130+
#[rocket::post(
131+
"/v2/config/add-rulesets",
132+
format = "application/json",
133+
data = "<request>"
134+
)]
135+
pub fn post_add_rulesets_v2(
136+
request: Json<AddRuleSetsRequest>,
137+
) -> Result<String, Custom<ConfigFileError>> {
138+
add_rulesets(request)
139+
}
140+
141+
// ----------
142+
143+
/// Adds rulesets to the configuration file.
144+
///
145+
/// # Arguments
146+
/// * `request` - The request containing rulesets and configuration file (base64).
147+
fn add_rulesets(request: Json<AddRuleSetsRequest>) -> Result<String, Custom<ConfigFileError>> {
33148
let AddRuleSetsRequest {
34149
rulesets,
35150
configuration_base64,
@@ -44,25 +159,42 @@ pub fn post_rulesets(request: Json<AddRuleSetsRequest>) -> Result<String, Custom
44159
to_response_result(result, encoded)
45160
}
46161

47-
#[instrument()]
48-
#[rocket::get("/v1/config/rulesets/<content..>")]
49-
pub fn get_rulesets(content: PathBuf) -> Json<Vec<String>> {
50-
let content_str = content.to_string_lossy().into_owned();
51-
tracing::debug!(%content_str);
52-
Json(StaticAnalysisConfigFile::to_rulesets(content_str))
162+
/// Extracts rulesets from the configuration file.
163+
///
164+
/// # Arguments
165+
/// * `content` - The configuration file content (base64).
166+
fn get_rulesets(mut content: String) -> Json<Vec<String>> {
167+
if cfg!(target_os = "windows") {
168+
// NOTE: this is needed due to how Rocket works with multiple segment captures.
169+
// we may get rid of this once v1 endpoints are no longer needed.
170+
content = content.replace("\\", "/");
171+
}
172+
tracing::debug!(%content);
173+
Json(StaticAnalysisConfigFile::to_rulesets(content))
53174
}
54175

55-
#[instrument()]
56-
#[rocket::get("/v1/config/can-onboard/<content..>")]
57-
pub fn can_onboard(content: PathBuf) -> Result<Json<bool>, Custom<ConfigFileError>> {
58-
let content_str = content.to_string_lossy().into_owned();
59-
tracing::debug!(%content_str);
60-
let config = StaticAnalysisConfigFile::try_from(content_str)
176+
/// Checks if onboarding is allowed for the configuration file.
177+
///
178+
/// # Arguments
179+
/// * `content` - The configuration file content (base64).
180+
fn can_onboard(mut content: String) -> Result<Json<bool>, Custom<ConfigFileError>> {
181+
if cfg!(target_os = "windows") {
182+
// NOTE: this is needed due to how Rocket works with multiple segment captures.
183+
// we may get rid of this once v1 endpoints are no longer needed.
184+
content = content.replace("\\", "/");
185+
}
186+
tracing::debug!(%content);
187+
let config = StaticAnalysisConfigFile::try_from(content)
61188
.map_err(|e| Custom(Status::InternalServerError, e))?;
62189
let can_onboard = config.is_onboarding_allowed();
63190
Ok(Json(can_onboard))
64191
}
65192

193+
/// Converts the result to a response string, optionally encoding it in base64.
194+
///
195+
/// # Arguments
196+
/// * `result` - The result string or error.
197+
/// * `encode` - Whether to encode the result in base64.
66198
fn to_response_result(
67199
result: Result<String, ConfigFileError>,
68200
encode: bool,

crates/bins/src/bin/datadog_static_analyzer_server/ide/configuration_file/models.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,15 @@ pub struct AddRuleSetsRequest {
1515
pub configuration_base64: Option<String>,
1616
pub encoded: bool,
1717
}
18+
19+
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
20+
pub struct GetRulesetsRequest {
21+
#[serde(rename = "configuration")]
22+
pub configuration_base64: String,
23+
}
24+
25+
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
26+
pub struct CanOnboardRequest {
27+
#[serde(rename = "configuration")]
28+
pub configuration_base64: String,
29+
}

0 commit comments

Comments
 (0)