Skip to content

Commit 1321cff

Browse files
goffrieConvex, Inc.
authored andcommitted
Make URL implementation a bit more robust (#41938)
GitOrigin-RevId: 746f5d343c422d7862e6320e11ef5afc14bff168
1 parent 3c32242 commit 1321cff

File tree

3 files changed

+128
-103
lines changed

3 files changed

+128
-103
lines changed

crates/isolate/src/ops/http.rs

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -131,32 +131,30 @@ pub fn op_url_stringify_url_search_params<'b, P: OpProvider<'b>>(
131131
Ok(search)
132132
}
133133

134+
#[derive(Deserialize, Debug, Clone)]
135+
#[serde(rename_all = "camelCase")]
136+
enum UrlInfoUpdate {
137+
Hash(Option<String>),
138+
Hostname(Option<String>),
139+
Href(String),
140+
Protocol(String),
141+
Port(Option<String>),
142+
Pathname(String),
143+
Search(Option<String>),
144+
SearchParams(Vec<(String, String)>),
145+
}
146+
134147
#[convex_macro::v8_op]
135148
pub fn op_url_update_url_info<'b, P: OpProvider<'b>>(
136149
provider: &mut P,
137150
original_url: String,
138-
update: JsonValue,
151+
update: UrlInfoUpdate,
139152
) -> anyhow::Result<JsonValue> {
140-
#[derive(Deserialize, Debug, Clone)]
141-
#[serde(rename_all = "camelCase")]
142-
#[serde(tag = "type")]
143-
enum Update {
144-
Hash { value: Option<String> },
145-
Hostname { value: Option<String> },
146-
Href { value: String },
147-
Protocol { value: String },
148-
Port { value: Option<String> },
149-
Pathname { value: String },
150-
Search { value: Option<String> },
151-
SearchParams { value: Vec<(String, String)> },
152-
}
153-
154-
let update: Update = serde_json::from_value(update)?;
155153
let mut parsed_url = Url::parse(&original_url)?;
156154

157155
match update {
158-
Update::Hash { value } => parsed_url.set_fragment(value.as_deref()),
159-
Update::SearchParams { value } => {
156+
UrlInfoUpdate::Hash(value) => parsed_url.set_fragment(value.as_deref()),
157+
UrlInfoUpdate::SearchParams(value) => {
160158
if value.is_empty() {
161159
parsed_url.set_query(None)
162160
} else {
@@ -167,21 +165,21 @@ pub fn op_url_update_url_info<'b, P: OpProvider<'b>>(
167165
.finish();
168166
}
169167
},
170-
Update::Hostname { value } => parsed_url.set_host(value.as_deref())?,
171-
Update::Href { value } => {
168+
UrlInfoUpdate::Hostname(value) => parsed_url.set_host(value.as_deref())?,
169+
UrlInfoUpdate::Href(value) => {
172170
parsed_url = Url::parse(&value).context(ErrorMetadata::bad_request(
173171
"BadUrl",
174172
format!("Could not parse URL: {original_url}"),
175173
))?;
176174
},
177-
Update::Protocol { value } => {
175+
UrlInfoUpdate::Protocol(value) => {
178176
if value != "http" && value != "https" {
179177
parsed_url
180178
.set_scheme(&value)
181179
.map_err(|_e| anyhow::anyhow!("Failed to set scheme"))?
182180
}
183181
},
184-
Update::Port { value } => match value {
182+
UrlInfoUpdate::Port(value) => match value {
185183
Some(port_str) => match port_str.parse::<u16>() {
186184
Ok(port_number) => parsed_url
187185
.set_port(Some(port_number))
@@ -192,8 +190,8 @@ pub fn op_url_update_url_info<'b, P: OpProvider<'b>>(
192190
.set_port(None)
193191
.map_err(|_e| anyhow::anyhow!("Failed to set port"))?,
194192
},
195-
Update::Pathname { value } => parsed_url.set_path(&value),
196-
Update::Search { value } => parsed_url.set_query(value.as_deref()),
193+
UrlInfoUpdate::Pathname(value) => parsed_url.set_path(&value),
194+
UrlInfoUpdate::Search(value) => parsed_url.set_query(value.as_deref()),
197195
}
198196

199197
let url_info: UrlInfo = parsed_url.try_into()?;

0 commit comments

Comments
 (0)