| 101 | } // namespace |
| 102 | |
| 103 | int caf_main(caf::actor_system& sys, const config& cfg) { |
| 104 | namespace ssl = caf::net::ssl; |
| 105 | namespace http = caf::net::http; |
| 106 | // Do a regular shutdown for CTRL+C and SIGTERM. |
| 107 | signal(SIGTERM, set_shutdown_flag); |
| 108 | signal(SIGINT, set_shutdown_flag); |
| 109 | // Read the configuration. |
| 110 | auto port = caf::get_or(cfg, "port", default_port); |
| 111 | auto pem = ssl::format::pem; |
| 112 | auto key_file = caf::get_as<std::string>(cfg, "tls.key-file"); |
| 113 | auto cert_file = caf::get_as<std::string>(cfg, "tls.cert-file"); |
| 114 | auto max_connections = caf::get_or(cfg, "max-connections", |
| 115 | default_max_connections); |
| 116 | auto max_request_size = caf::get_or( |
| 117 | cfg, "max-request-size", caf::defaults::net::http_max_request_size); |
| 118 | if (!key_file != !cert_file) { |
| 119 | sys.println("*** inconsistent TLS config: declare neither file or both"); |
| 120 | return EXIT_FAILURE; |
| 121 | } |
| 122 | // Spin up our key-value store actor. |
| 123 | auto kvs = sys.spawn(caf::actor_from_state<kvs_actor_state>); |
| 124 | // Open up a TCP port for incoming connections and start the server. |
| 125 | auto server |
| 126 | = http::with(sys) |
| 127 | // Optionally enable TLS. |
| 128 | .context(ssl::context::enable(key_file && cert_file) |
| 129 | .and_then(ssl::emplace_server(ssl::tls::v1_2)) |
| 130 | .and_then(ssl::use_private_key_file(key_file, pem)) |
| 131 | .and_then(ssl::use_certificate_file(cert_file, pem))) |
| 132 | // Bind to the user-defined port. |
| 133 | .accept(port) |
| 134 | // Limit how many clients may be connected at any given time. |
| 135 | .max_connections(max_connections) |
| 136 | // Limit the maximum request size. |
| 137 | .max_request_size(max_request_size) |
| 138 | // Stop the server if our key-value store actor terminates. |
| 139 | .monitor(kvs) |
| 140 | // Forward incoming requests to the kvs actor. |
| 141 | .route("/api/<arg>", http::method::get, |
| 142 | [kvs](http::responder& res, std::string key) { |
| 143 | auto* self = res.self(); |
| 144 | auto prom = std::move(res).to_promise(); |
| 145 | self->mail(caf::get_atom_v, std::move(key)) |
| 146 | .request(kvs, 2s) |
| 147 | .then( |
| 148 | [prom](const std::string& value) mutable { |
| 149 | prom.respond(http::status::ok, "text/plain", value); |
| 150 | }, |
| 151 | [prom](const caf::error& what) mutable { |
| 152 | if (what == caf::sec::no_such_key) |
| 153 | prom.respond(http::status::not_found, "text/plain", |
| 154 | "Key not found."); |
| 155 | else |
| 156 | prom.respond(http::status::internal_server_error, |
| 157 | what); |
| 158 | }); |
| 159 | }) |
| 160 | .route("/api/<arg>", http::method::post, |
nothing calls this directly
no test coverage detected