xmpp-parsers: Convert http_upload::Header to xso
We can’t use generate_attribute!() for HeaderName because it has to be case insensitive.
This commit is contained in:
parent
40808b883d
commit
543d9eb590
3 changed files with 55 additions and 68 deletions
|
|
@ -48,6 +48,9 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
|
||||||
ssm::StreamManagement::optional and starttls::StartTls::required are
|
ssm::StreamManagement::optional and starttls::StartTls::required are
|
||||||
now proper bools, instead of Option<ZeroSizedType> (!518)
|
now proper bools, instead of Option<ZeroSizedType> (!518)
|
||||||
- vCard-temp queries have been split into vcard::VCardQuery (!522)
|
- vCard-temp queries have been split into vcard::VCardQuery (!522)
|
||||||
|
- http_upload’s Header type has been split into HeaderName, an enum
|
||||||
|
containing only the name of the header, and the Header struct with
|
||||||
|
both a name and a value(!530)
|
||||||
* New parsers/serialisers:
|
* New parsers/serialisers:
|
||||||
- Stream Features (RFC 6120) (!400)
|
- Stream Features (RFC 6120) (!400)
|
||||||
- Spam Reporting (XEP-0377) (!506)
|
- Spam Reporting (XEP-0377) (!506)
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,11 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
use xso::{
|
use xso::{error::Error, AsXml, AsXmlText, FromXml, FromXmlText};
|
||||||
error::{Error, FromElementError, FromEventsError},
|
|
||||||
exports::rxml,
|
|
||||||
minidom_compat, AsXml, FromXml,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload};
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use minidom::Element;
|
use alloc::borrow::Cow;
|
||||||
|
|
||||||
/// Requesting a slot
|
/// Requesting a slot
|
||||||
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
|
|
@ -33,32 +29,37 @@ pub struct SlotRequest {
|
||||||
|
|
||||||
impl IqGetPayload for SlotRequest {}
|
impl IqGetPayload for SlotRequest {}
|
||||||
|
|
||||||
/// Slot header
|
/// All three possible header names.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Header {
|
pub enum HeaderName {
|
||||||
/// Authorization header
|
/// Authorization header
|
||||||
Authorization(String),
|
Authorization,
|
||||||
|
|
||||||
/// Cookie header
|
/// Cookie header
|
||||||
Cookie(String),
|
Cookie,
|
||||||
|
|
||||||
/// Expires header
|
/// Expires header
|
||||||
Expires(String),
|
Expires,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Element> for Header {
|
impl HeaderName {
|
||||||
type Error = FromElementError;
|
/// Returns the string version of this enum value.
|
||||||
fn try_from(elem: Element) -> Result<Header, FromElementError> {
|
pub fn as_str(&self) -> &'static str {
|
||||||
check_self!(elem, "header", HTTP_UPLOAD);
|
match self {
|
||||||
check_no_children!(elem, "header");
|
HeaderName::Authorization => "Authorization",
|
||||||
check_no_unknown_attributes!(elem, "header", ["name"]);
|
HeaderName::Cookie => "Cookie",
|
||||||
let name: String = get_attr!(elem, "name", Required);
|
HeaderName::Expires => "Expires",
|
||||||
let text = elem.text();
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(match name.to_lowercase().as_str() {
|
impl FromXmlText for HeaderName {
|
||||||
"authorization" => Header::Authorization(text),
|
fn from_xml_text(mut s: String) -> Result<Self, Error> {
|
||||||
"cookie" => Header::Cookie(text),
|
s.make_ascii_lowercase();
|
||||||
"expires" => Header::Expires(text),
|
Ok(match s.as_str() {
|
||||||
|
"authorization" => HeaderName::Authorization,
|
||||||
|
"cookie" => HeaderName::Cookie,
|
||||||
|
"expires" => HeaderName::Expires,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::Other(
|
return Err(Error::Other(
|
||||||
"Header name must be either 'Authorization', 'Cookie', or 'Expires'.",
|
"Header name must be either 'Authorization', 'Cookie', or 'Expires'.",
|
||||||
|
|
@ -69,41 +70,23 @@ impl TryFrom<Element> for Header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromXml for Header {
|
impl AsXmlText for HeaderName {
|
||||||
type Builder = minidom_compat::FromEventsViaElement<Header>;
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
Ok(Cow::Borrowed(self.as_str()))
|
||||||
fn from_events(
|
|
||||||
qname: rxml::QName,
|
|
||||||
attrs: rxml::AttrMap,
|
|
||||||
) -> Result<Self::Builder, FromEventsError> {
|
|
||||||
if qname.0 != ns::HTTP_UPLOAD || qname.1 != "header" {
|
|
||||||
return Err(FromEventsError::Mismatch { name: qname, attrs });
|
|
||||||
}
|
|
||||||
Self::Builder::new(qname, attrs)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Header> for Element {
|
/// Slot header
|
||||||
fn from(elem: Header) -> Element {
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
let (attr, val) = match elem {
|
#[xml(namespace = ns::HTTP_UPLOAD, name = "header")]
|
||||||
Header::Authorization(val) => ("Authorization", val),
|
pub struct Header {
|
||||||
Header::Cookie(val) => ("Cookie", val),
|
/// Name of the header
|
||||||
Header::Expires(val) => ("Expires", val),
|
#[xml(attribute)]
|
||||||
};
|
pub name: HeaderName,
|
||||||
|
|
||||||
Element::builder("header", ns::HTTP_UPLOAD)
|
/// Value of the header
|
||||||
.attr("name", attr)
|
#[xml(text)]
|
||||||
.append(val)
|
pub value: String,
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsXml for Header {
|
|
||||||
type ItemIter<'x> = minidom_compat::AsItemsViaElement<'x>;
|
|
||||||
|
|
||||||
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, Error> {
|
|
||||||
minidom_compat::AsItemsViaElement::new(self.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Put URL
|
/// Put URL
|
||||||
|
|
@ -146,11 +129,13 @@ impl IqResultPayload for SlotResult {}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use minidom::Element;
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(SlotRequest, 32);
|
assert_size!(SlotRequest, 32);
|
||||||
|
assert_size!(HeaderName, 1);
|
||||||
assert_size!(Header, 16);
|
assert_size!(Header, 16);
|
||||||
assert_size!(Put, 24);
|
assert_size!(Put, 24);
|
||||||
assert_size!(Get, 12);
|
assert_size!(Get, 12);
|
||||||
|
|
@ -161,6 +146,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(SlotRequest, 56);
|
assert_size!(SlotRequest, 56);
|
||||||
|
assert_size!(HeaderName, 1);
|
||||||
assert_size!(Header, 32);
|
assert_size!(Header, 32);
|
||||||
assert_size!(Put, 48);
|
assert_size!(Put, 48);
|
||||||
assert_size!(Get, 24);
|
assert_size!(Get, 24);
|
||||||
|
|
@ -196,11 +182,17 @@ mod tests {
|
||||||
assert_eq!(slot.put.url, String::from("https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/tr%C3%A8s%20cool.jpg"));
|
assert_eq!(slot.put.url, String::from("https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/tr%C3%A8s%20cool.jpg"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slot.put.headers[0],
|
slot.put.headers[0],
|
||||||
Header::Authorization(String::from("Basic Base64String=="))
|
Header {
|
||||||
|
name: HeaderName::Authorization,
|
||||||
|
value: String::from("Basic Base64String==")
|
||||||
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slot.put.headers[1],
|
slot.put.headers[1],
|
||||||
Header::Cookie(String::from("foo=bar; user=romeo"))
|
Header {
|
||||||
|
name: HeaderName::Cookie,
|
||||||
|
value: String::from("foo=bar; user=romeo")
|
||||||
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(slot.get.url, String::from("https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/tr%C3%A8s%20cool.jpg"));
|
assert_eq!(slot.get.url, String::from("https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/tr%C3%A8s%20cool.jpg"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,7 @@ use reqwest::{
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio_util::codec::{BytesCodec, FramedRead};
|
use tokio_util::codec::{BytesCodec, FramedRead};
|
||||||
use tokio_xmpp::{
|
use tokio_xmpp::{jid::Jid, minidom::Element, parsers::http_upload::SlotResult};
|
||||||
jid::Jid,
|
|
||||||
minidom::Element,
|
|
||||||
parsers::http_upload::{Header as HttpUploadHeader, SlotResult},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{Agent, Event};
|
use crate::{Agent, Event};
|
||||||
|
|
||||||
|
|
@ -39,12 +35,8 @@ pub async fn handle_upload_result(
|
||||||
|
|
||||||
let mut headers = ReqwestHeaderMap::new();
|
let mut headers = ReqwestHeaderMap::new();
|
||||||
for header in slot.put.headers {
|
for header in slot.put.headers {
|
||||||
let (attr, val) = match header {
|
let attr = header.name.as_str();
|
||||||
HttpUploadHeader::Authorization(val) => ("Authorization", val),
|
headers.insert(attr, header.value.parse().unwrap());
|
||||||
HttpUploadHeader::Cookie(val) => ("Cookie", val),
|
|
||||||
HttpUploadHeader::Expires(val) => ("Expires", val),
|
|
||||||
};
|
|
||||||
headers.insert(attr, val.parse().unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let web = ReqwestClient::new();
|
let web = ReqwestClient::new();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue