diff --git a/ext-hyper/src/hyper_http.rs b/ext-hyper/src/hyper_http.rs index 20eb8aa..eca4278 100644 --- a/ext-hyper/src/hyper_http.rs +++ b/ext-hyper/src/hyper_http.rs @@ -163,7 +163,7 @@ mod tests { #[tokio::test] async fn test_extract_component_from_request() { - let mut req = build_request().await.unwrap(); + let req = build_request().await.unwrap(); let component_id_method = HttpMessageComponentId::try_from("\"@method\"").unwrap(); let component = extract_http_message_component_from_request(&req, &component_id_method).unwrap(); @@ -186,7 +186,11 @@ mod tests { component.to_string(), "\"content-digest\": sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:" ); + } + #[tokio::test] + async fn test_extract_signature_params_from_request() { + let mut req = build_request().await.unwrap(); let headers = req.headers_mut(); headers.insert( "signature-input", @@ -194,6 +198,10 @@ mod tests { ); let component_id = HttpMessageComponentId::try_from("@signature-params").unwrap(); let component = extract_http_message_component_from_request(&req, &component_id).unwrap(); - assert_eq!(component.to_string(), "\"@signature-params\": (\"@method\" \"@input\")"); + assert_eq!(component.to_string(), "\"@signature-params\": (\"@method\" \"@authority\")"); + assert_eq!(component.value.to_string(), r##"("@method" "@authority")"##); + assert_eq!(component.value.as_field_value(), r##"sig1=("@method" "@authority")"##); + assert_eq!(component.value.as_component_value(), r##"("@method" "@authority")"##); + assert_eq!(component.value.key(), Some("sig1")); } } diff --git a/lib/src/message_component/component.rs b/lib/src/message_component/component.rs index dafb22f..b090bce 100644 --- a/lib/src/message_component/component.rs +++ b/lib/src/message_component/component.rs @@ -186,7 +186,7 @@ impl std::fmt::Display for HttpMessageComponentValueInner { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::String(val) => write!(f, "{}", val), - Self::KeyValue((key, val)) => write!(f, "{}={}", key, val), + Self::KeyValue((_, val)) => write!(f, "{}", val), } } } @@ -199,8 +199,15 @@ impl HttpMessageComponentValue { HttpMessageComponentValueInner::KeyValue((key, _)) => Some(key.as_ref()), } } - /// Get value - pub fn value(&self) -> &str { + /// Get key value connected with `=`, or just value + pub fn as_field_value(&self) -> String { + match &self.inner { + HttpMessageComponentValueInner::String(val) => val.to_owned(), + HttpMessageComponentValueInner::KeyValue((key, val)) => format!("{}={}", key, val), + } + } + /// Get value only + pub fn as_component_value(&self) -> &str { match &self.inner { HttpMessageComponentValueInner::String(val) => val.as_ref(), HttpMessageComponentValueInner::KeyValue((_, val)) => val.as_ref(), @@ -412,6 +419,8 @@ mod tests { assert!(!comp.id.params.0.is_empty()); } assert_eq!(comp.value.inner.to_string(), value); + assert_eq!(comp.value.as_field_value(), value); + assert_eq!(comp.value.key(), None); assert_eq!(comp.to_string(), format!("{}: {}", id, value)); } } @@ -426,7 +435,8 @@ mod tests { Some(&HttpMessageComponentParam::Name("key".to_string())) ); assert_eq!(comp.value.inner.to_string(), value); - assert_eq!(comp.value.value(), value); + assert_eq!(comp.value.as_field_value(), value); + assert_eq!(comp.value.key(), None); assert_eq!(comp.to_string(), format!("{}: {}", id, value)); } diff --git a/lib/src/message_component/parse.rs b/lib/src/message_component/parse.rs index 7919c27..bbfe2ae 100644 --- a/lib/src/message_component/parse.rs +++ b/lib/src/message_component/parse.rs @@ -31,15 +31,15 @@ fn build_derived_component(id: &HttpMessageComponentId, field_values: &[String]) "invalid parameter for derived component" ); - let merged = match derived_id { - super::DerivedComponentName::Method => field_values[0].to_ascii_uppercase(), - super::DerivedComponentName::TargetUri => field_values[0].to_string(), - super::DerivedComponentName::Authority => field_values[0].to_ascii_lowercase(), - super::DerivedComponentName::Scheme => field_values[0].to_ascii_lowercase(), - super::DerivedComponentName::RequestTarget => field_values[0].to_string(), - super::DerivedComponentName::Path => field_values[0].to_string(), - super::DerivedComponentName::Query => field_values[0].to_string(), - super::DerivedComponentName::Status => field_values[0].to_string(), + let value = match derived_id { + super::DerivedComponentName::Method => HttpMessageComponentValue::from(field_values[0].to_ascii_uppercase().as_ref()), + super::DerivedComponentName::TargetUri => HttpMessageComponentValue::from(field_values[0].to_string().as_ref()), + super::DerivedComponentName::Authority => HttpMessageComponentValue::from(field_values[0].to_ascii_lowercase().as_ref()), + super::DerivedComponentName::Scheme => HttpMessageComponentValue::from(field_values[0].to_ascii_lowercase().as_ref()), + super::DerivedComponentName::RequestTarget => HttpMessageComponentValue::from(field_values[0].to_string().as_ref()), + super::DerivedComponentName::Path => HttpMessageComponentValue::from(field_values[0].to_string().as_ref()), + super::DerivedComponentName::Query => HttpMessageComponentValue::from(field_values[0].to_string().as_ref()), + super::DerivedComponentName::Status => HttpMessageComponentValue::from(field_values[0].to_string().as_ref()), super::DerivedComponentName::QueryParam => { let name = id.params.0.iter().find_map(|p| match p { HttpMessageComponentParam::Name(name) => Some(name), @@ -54,18 +54,17 @@ fn build_derived_component(id: &HttpMessageComponentId, field_values: &[String]) .filter(|(k, _)| *k == name.as_str()) .map(|(_, v)| v) .collect::>(); - kvs.join(", ") + HttpMessageComponentValue::from(kvs.join(", ").as_ref()) } super::DerivedComponentName::SignatureParams => { let value = field_values[0].to_string(); - // let s = value.trim().split_once('='); - value + let opt_pair = value.trim().split_once('='); + ensure!(opt_pair.is_some(), "invalid signature-params derived component"); + let (key, value) = opt_pair.unwrap(); + HttpMessageComponentValue::from((key, value)) } }; - let component = HttpMessageComponent { - id: id.clone(), - value: HttpMessageComponentValue::from(merged.as_ref()), - }; + let component = HttpMessageComponent { id: id.clone(), value }; Ok(component) }