mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
add pac
This commit is contained in:
@@ -82,3 +82,6 @@ git = "https://github.com/zonyitoo/simplesched.git"
|
||||
|
||||
[dependencies.qrcode]
|
||||
git = "https://github.com/kennytm/qrcode-rust.git"
|
||||
|
||||
[dependencies.hyper]
|
||||
git = "https://github.com/hyperium/hyper.git"
|
||||
|
||||
@@ -34,15 +34,21 @@ extern crate shadowsocks;
|
||||
extern crate log;
|
||||
extern crate fern;
|
||||
extern crate time;
|
||||
extern crate hyper;
|
||||
extern crate simplesched;
|
||||
|
||||
use clap::{App, Arg};
|
||||
|
||||
use std::net::{SocketAddr, IpAddr};
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
use shadowsocks::config::{Config, ServerConfig, self};
|
||||
use shadowsocks::config::DEFAULT_DNS_CACHE_CAPACITY;
|
||||
use shadowsocks::relay::{RelayLocal, Relay};
|
||||
|
||||
use simplesched::net::http::Server;
|
||||
|
||||
fn main() {
|
||||
let matches = App::new("shadowsocks")
|
||||
.version(shadowsocks::VERSION)
|
||||
@@ -77,6 +83,12 @@ fn main() {
|
||||
.arg(Arg::with_name("THREADS").short("t").long("threads")
|
||||
.takes_value(true)
|
||||
.help("Threads in thread pool"))
|
||||
.arg(Arg::with_name("PAC_PATH").short("a").long("pac-path")
|
||||
.takes_value(true)
|
||||
.help("PAC file path"))
|
||||
.arg(Arg::with_name("PAC_PORT").short("o").long("pac-port")
|
||||
.takes_value(true)
|
||||
.help("PAC server will listen on this port"))
|
||||
.get_matches();
|
||||
|
||||
let logger_config = |show_location| fern::DispatchConfig {
|
||||
@@ -173,5 +185,49 @@ fn main() {
|
||||
let threads = matches.value_of("THREADS").unwrap_or("1").parse::<usize>()
|
||||
.ok().expect("`threads` should be an integer");
|
||||
|
||||
if matches.value_of("PAC_PATH").is_some() ^ matches.value_of("PAC_PORT").is_some() {
|
||||
panic!("`pac-path` and `pac-port` must be specified together");
|
||||
} else {
|
||||
if let Some(path) = matches.value_of("PAC_PATH") {
|
||||
|
||||
let content = {
|
||||
let mut pac_file = File::open(&path).unwrap();
|
||||
let mut buf = Vec::new();
|
||||
pac_file.read_to_end(&mut buf).unwrap();
|
||||
buf
|
||||
};
|
||||
|
||||
if let Some(port) = matches.value_of("PAC_PORT") {
|
||||
use hyper::server::{Request, Response};
|
||||
use hyper::uri::RequestUri::AbsolutePath;
|
||||
use hyper::Get;
|
||||
|
||||
let port = port.parse::<u16>().ok().expect("`pac-port` has to be a u16 number");
|
||||
|
||||
info!("Serving PAC file ({}) at http://{}:{}/", path, config.local.unwrap().ip(), port);
|
||||
|
||||
let server = Server::http((config.local.unwrap().ip(), port)).unwrap();
|
||||
server.listen(move|req: Request, mut res: Response| {
|
||||
match req.uri {
|
||||
AbsolutePath(ref path) => match (&req.method, &path[..]) {
|
||||
(&Get, "/") => {
|
||||
if let Err(err) = res.send(&content) {
|
||||
error!("Error occurs while sending PAC file: {:?}", err);
|
||||
}
|
||||
},
|
||||
(_, "/") => {
|
||||
*res.status_mut() = hyper::status::StatusCode::MethodNotAllowed;
|
||||
},
|
||||
_ => {
|
||||
*res.status_mut() = hyper::NotFound;
|
||||
}
|
||||
},
|
||||
_ => return
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RelayLocal::new(config).run(threads);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user