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::connect::ServerConnector;
14use tokio_xmpp::{
15 parsers::http_upload::{Header as HttpUploadHeader, SlotResult},
16 Element, Jid,
17};
18
19use crate::{Agent, Event};
20
21pub async fn handle_upload_result<C: ServerConnector>(
22 from: &Jid,
23 iqid: String,
24 elem: Element,
25 agent: &mut Agent<C>,
26) -> impl IntoIterator<Item = Event> {
27 let mut res: Option<(usize, PathBuf)> = None;
28
29 for (i, (id, to, filepath)) in agent.uploads.iter().enumerate() {
30 if to == from && id == &iqid {
31 res = Some((i, filepath.to_path_buf()));
32 break;
33 }
34 }
35
36 if let Some((index, file)) = res {
37 agent.uploads.remove(index);
38 let slot = SlotResult::try_from(elem).unwrap();
39
40 let mut headers = ReqwestHeaderMap::new();
41 for header in slot.put.headers {
42 let (attr, val) = match header {
43 HttpUploadHeader::Authorization(val) => ("Authorization", val),
44 HttpUploadHeader::Cookie(val) => ("Cookie", val),
45 HttpUploadHeader::Expires(val) => ("Expires", val),
46 };
47 headers.insert(attr, val.parse().unwrap());
48 }
49
50 let web = ReqwestClient::new();
51 let stream = FramedRead::new(File::open(file).await.unwrap(), BytesCodec::new());
52 let body = ReqwestBody::wrap_stream(stream);
53 let res = web
54 .put(slot.put.url.as_str())
55 .headers(headers)
56 .body(body)
57 .send()
58 .await
59 .unwrap();
60 if res.status() == 201 {
61 return vec![Event::HttpUploadedFile(slot.get.url)];
62 }
63 }
64
65 return vec![];
66}