zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
use lazy_static::lazy_static;

use crate::core::auth0::Protected;
use crate::core::url_dispatch::*;

use crate::core::config::UpStreams;
use crate::core::upstream;
use crate::server::AppContext;

lazy_static! {
    pub static ref P0: Protected = Protected::AnonymousUser;
    pub static ref U1: Protected = Protected::build(vec!["r_user"]);
}

#[rustfmt::skip]
pub fn config(cfg: &mut actix_web::web::ServiceConfig, use_developer: bool, ctx: actix_web::web::Data<AppContext>, upstreams: Option<Vec<UpStreams>>) {

    if !use_developer {
        return;
    }

    // health check
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/info", || async { "Hello, server is alive and kicking." });
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/health_check", || async { "Hello, server is alive and kicking." });

    // default pages
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/", crate::sitepages::default::home);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/index", crate::sitepages::default::home);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/home", crate::sitepages::default::home);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/signup", crate::sitepages::default::signup_form);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/post_signup", crate::services::user_service::signup);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/register", crate::services::user_service::register);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/login", crate::sitepages::default::login_form);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/logout", crate::sitepages::default::logout);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/post_login", crate::sitepages::default::login_post_flash);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/access_token", crate::sitepages::default::access_token);

    // oauth
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/authorize", crate::sitepages::oauth2_0::authorize_form);

    url_dispatch(cfg, ctx.clone(), "post", &P0, "/send_sms_code", crate::sitepages::default::send_sms_code);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/check_sms_code", crate::sitepages::default::check_sms_code);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/captcha_code", crate::sitepages::default::captcha_code);

    url_dispatch(cfg, ctx.clone(), "get", &P0, "/full_reload", crate::sitepages::default::full_reload);
    // oauth2 login
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/gl", crate::sitepages::lauth::gl); // google oauth
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/gt", crate::sitepages::lauth::gt); // github oauth
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/fb", crate::sitepages::lauth::gl); // facebook oauth
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/tx", crate::sitepages::lauth::gl); // twitter oauth
    // oauth2 login callback
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/cb/gl", crate::sitepages::lauth::gl_cb); // google oauth callback
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/cb/gt", crate::sitepages::lauth::gt_cb); // github oauth callback
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/cb/fb", crate::sitepages::lauth::gl_cb); // facebook oauth callback
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/lauth/oidc/cb/tx", crate::sitepages::lauth::gl_cb); // twitter oauth callback
    // user account settings
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/your-profile", crate::sitepages::account_setting::user_profile_form);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/your-profile/update", crate::sitepages::account_setting::user_profile_update);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/user-account", crate::sitepages::account_setting::user_account_form);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/user-account/update", crate::sitepages::account_setting::user_account_update);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/payments", crate::sitepages::account_setting::payments_form);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/payments/r/{qrcode}", crate::sitepages::account_setting::payments_receive_code);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/payments/s/{qrcode}", crate::sitepages::account_setting::payments_payment_code);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/user-notifications", crate::sitepages::account_setting::user_notifications_form);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/user-notifications/update", crate::sitepages::account_setting::user_notifications_update);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/user-identifier", crate::sitepages::account_setting::user_identifier_form);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/user-identifier/update", crate::sitepages::account_setting::user_identifier_update);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/user-keys", crate::sitepages::account_setting::user_keys_form);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/user-keys/update", crate::sitepages::account_setting::user_keys_update);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/user/change-passwd", crate::sitepages::account_setting::change_passwd);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/user/opt_codes", crate::sitepages::account_setting::query_opt_code);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/user/import_opt_code", crate::sitepages::account_setting::import_opt_code);
    url_dispatch(cfg, ctx.clone(), "put", &U1, "/user/opt_renew", crate::sitepages::account_setting::opt_code_renew);

    // 查询用户信息
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/user-info", crate::sitepages::account_setting::user_info);
    // 处理所有用户头像显示 profile_picture (pp)
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/m/pp/{user_id}", crate::sitepages::account_pics::profile_picture);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/avator/{user_id}", crate::sitepages::account_pics::avator);
    // 处理所有用户证件照片正(1)/反(2)面显示 idcard_picture (id1c)
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/id1a/{user_id}", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/id2b/{user_id}", crate::sitepages::upload0::image_viewer);
    // 处理所有用户从业资格证书显示 certificate_picture (cf), 可能有多张, 默认显示第1张
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/cf/{user_id}", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/cf/{user_id}/count", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/cf/{user_id}/{no}", crate::sitepages::upload0::image_viewer);
    // 处理所有用户毕业证书显示 diploma_picture (dp), 可能有多张, 默认显示第1张
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/dp/{user_id}", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/dp/{user_id}/count", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/m/dp/{user_id}/{no}", crate::sitepages::upload0::image_viewer);
    // public restful
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/public/generate_api_key", crate::actions::public::generate_api_key);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/generate_pgp_key", crate::actions::public::generate_pgp_key);
    // url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/generate_pgp_key2", crate::actions::public::generate_pgp_key2);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/generate_pgp_fingerprint", crate::actions::public::generate_pgp_fingerprint);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/pgp_signer", crate::actions::public::pgp_signer);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/pgp_encrypt", crate::actions::public::pgp_encrypt);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/pgp_decrypt", crate::actions::public::pgp_decrypt);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/public/pgp_verify", crate::actions::public::pgp_verify);
    // developer index
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer", crate::sitepages::developer::developer);
    // developer algorithm
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/algorithm", crate::sitepages::developer::algorithm::algorithm_index);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/algorithm/mandelbrot", crate::sitepages::developer::algorithm::mandelbrot);
    // developer tools
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/toolkit/base64_string", crate::sitepages::developer::base64_string);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/toolkit/gretting/{name}", crate::sitepages::developer::gretting);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/toolkit/format_durations", crate::sitepages::developer::format_durations);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/toolkit/compute_password_hash", crate::sitepages::developer::compute_password_hash);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/developer/toolkit/verify_password_hash", crate::sitepages::developer::verify_password_hash);
    // developer datetime
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/map_of", crate::actions::developer::map_of);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/developer/to_datetime_string", crate::actions::developer::to_datetime_string);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/developer/parse_datetime_string_to_millis", crate::actions::developer::parse_datetime_string_to_millis);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/developer/excel/read_excel_to_vec", crate::actions::excel::excel_index);
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/letex/latex_to_pdf", crate::actions::letex::latex_index);
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/pdf/pdf_gen", crate::actions::pdf::pdf_index);
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/pdf/pdf_shape", crate::actions::pdf::pdf_shape);
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/pdf/pdf_table", crate::actions::pdf::pdf_table);

    url_dispatch(cfg, ctx.clone(), "post", &P0, "/developer/convert_to_unicode_escape", crate::actions::developer::convert_to_unicode_escape);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/developer/format_jsonstring", crate::actions::developer::format_jsonstring);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/text_compare", crate::sitepages::developer::text_compare);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/js_beautify", crate::sitepages::developer::js_beautify);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/iphone13", crate::sitepages::developer::iphone13);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/cronitor", crate::sitepages::developer::cronitor);
    // developer qrcode
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/developer/qrcode", crate::sitepages::qrcode::qrcode_index);
    // libvps
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/libvips/progressive_image", crate::actions::libvips_lab::progressive_image);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/libvips/progressive_render", crate::actions::libvips_lab::progressive_render);

    // developer isql
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/generator/isql", crate::sitepages::developer::isql::index);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/generator/isql/gen_code", crate::sitepages::developer::isql::gen_code);
    // developer json to struct
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/generator/json", crate::sitepages::developer::generator::json_to_struct);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/generator/json/to_struct", crate::sitepages::developer::generator::json_to_struct);

    // labs
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/curd_post", crate::actions::labs::curd_lab::post_test);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/curd_get", crate::actions::labs::curd_lab::get_test);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/captcha", crate::actions::labs::captcha_lab::captcha);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/kafka_producer", crate::actions::labs::kafka_lab::kafka_producer);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/mongodb_save", crate::actions::labs::mongodb_lab::mongodb_save);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/find_one", crate::actions::labs::mongodb_lab::find_one);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/mongo_query_list", crate::actions::labs::mongodb_lab::query_list);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/serde_date_format", crate::actions::labs::serde_lab::date_format);

    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/nats_list_stream", crate::actions::labs::nats_lab::list_stream);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/nats_create_stream", crate::actions::labs::nats_lab::create_stream);
    url_dispatch(cfg, ctx.clone(), "delete", &P0, "/actions/labs/nats_delete_stream", crate::actions::labs::nats_lab::delete_stream);
    url_dispatch(cfg, ctx.clone(), "patch", &P0, "/actions/labs/nats_remove_subject", crate::actions::labs::nats_lab::remove_subject);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/nats_add_subscribe", crate::actions::labs::nats_lab::add_subscribe);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/nats_publish", crate::actions::labs::nats_lab::publish);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/nats_subscribe", crate::actions::labs::nats_lab::subscribe);   // 消费消息
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/nats_listen", crate::actions::labs::nats_lab::listen);         // 监听消息
    url_dispatch(cfg, ctx.clone(), "delete", &P0, "/actions/labs/nats_delete_consumer", crate::actions::labs::nats_lab::unsubscribe);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/nats_unsubscribe", crate::actions::labs::nats_lab::unsubscribe);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/nats_list_consumer", crate::actions::labs::nats_lab::list_consumer);

    // error2
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/error2_1", crate::actions::labs::error2_lab::error2_1);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/error2_2", crate::actions::labs::error2_lab::error2_2);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/error2_3", crate::actions::labs::error2_lab::error2_3);

    // curl -N 'http://localhost:9100/actions/labs/streams'
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/streams_text", crate::actions::labs::streaming_lab::streaming_index);
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/streams_image", crate::actions::labs::streaming_lab::streaming_image);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/channel_subscribe", crate::actions::labs::channel_lab::channel_subscribe);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/task_streaming", crate::actions::labs::streaming_lab::task_streaming);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/current_feature", crate::actions::labs::current_feature);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/jwt_encode/{id}", crate::actions::labs::jwt_encode);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/jwt_decode/{key}", crate::actions::labs::jwt_decode);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/jwt_protected", crate::actions::labs::jwt_protected);

    // rudis
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/rudis/set", crate::actions::labs::rudis_lab::set);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/rudis/get", crate::actions::labs::rudis_lab::get);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/rudis/ttl", crate::actions::labs::rudis_lab::ttl);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/rudis/exists", crate::actions::labs::rudis_lab::exists);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/rudis/rpub", crate::actions::labs::rudis_lab::rpub);
    // curl -N "http://localhost:8000/actions/labs/rudis/rsub?topic=one_topic"
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/rudis/rsub", crate::actions::labs::rudis_lab::rsub);

    // encrypt
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/generate_random_16_string", crate::actions::labs::generate_random_16_string);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/generate_random_32_string", crate::actions::labs::generate_random_32_string);

    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/encrypt_aes_256", crate::actions::labs::encrypt_aes_256);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/decrypt_aes_256", crate::actions::labs::decrypt_aes_256);

    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/parse_datetime", crate::actions::labs::parse_datetime);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/es_save", crate::actions::labs::es_save);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/es_save2", crate::actions::labs::es_save2);
    url_dispatch(cfg, ctx.clone(), "patch", &P0, "/actions/labs/es_update", crate::actions::labs::es_update);
    url_dispatch(cfg, ctx.clone(), "delete", &P0, "/actions/labs/es_delete", crate::actions::labs::es_delete);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/es_query_single", crate::actions::labs::es_query_single);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/es_select", crate::actions::labs::es_select);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/es_select_after", crate::actions::labs::es_select_after);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/big_decimal", crate::actions::labs::big_decimal);
    // mysql
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/mysql_select", crate::actions::labs::mysql_select);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/mysql_save_region", crate::actions::labs::mysql_save_region);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/mysql_save_region_bulk", crate::actions::labs::mysql_save_region_bulk);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/mysql_save_kline_bulk", crate::actions::labs::mysql_save_kline_bulk);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/mysql_select_kline", crate::actions::labs::mysql_select_kline);
    // csv
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/read_csv_file", crate::actions::labs::read_csv_file);
    // xml
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/render_xml", crate::actions::labs::render_xml);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/{tail:.*}.shtml", crate::actions::labs::render_shtml);

    // xml
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/actions/labs/qrcode_detect", crate::actions::labs::qrcode_lab::detect_grids);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/actions/labs/generate_otpcode", crate::actions::labs::qrcode_lab::generate_otpcode);

    // google maps
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/maps_api/get_route_between_coordinates", crate::actions::google_maps::get_route_between_coordinates);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/maps_api/geocoding", crate::actions::google_maps::geocoding);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/maps_api/reverse_geocoding", crate::actions::google_maps::reverse_geocoding);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/maps_api/auto_complete_search", crate::actions::google_maps::auto_complete_search);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/maps_api/place_details", crate::actions::google_maps::place_details);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/maps_api/lookup_address_photo", crate::actions::google_maps::lookup_address_photo);

    // 旋转图片
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/x-image/{tail:.*}", crate::controllers::rotate90);

    // websocket speet test
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/speed-tests", crate::websocket::speed_tests::test_page);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/speed-tests/ws", crate::websocket::speed_tests::ws);

    // websocket devstream
    // wscat --no-check -c ws://127.0.0.1:8000/devstream/ws
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/devstream/ws", crate::websocket::devstreams::ws);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/devstream/broadcast", crate::websocket::devstreams::broadcast);

    // websocket actor less echo server
    // websocat -v --ping-interval=2 ws://127.0.0.1:8000/websocat/echo/ws
    // wscat --no-check -H "Authorization: Bearer $TOKEN" -c http://127.0.0.1:8000/websocat/echo/ws
    // wscat --no-check -H "Authorization: Bearer <YOUR_TOKEN_HERE>" -c http://127.0.0.1:8000/websocat/echo/ws
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/websocat/echo/ws", crate::core::websocat::echo::restful::ws);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/websocat/echo/total", crate::core::websocat::echo::restful::total);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/websocat/echo/users_online", crate::core::websocat::echo::restful::users_online);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/websocat/echo/all_connections", crate::core::websocat::echo::restful::all_connections);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/websocat/echo/closing", crate::core::websocat::echo::restful::closing);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/websocat/echo/broadcast", crate::core::websocat::echo::restful::broadcast);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/websocat/echo/talk_message", crate::core::websocat::echo::restful::talk_message);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/websocat/echo/send_message", crate::core::websocat::echo::restful::send_message);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/websocat/echo/history_message", crate::core::websocat::echo::restful::history_message);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/websocat/echo/query_history_msg", crate::core::websocat::echo::restful::query_history_msg);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/websocat/echo/query_last_message", crate::core::websocat::echo::restful::query_last_message);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/websocat/echo/history_talk", crate::core::websocat::echo::restful::history_talk);

    // websocat webchat page
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/webchat", crate::sitepages::webchat::index);

    // graphiql
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/graphiql", crate::graphql::graphiql);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/graphql", crate::graphql::graphql);

    // upload form
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/file_upload", crate::sitepages::upload0::file_upload_form);
    // upload images
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/upload_images", crate::sitepages::upload0::upload_images);
    // upload videos
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/upload_videos", crate::sitepages::upload0::upload_videos);

    // view image or videos
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/images/{image_id}", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/image/{image_id}", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/video/{video_id}", crate::sitepages::upload0::image_viewer);
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/file/get_file_by_md5", crate::sitepages::upload0::get_file_by_md5);

    url_dispatch(cfg, ctx.clone(), "get", &U1, "/download", crate::sitepages::upload0::download);
    // newsletters
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/subscriptions", crate::sitepages::subscribe);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/subscriptions/confirm", crate::sitepages::confirm_subscription);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/newsletters/list_confirmed_subscribers", crate::sitepages::list_confirmed_subscribers);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/newsletters/publish_newsletter", crate::sitepages::publish_newsletter_v2);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/newsletters", crate::sitepages::publish_newsletter_form);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/send_email", crate::sitepages::send_email);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/send_emails", crate::sitepages::send_emails);
    // notes
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/notes/note-list", crate::actions::notes::list_notes);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/notes/note-create", crate::actions::notes::create_note);
    url_dispatch(cfg, ctx.clone(), "get", &U1, "/notes/details/{note_id}", crate::actions::notes::note_details);
    url_dispatch(cfg, ctx.clone(), "patch", &U1, "/notes/update/{note_id}", crate::actions::notes::update_note);
    url_dispatch(cfg, ctx.clone(), "delete", &U1, "/notes/{note_id}", crate::actions::notes::delete_note);
    // youtube
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube", crate::sitepages::youtube::dl);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube/check", crate::sitepages::youtube::check);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube/content_length", crate::sitepages::youtube::content_length);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube/descrambler", crate::sitepages::youtube::descrambler);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube/best_quality", crate::sitepages::youtube::best_quality);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube/dl", crate::sitepages::youtube::dl);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/youtube/dl_async", crate::sitepages::youtube::dl_async);
    // url_dispatch(cfg, ctx.clone(), "get", &P0, "/youtube/video_frame", crate::sitepages::youtube::video_frame);
    // gps
    // wscat --no-check -c ws://127.0.0.1:8000/livestreaming
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/gpss", crate::sitepages::gpss::gps_index);
    // feeds
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/feeds", crate::sitepages::feeds::feeds_index);
    // 列表页
    url_dispatch(cfg, ctx.clone(), "get", &P0, "/w1pn0l", crate::sitepages::w1pn0l::w1pn0l_index);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/feeds/new", crate::sitepages::feeds::feeds_create);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/feeds/new/thumb_up", crate::sitepages::feeds::feeds_thumb_up);
    url_dispatch(cfg, ctx.clone(), "post", &U1, "/feeds/comment_post", crate::sitepages::feeds::comment_post);

    // url_dispatch(cfg, ctx.clone(), "post", &P0, "/locations/filter_locaitons", crate::actions::location::filter_locaitons);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/locations/upload_locaitons", crate::actions::location::upload_locaitons);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/app_logs/upload_app_log", crate::actions::app_logs::upload_app_logs);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/app_logs/upload_network_log", crate::actions::app_logs::upload_network_log);
    url_dispatch(cfg, ctx.clone(), "post", &P0, "/app_logs/upload_tasks_log", crate::actions::app_logs::upload_tasks_log);

    // config upstreams
    if let Some(up) = upstreams {
        for up in &up {
            if let Some(true) = up.enable {
                // url_dispatch(cfg, ctx.clone(), "*", &P0, &format!("/{}", "{upstream:".to_owned() + up.location.trim_start_matches('/') + "}{tail:.*}"), upstream::process);
                url_dispatch(cfg, ctx.clone(), "Any", &P0, &format!("/{}", "{forward:".to_owned() + up.location.trim_start_matches('/') + "}{tail:.*}"), upstream::forward_reqwest);
            }
        }
    }
}