FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "StarWarsData.h" #include "graphqlservice/JSONResponse.h" #ifdef _MSC_VER #include #endif // _MSC_VER #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std::literals; using namespace graphql; namespace beast = boost::beast; namespace http = beast::http; namespace net = boost::asio; using tcp = boost::asio::ip::tcp; using tcp_stream = typename beast::tcp_stream::rebind_executor< net::use_awaitable_t::executor_with_default>::other; constexpr net::string_view c_host { "127.0.0.1" }; constexpr unsigned short c_port = 8080; constexpr beast::string_view c_target { "/graphql" }; // Based on: // https://www.boost.org/doc/libs/1_82_0/libs/beast/example/http/server/awaitable/http_server_awaitable.cpp int main() { auto service = star_wars::GetService(); std::cout net::awaitable { // This buffer is required to persist across reads beast::flat_buffer buffer; bool keepAlive = false; // This lambda is used to send messages try { do { // Set the timeout. stream.expires_after(std::chrono::seconds(30)); // Read a request http::request req; co_await http::async_read(stream, buffer, req); // Handle the request http::response msg; try { if (req.method() != http::verb::post || req.target() != c_target) { throw std::runtime_error( "Only POST requests to /graphql are supported."); } else { std::ostringstream oss; oss second.type() != response::Type::String) { throw std::runtime_error("Invalid request!"); } peg::ast query; query = peg::parseString( queryItr->second.get()); if (!query.root) { throw std::runtime_error("Unknown error!"); } const auto operationNameItr = payload.find("operationName"sv); const auto operationName = (operationNameItr != payload.end() && operationNameItr->second.type() == response::Type::String) ? std::string_view { operationNameItr->second .get() } : std::string_view {}; const auto variablesItr = payload.find("variables"sv); auto variables = (variablesItr != payload.end() && variablesItr->second.type() == response::Type::String) ? response::parseJSON( variablesItr->second.get()) : response::Value {}; msg = http::response { http::status::ok, req.version() }; msg.set(http::field::server, BOOST_BEAST_VERSION_STRING); msg.set(http::field::content_type, "application/json"); msg.keep_alive(req.keep_alive()); msg.body() = response::toJSON( service ->resolve( { query, operationName, std::move(variables) }) .get()); msg.prepare_payload(); } } catch (const std::runtime_error& ex) { msg = http::response { http::status::bad_request, req.version() }; msg.set(http::field::server, BOOST_BEAST_VERSION_STRING); msg.set(http::field::content_type, "text/plain"); msg.keep_alive(req.keep_alive()); msg.body() = "Error: "s + ex.what(); msg.prepare_payload(); } // Determine if we should close the connection keepAlive = msg.keep_alive(); // Send the response co_await beast::async_write(stream, http::message_generator { std::move(msg) }, net::use_awaitable); } while (keepAlive); } catch (boost::system::system_error& se) { if (se.code() != http::error::end_of_stream) throw; } // Send a TCP shutdown beast::error_code ec; stream.socket().shutdown(tcp::socket::shutdown_send, ec); // At this point the connection is closed gracefully // we ignore the error because the client might have // dropped the connection already. }(tcp_stream(co_await acceptor.async_accept()), service), [](std::exception_ptr exp) { if (exp) { try { std::rethrow_exception(exp); } catch (const std::exception& ex) { std::cerr

Back | FazBrowse Home | New Git URL