-
Notifications
You must be signed in to change notification settings - Fork 11
more #245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
more #245
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| description: Documentation style conventions for code snippets, javadocs, and API documentation examples | ||
| globs: | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| - `route_params` are named `rp` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,31 +18,73 @@ | |
| namespace boost { | ||
| namespace http { | ||
|
|
||
| /** Options for CORS middleware configuration. | ||
| */ | ||
| struct cors_options | ||
| { | ||
| /// Allowed origin, or "*" for any. Empty defaults to "*". | ||
| std::string origin; | ||
|
|
||
| /// Allowed HTTP methods. Empty defaults to common methods. | ||
| std::string methods; | ||
|
|
||
| /// Allowed request headers. | ||
| std::string allowedHeaders; | ||
|
|
||
| /// Response headers exposed to client. | ||
| std::string exposedHeaders; | ||
|
|
||
| /// Max age for preflight cache. | ||
| std::chrono::seconds max_age{ 0 }; | ||
|
|
||
| /// Status code for preflight response. | ||
| status result = status::no_content; | ||
|
|
||
| /// If true, pass preflight to next handler. | ||
| bool preFlightContinue = false; | ||
|
|
||
| /// If true, allow credentials. | ||
| bool credentials = false; | ||
| }; | ||
|
|
||
| class cors | ||
| /** CORS middleware for handling cross-origin requests. | ||
| This middleware handles Cross-Origin Resource Sharing | ||
| (CORS) by setting appropriate response headers and | ||
| handling preflight OPTIONS requests. | ||
| @par Example | ||
| @code | ||
| cors_options opts; | ||
| opts.origin = "*"; | ||
| opts.methods = "GET,POST,PUT,DELETE"; | ||
| opts.credentials = true; | ||
| router.use( cors( opts ) ); | ||
| @endcode | ||
| @see cors_options | ||
| */ | ||
| class BOOST_HTTP_DECL cors | ||
| { | ||
| cors_options options_; | ||
|
|
||
| public: | ||
| BOOST_HTTP_DECL | ||
| explicit cors( | ||
| cors_options options = {}) noexcept; | ||
| /** Construct a CORS middleware. | ||
| BOOST_HTTP_DECL | ||
| route_result | ||
| operator()(route_params& p) const; | ||
| @param options Configuration options. | ||
| */ | ||
| explicit cors(cors_options options = {}) noexcept; | ||
|
|
||
| private: | ||
| cors_options options_; | ||
| /** Handle a request. | ||
| Sets CORS headers and handles preflight requests. | ||
| @param rp The route parameters. | ||
| @return A task that completes with the routing result. | ||
| */ | ||
| route_task operator()(route_params& rp) const; | ||
| }; | ||
|
Comment on lines
+68
to
88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Short answer: The standard never guaranteed that every std::string move constructor is noexcept across C++11/C++14; it was implementation-/form-dependent (allocator forms could throw). The language rules for implicitly‑declared/defaulted move constructors’ exception specification are in the core language (and evolved), but library wording and LWG discussion show basic_string’s move/noexcept was tricky and not an absolute, unconditional guarantee. See cppreference for the language rules and the LWG issues (2069, 2319) about basic_string’s noexcept wording. [1][2][3] Sources
🏁 Script executed: # Search for cors_options definition
rg -n "class cors_options|struct cors_options" include/Repository: cppalliance/http Length of output: 117 🏁 Script executed: # Check for C++ standard configuration
find . -name "CMakeLists.txt" -o -name "cmake.txt" -o -name ".clang-format" -o -name "*.h" -o -name "*.hpp" | head -20 | xargs grep -l "std=c++" 2>/dev/null || echo "Searching for standard flags..."Repository: cppalliance/http Length of output: 91 🏁 Script executed: # Look at the top of the header file for any C++ standard comments or includes
head -50 include/boost/http/server/cors.hppRepository: cppalliance/http Length of output: 1369 Remove The constructor is marked 🤖 Prompt for AI Agents |
||
|
|
||
| } // http | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // | ||
| // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| // | ||
| // Official repository: https://github.com/cppalliance/http | ||
| // | ||
|
|
||
| #ifndef BOOST_HTTP_SERVER_ENCODE_URL_HPP | ||
| #define BOOST_HTTP_SERVER_ENCODE_URL_HPP | ||
|
|
||
| #include <boost/http/detail/config.hpp> | ||
| #include <boost/core/detail/string_view.hpp> | ||
| #include <string> | ||
|
|
||
| namespace boost { | ||
| namespace http { | ||
|
|
||
| /** Percent-encode a URL for safe use in HTTP responses. | ||
| Encodes characters that are not safe in URLs using | ||
| percent-encoding (e.g. space becomes %20). This is | ||
| useful for encoding URLs that will be included in | ||
| Location headers or HTML links. | ||
| The following characters are NOT encoded: | ||
| - Unreserved: A-Z a-z 0-9 - _ . ~ | ||
| - Reserved (allowed in URLs): ! # $ & ' ( ) * + , / : ; = ? @ | ||
| @par Example | ||
| @code | ||
| std::string url = encode_url( "/path/to/file with spaces.txt" ); | ||
| // url == "/path/to/file%20with%20spaces.txt" | ||
| @endcode | ||
| @param url The URL or URL component to encode. | ||
| @return A new string with unsafe characters percent-encoded. | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| */ | ||
| BOOST_HTTP_DECL | ||
| std::string | ||
| encode_url(core::string_view url); | ||
|
|
||
| } // http | ||
| } // boost | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // | ||
| // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| // | ||
| // Official repository: https://github.com/cppalliance/http | ||
| // | ||
|
|
||
| #ifndef BOOST_HTTP_SERVER_ESCAPE_HTML_HPP | ||
| #define BOOST_HTTP_SERVER_ESCAPE_HTML_HPP | ||
|
|
||
| #include <boost/http/detail/config.hpp> | ||
| #include <boost/core/detail/string_view.hpp> | ||
| #include <string> | ||
|
|
||
| namespace boost { | ||
| namespace http { | ||
|
|
||
| /** Escape a string for safe inclusion in HTML. | ||
|
|
||
| Replaces characters that have special meaning in HTML | ||
| with their corresponding character entity references: | ||
|
|
||
| @li `&` becomes `&` | ||
| @li `<` becomes `<` | ||
| @li `>` becomes `>` | ||
| @li `"` becomes `"` | ||
| @li `'` becomes `'` | ||
|
|
||
| This function is used to prevent XSS (Cross-Site Scripting) | ||
| attacks when embedding user input in HTML responses. | ||
|
|
||
| @par Example | ||
| @code | ||
| std::string safe = escape_html( "<script>alert('xss')</script>" ); | ||
| // safe == "<script>alert('xss')</script>" | ||
| @endcode | ||
|
|
||
| @param s The string to escape. | ||
|
|
||
| @return A new string with HTML special characters escaped. | ||
| */ | ||
| BOOST_HTTP_DECL | ||
| std::string | ||
| escape_html(core::string_view s); | ||
|
|
||
| } // http | ||
| } // boost | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| // | ||
| // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| // | ||
| // Official repository: https://github.com/cppalliance/http | ||
| // | ||
|
|
||
| #ifndef BOOST_HTTP_SERVER_ETAG_HPP | ||
| #define BOOST_HTTP_SERVER_ETAG_HPP | ||
|
|
||
| #include <boost/http/detail/config.hpp> | ||
| #include <boost/core/detail/string_view.hpp> | ||
| #include <cstdint> | ||
| #include <string> | ||
|
|
||
| namespace boost { | ||
| namespace http { | ||
|
|
||
| /** Options for ETag generation. | ||
| */ | ||
| struct etag_options | ||
| { | ||
| /// Generate a weak ETag (prefixed with W/). | ||
| bool weak = false; | ||
| }; | ||
|
|
||
| /** Generate an ETag from content. | ||
| Creates an ETag by computing a hash of the provided | ||
| content. The resulting ETag can be used in HTTP | ||
| responses to enable caching. | ||
| @par Example | ||
| @code | ||
| std::string content = "Hello, World!"; | ||
| std::string tag = etag( content ); | ||
| // tag == "\"d-3/1gIbsr1bCvZ2KQgJ7DpTGR3YH\"" | ||
| @endcode | ||
|
Comment on lines
+35
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation example may not match actual output format. The example shows Consider updating the example to reflect the actual output format, or mark it as illustrative only. 🤖 Prompt for AI Agents |
||
| @param body The content to hash. | ||
| @param opts Options controlling ETag generation. | ||
| @return An ETag string suitable for use in the ETag header. | ||
| */ | ||
| BOOST_HTTP_DECL | ||
| std::string | ||
| etag(core::string_view body, etag_options opts = {}); | ||
|
|
||
| /** Generate an ETag from file metadata. | ||
| Creates an ETag based on a file's size and modification | ||
| time. This is more efficient than hashing file content | ||
| and is suitable for static file serving. | ||
| @par Example | ||
| @code | ||
| std::uint64_t size = 1234; | ||
| std::uint64_t mtime = 1704067200; // Unix timestamp | ||
| std::string tag = etag( size, mtime ); | ||
| // tag == "\"4d2-65956a00\"" | ||
| @endcode | ||
| @param size The file size in bytes. | ||
| @param mtime The file modification time (typically Unix timestamp). | ||
| @param opts Options controlling ETag generation. | ||
| @return An ETag string suitable for use in the ETag header. | ||
| */ | ||
| BOOST_HTTP_DECL | ||
| std::string | ||
| etag( | ||
| std::uint64_t size, | ||
| std::uint64_t mtime, | ||
| etag_options opts = {}); | ||
|
|
||
| } // http | ||
| } // boost | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // | ||
| // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| // | ||
| // Official repository: https://github.com/cppalliance/http | ||
| // | ||
|
|
||
| #ifndef BOOST_HTTP_SERVER_FRESH_HPP | ||
| #define BOOST_HTTP_SERVER_FRESH_HPP | ||
|
|
||
| #include <boost/http/detail/config.hpp> | ||
| #include <boost/http/request.hpp> | ||
| #include <boost/http/response.hpp> | ||
|
|
||
| namespace boost { | ||
| namespace http { | ||
|
|
||
| /** Check if a response is fresh for conditional GET. | ||
|
|
||
| Compares the request's conditional headers (`If-None-Match` | ||
| and `If-Modified-Since`) against the response's caching | ||
| headers (`ETag` and `Last-Modified`) to determine if the | ||
| cached response is still valid. | ||
|
|
||
| If this returns `true`, the server should respond with | ||
| 304 Not Modified instead of sending the full response body. | ||
|
|
||
| @par Example | ||
| @code | ||
| // Prepare response headers | ||
| rp.res.set( field::etag, "\"abc123\"" ); | ||
| rp.res.set( field::last_modified, "Wed, 21 Oct 2024 07:28:00 GMT" ); | ||
|
|
||
| // Check freshness | ||
| if( is_fresh( rp.req, rp.res ) ) | ||
| { | ||
| rp.status( status::not_modified ); | ||
| co_return co_await rp.send( "" ); | ||
| } | ||
|
|
||
| // Send full response | ||
| co_return co_await rp.send( content ); | ||
| @endcode | ||
|
|
||
| @param req The HTTP request. | ||
|
|
||
| @param res The HTTP response (with ETag/Last-Modified set). | ||
|
|
||
| @return `true` if the response is fresh (304 should be sent), | ||
| `false` if the full response should be sent. | ||
|
|
||
| @see http::field::if_none_match, http::field::if_modified_since | ||
| */ | ||
| BOOST_HTTP_DECL | ||
| bool | ||
| is_fresh( | ||
| request const& req, | ||
| response const& res) noexcept; | ||
|
|
||
| } // http | ||
| } // boost | ||
|
|
||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define
globsor enablealwaysApplyso the rule actually runs.With
alwaysApply: falseand an emptyglobs, this rule likely won’t apply anywhere. Please add explicit doc globs or switch toalwaysApply: trueif it should be global.🤖 Prompt for AI Agents