Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 52e7015

Browse files
committed
Replace old upload route
1 parent 0fa1079 commit 52e7015

File tree

2 files changed

+108
-3
lines changed

2 files changed

+108
-3
lines changed

src/main.rs

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
// jkcoxson
22

33
use backend::Backend;
4+
use bytes::BufMut;
5+
use futures::TryStreamExt;
46
use log::{info, warn};
57
use plist_plus::Plist;
68
use serde_json::Value;
79
use std::{net::SocketAddr, str::FromStr, sync::Arc};
810
use tokio::sync::Mutex;
9-
use warp::{filters::BoxedFilter, http::Uri, path::FullPath, redirect, Filter, Rejection, Reply};
11+
use warp::{
12+
filters::BoxedFilter,
13+
http::Uri,
14+
multipart::{FormData, Part},
15+
path::FullPath,
16+
redirect, Filter, Rejection, Reply,
17+
};
1018

1119
mod backend;
1220
mod client;
@@ -24,6 +32,7 @@ async fn main() {
2432
let static_dir = config.static_path.clone();
2533
let current_dir = std::env::current_dir().expect("failed to read current directory");
2634
let backend = Arc::new(Mutex::new(backend::Backend::load(&config)));
35+
let upload_backend = backend.clone();
2736
let potential_backend = backend.clone();
2837
let potential_follow_up_backend = backend.clone();
2938
let status_backend = backend.clone();
@@ -44,6 +53,13 @@ async fn main() {
4453
))
4554
});
4655

56+
// Upload route
57+
let upload_route = warp::path("upload")
58+
.and(warp::post())
59+
.and(warp::multipart::form().max_length(5_000_000))
60+
.and(warp::filters::addr::remote())
61+
.and_then(move |form, addr| upload_file(form, addr, upload_backend.clone()));
62+
4763
// Potential route
4864
let potential_route = warp::path("potential")
4965
.and(warp::get())
@@ -84,6 +100,7 @@ async fn main() {
84100
let routes = root_redirect()
85101
.or(warp::fs::dir(current_dir.join(static_dir)))
86102
.or(status_route)
103+
.or(upload_route)
87104
.or(potential_route)
88105
.or(potential_follow_up_route)
89106
.or(list_apps_route)
@@ -121,6 +138,95 @@ async fn version_route() -> Result<impl Reply, Rejection> {
121138
Ok("0.1.2")
122139
}
123140

141+
async fn upload_file(
142+
form: FormData,
143+
address: Option<SocketAddr>,
144+
backend: Arc<Mutex<Backend>>,
145+
) -> Result<impl Reply, Rejection> {
146+
let lock = backend.lock().await;
147+
let parts: Vec<Part> = match form.try_collect().await {
148+
Ok(parts) => parts,
149+
Err(_) => return Ok(packets::upload_response(false, "Form error")),
150+
};
151+
152+
for p in parts {
153+
if p.name() == "file" {
154+
let value = match p
155+
.stream()
156+
.try_fold(Vec::new(), |mut vec, data| {
157+
vec.put(data);
158+
async move { Ok(vec) }
159+
})
160+
.await
161+
{
162+
Ok(value) => value,
163+
Err(_) => return Ok(packets::upload_response(false, "File error")),
164+
};
165+
166+
// Get string from value
167+
let value = match String::from_utf8(value) {
168+
Ok(value) => value,
169+
Err(_) => {
170+
return Ok(packets::upload_response(false, "Unable to read file"));
171+
}
172+
};
173+
// Attempt to parse it as an Apple Plist
174+
let plist: Plist = Plist::from_xml(value.clone()).unwrap();
175+
let udid = match plist.dict_get_item("UDID") {
176+
Ok(s) => match s.get_string_val() {
177+
Ok(s) => s,
178+
Err(_) => {
179+
return Ok(packets::upload_response(
180+
false,
181+
"Unable to read UDID from Plist",
182+
));
183+
}
184+
},
185+
_ => {
186+
return Ok(packets::upload_response(false, "Invalid pairing file!"));
187+
}
188+
};
189+
let address = match address {
190+
Some(address) => address,
191+
None => {
192+
return Ok(packets::upload_response(false, "No address provided"));
193+
}
194+
};
195+
let plist: Plist = Plist::from_xml(value).unwrap();
196+
// Save the plist to the plist storage directory
197+
match lock.write_pairing_file(plist.to_string(), &udid) {
198+
Ok(_) => {}
199+
Err(_) => {
200+
return Ok(packets::upload_response(
201+
false,
202+
"Unable to save pairing file",
203+
));
204+
}
205+
}
206+
drop(lock);
207+
// Make sure that the client is valid before adding it to the backend
208+
match backend::Backend::test_new_client(&address.ip().to_string(), &udid).await {
209+
Ok(_) => {}
210+
Err(_) => {
211+
return Ok(packets::upload_response(
212+
false,
213+
"Device did not respond to pairing test",
214+
));
215+
}
216+
}
217+
let mut lock = backend.lock().await;
218+
match lock.register_client(address.ip().to_string(), udid.clone()) {
219+
Ok(_) => {}
220+
Err(_) => {
221+
return Ok(packets::upload_response(false, "Client already registered"));
222+
}
223+
}
224+
return Ok(packets::upload_response(true, ""));
225+
}
226+
}
227+
return Ok(packets::upload_response(false, "No file found"));
228+
}
229+
124230
async fn potential_pair(
125231
addr: Option<SocketAddr>,
126232
backend: Arc<Mutex<Backend>>,

src/packets.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,9 @@ pub fn list_apps_response(
4242
success: bool,
4343
message: &str,
4444
list: serde_json::Value,
45-
mut prefered_list: serde_json::Value,
45+
prefered_list: serde_json::Value,
4646
) -> String {
4747
let mut packet: serde_json::Value = serde_json::Value::Object(serde_json::Map::new());
48-
prefered_list["More"] = serde_json::Value::String("List all apps".to_string());
4948
packet["success"] = serde_json::Value::Bool(success);
5049
packet["message"] = serde_json::Value::String(message.to_string());
5150
packet["list"] = list;

0 commit comments

Comments
 (0)