xmpp/upload/
receive.rs

1// Copyright (c) 2023 xmpp-rs contributors.
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use reqwest::{
8    header::HeaderMap as ReqwestHeaderMap, Body as ReqwestBody, Client as ReqwestClient,
9};
10use std::path::PathBuf;
11use tokio::fs::File;
12use tokio_util::codec::{BytesCodec, FramedRead};
13use tokio_xmpp::{jid::Jid, minidom::Element, parsers::http_upload::SlotResult};
14
15use crate::{Agent, Event};
16
17pub async fn handle_upload_result(
18    from: &Jid,
19    iqid: String,
20    elem: Element,
21    agent: &mut Agent,
22) -> impl IntoIterator<Item = Event> {
23    let mut res: Option<(usize, PathBuf)> = None;
24
25    for (i, (id, to, filepath)) in agent.uploads.iter().enumerate() {
26        if to == from && id == &iqid {
27            res = Some((i, filepath.to_path_buf()));
28            break;
29        }
30    }
31
32    if let Some((index, file)) = res {
33        agent.uploads.remove(index);
34        let slot = SlotResult::try_from(elem).unwrap();
35
36        let mut headers = ReqwestHeaderMap::new();
37        for header in slot.put.headers {
38            let attr = header.name.as_str();
39            headers.insert(attr, header.value.parse().unwrap());
40        }
41
42        let web = ReqwestClient::new();
43        let stream = FramedRead::new(File::open(file).await.unwrap(), BytesCodec::new());
44        let body = ReqwestBody::wrap_stream(stream);
45        let res = web
46            .put(slot.put.url.as_str())
47            .headers(headers)
48            .body(body)
49            .send()
50            .await
51            .unwrap();
52        if res.status() == 201 {
53            return vec![Event::HttpUploadedFile(slot.get.url)];
54        }
55    }
56
57    return vec![];
58}