execute from local file if possible
This commit is contained in:
parent
1385045013
commit
c990aef0e9
3 changed files with 46 additions and 19 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -6,5 +6,6 @@
|
|||
"bunbunsearch",
|
||||
"itertools",
|
||||
"opensearchdescription"
|
||||
]
|
||||
],
|
||||
"python.pythonPath": "/usr/bin/python3"
|
||||
}
|
|
@ -15,6 +15,17 @@ default_route: "g"
|
|||
# contain "{{query}}", which will be populated by the user's search query. This
|
||||
# input is percent-escaped. If multiple routes are defined, then the later
|
||||
# defined route is used.
|
||||
#
|
||||
# You may provide an (absolute, recommended) path to an executable file to out-
|
||||
# source route resolution to a program. The program will receive one argument
|
||||
# only, which is the entire string provided from the user after matching the
|
||||
# route. It is up to the out-sourced program to parse the arguments and to
|
||||
# interpret those arguments. These programs should print one line to standard
|
||||
# out, which should be a fully resolved URL to lead the user to.
|
||||
#
|
||||
# These programs must be developed defensively, as they accept arbitrary user
|
||||
# input. Improper handling of user input can easily lead to anywhere from simple
|
||||
# flakey responses to remote code execution.
|
||||
groups:
|
||||
-
|
||||
name: "Meta commands"
|
||||
|
|
|
@ -6,11 +6,12 @@ use actix_web::web::{Data, Query};
|
|||
use actix_web::{HttpRequest, HttpResponse, Responder};
|
||||
use handlebars::Handlebars;
|
||||
use itertools::Itertools;
|
||||
use log::debug;
|
||||
use log::{debug, error};
|
||||
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
||||
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::process::Command;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
/// https://url.spec.whatwg.org/#fragment-percent-encode-set
|
||||
|
@ -112,24 +113,34 @@ pub async fn hop(
|
|||
let data = data.read().unwrap();
|
||||
|
||||
match resolve_hop(&query.to, &data.routes, &data.default_route) {
|
||||
(Some(path), args) => HttpResponse::Found()
|
||||
.header(
|
||||
header::LOCATION,
|
||||
req
|
||||
.app_data::<Handlebars>()
|
||||
.unwrap()
|
||||
.render_template(
|
||||
match path {
|
||||
Route::Path(s) => s, // TODO: try resolve path
|
||||
Route::External(s) => s,
|
||||
},
|
||||
&template_args::query(
|
||||
utf8_percent_encode(&args, FRAGMENT_ENCODE_SET).to_string(),
|
||||
),
|
||||
(Some(path), args) => {
|
||||
let resolved_template = match path {
|
||||
Route::Path(path) => resolve_path(path, &args),
|
||||
Route::External(path) => Ok(path.to_owned().into_bytes()),
|
||||
};
|
||||
|
||||
match resolved_template {
|
||||
Ok(path) => HttpResponse::Found()
|
||||
.header(
|
||||
header::LOCATION,
|
||||
req
|
||||
.app_data::<Handlebars>()
|
||||
.unwrap()
|
||||
.render_template(
|
||||
&std::str::from_utf8(&path).unwrap().trim(),
|
||||
&template_args::query(
|
||||
utf8_percent_encode(&args, FRAGMENT_ENCODE_SET).to_string(),
|
||||
),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.finish(),
|
||||
.finish(),
|
||||
Err(e) => {
|
||||
error!("Failed to resolve template for path {}: {}", path, e);
|
||||
HttpResponse::InternalServerError().body("Something went wrong :(")
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, _) => HttpResponse::NotFound().body("not found"),
|
||||
}
|
||||
}
|
||||
|
@ -203,6 +214,10 @@ pub async fn index(data: StateData, req: HttpRequest) -> impl Responder {
|
|||
)
|
||||
}
|
||||
|
||||
fn resolve_path(path: &str, args: &str) -> Result<Vec<u8>, crate::BunBunError> {
|
||||
Ok(Command::new(path).arg(args).output()?.stdout)
|
||||
}
|
||||
|
||||
#[get("/bunbunsearch.xml")]
|
||||
pub async fn opensearch(data: StateData, req: HttpRequest) -> impl Responder {
|
||||
let data = data.read().unwrap();
|
||||
|
|
Loading…
Reference in a new issue