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",
|
"bunbunsearch",
|
||||||
"itertools",
|
"itertools",
|
||||||
"opensearchdescription"
|
"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
|
# 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
|
# input is percent-escaped. If multiple routes are defined, then the later
|
||||||
# defined route is used.
|
# 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:
|
groups:
|
||||||
-
|
-
|
||||||
name: "Meta commands"
|
name: "Meta commands"
|
||||||
|
|
|
@ -6,11 +6,12 @@ use actix_web::web::{Data, Query};
|
||||||
use actix_web::{HttpRequest, HttpResponse, Responder};
|
use actix_web::{HttpRequest, HttpResponse, Responder};
|
||||||
use handlebars::Handlebars;
|
use handlebars::Handlebars;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::debug;
|
use log::{debug, error};
|
||||||
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
||||||
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::process::Command;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
/// https://url.spec.whatwg.org/#fragment-percent-encode-set
|
/// https://url.spec.whatwg.org/#fragment-percent-encode-set
|
||||||
|
@ -112,24 +113,34 @@ pub async fn hop(
|
||||||
let data = data.read().unwrap();
|
let data = data.read().unwrap();
|
||||||
|
|
||||||
match resolve_hop(&query.to, &data.routes, &data.default_route) {
|
match resolve_hop(&query.to, &data.routes, &data.default_route) {
|
||||||
(Some(path), args) => HttpResponse::Found()
|
(Some(path), args) => {
|
||||||
.header(
|
let resolved_template = match path {
|
||||||
header::LOCATION,
|
Route::Path(path) => resolve_path(path, &args),
|
||||||
req
|
Route::External(path) => Ok(path.to_owned().into_bytes()),
|
||||||
.app_data::<Handlebars>()
|
};
|
||||||
.unwrap()
|
|
||||||
.render_template(
|
match resolved_template {
|
||||||
match path {
|
Ok(path) => HttpResponse::Found()
|
||||||
Route::Path(s) => s, // TODO: try resolve path
|
.header(
|
||||||
Route::External(s) => s,
|
header::LOCATION,
|
||||||
},
|
req
|
||||||
&template_args::query(
|
.app_data::<Handlebars>()
|
||||||
utf8_percent_encode(&args, FRAGMENT_ENCODE_SET).to_string(),
|
.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(),
|
||||||
)
|
Err(e) => {
|
||||||
.finish(),
|
error!("Failed to resolve template for path {}: {}", path, e);
|
||||||
|
HttpResponse::InternalServerError().body("Something went wrong :(")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
(None, _) => HttpResponse::NotFound().body("not found"),
|
(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")]
|
#[get("/bunbunsearch.xml")]
|
||||||
pub async fn opensearch(data: StateData, req: HttpRequest) -> impl Responder {
|
pub async fn opensearch(data: StateData, req: HttpRequest) -> impl Responder {
|
||||||
let data = data.read().unwrap();
|
let data = data.read().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue