///|
pub struct SignatureComponent {
key : String
value : String
} derive(Eq, Debug)
///|
pub fn SignatureComponent::new(
key : String,
value : String,
) -> SignatureComponent {
{ key, value }
}
///|
fn first_ascii_index(input : String, wanted : UInt16) -> Int {
for i in 0.. Int {
if trim_ascii(input) == "" {
return 0
}
let mut count = 1
for i in 0.. Array[String] {
let count = count_signature_parts(input)
if count == 0 {
return []
}
let comma = ','.to_int().to_uint16()
let mut cursor = 0
let mut start = 0
Array::makei(count, _ => {
while cursor < input.length() && input.unsafe_get(cursor) != comma {
cursor = cursor + 1
}
let part = trim_ascii(input[start:cursor].to_owned())
if cursor < input.length() {
cursor = cursor + 1
}
start = cursor
part
})
}
///|
fn parse_signature_component(input : String) -> SignatureComponent? {
let separator = first_ascii_index(input, '='.to_int().to_uint16())
if separator <= 0 || separator >= input.length() - 1 {
return None
}
let key = trim_ascii(input[0:separator].to_owned())
let value = trim_ascii(input[separator + 1:].to_owned())
if key == "" || value == "" {
None
} else {
Some(SignatureComponent::new(key, value))
}
}
///|
pub fn parse_signature_header(input : String) -> Array[SignatureComponent] {
let parts = split_signature_parts(input)
let parsed : Array[SignatureComponent] = []
for part in parts {
match parse_signature_component(part) {
Some(component) => parsed.push(component)
None => ()
}
}
parsed
}
///|
pub fn signature_values(
components : Array[SignatureComponent],
key : String,
) -> Array[String] {
let values : Array[String] = []
for component in components {
if component.key == key {
values.push(component.value)
}
}
values
}
///|
pub fn first_signature_value(
components : Array[SignatureComponent],
key : String,
) -> String? {
for component in components {
if component.key == key {
return Some(component.value)
}
}
None
}
///|
pub struct StripeSignature {
timestamp : Int
timestamp_text : String
v1_signatures : Array[String]
legacy_signatures : Array[String]
unknown_components : Array[SignatureComponent]
} derive(Eq, Debug)
///|
pub fn StripeSignature::empty() -> StripeSignature {
{
timestamp: 0,
timestamp_text: "",
v1_signatures: [],
legacy_signatures: [],
unknown_components: [],
}
}
///|
pub fn StripeSignature::is_well_formed(self : StripeSignature) -> Bool {
self.timestamp > 0 && self.v1_signatures.length() > 0
}
///|
pub fn parse_stripe_signature(input : String) -> StripeSignature {
let components = parse_signature_header(input)
let timestamp_text = first_signature_value(components, "t").unwrap_or("")
let v1_signatures = signature_values(components, "v1")
let legacy_signatures = signature_values(components, "v0")
let unknown_components : Array[SignatureComponent] = []
for component in components {
if component.key != "t" && component.key != "v1" && component.key != "v0" {
unknown_components.push(component)
}
}
{
timestamp: parse_positive_int(timestamp_text),
timestamp_text,
v1_signatures,
legacy_signatures,
unknown_components,
}
}
///|
pub fn stripe_signature_summary(signature : StripeSignature) -> String {
let builder = StringBuilder::new()
builder.write_string("timestamp=")
builder.write_string(signature.timestamp.to_string())
builder.write_string(" v1=")
builder.write_string(signature.v1_signatures.length().to_string())
builder.write_string(" legacy=")
builder.write_string(signature.legacy_signatures.length().to_string())
builder.write_string(" unknown=")
builder.write_string(signature.unknown_components.length().to_string())
builder.to_string()
}