LCOV - code coverage report
Current view: top level - libs/http_proto/src/server - cors.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 0.0 % 77 0
Test Date: 2025-12-05 19:49:25 Functions: 0.0 % 11 0

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
       3              : //
       4              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6              : //
       7              : // Official repository: https://github.com/cppalliance/http_proto
       8              : //
       9              : 
      10              : #include <boost/http_proto/server/cors.hpp>
      11              : #include <utility>
      12              : 
      13              : namespace boost {
      14              : namespace http_proto {
      15              : 
      16            0 : cors::
      17              : cors(
      18            0 :     cors_options options) noexcept
      19            0 :     : options_(std::move(options))
      20              : {
      21              :     // VFALCO TODO Validate the strings in options against RFC
      22            0 : }
      23              : 
      24              : namespace {
      25              : 
      26              : struct Vary
      27              : {
      28            0 :     Vary(route_params& p)
      29            0 :         : p_(p)
      30              :     {
      31            0 :     }
      32              : 
      33            0 :     void set(field f, core::string_view s)
      34              :     {
      35            0 :         p_.res.set(f, s);
      36            0 :     }
      37              : 
      38            0 :     void append(field f, core::string_view v)
      39              :     {
      40            0 :         auto it = p_.res.find(f);
      41            0 :         if (it != p_.res.end())
      42              :         {
      43            0 :             std::string s = it->value;
      44            0 :             s += ", ";
      45            0 :             s += v;
      46            0 :             p_.res.set(it, s);
      47            0 :         }
      48              :         else
      49              :         {
      50            0 :             p_.res.set(f, v);
      51              :         }
      52            0 :     }
      53              : 
      54              : private:
      55              :     route_params& p_;
      56              :     std::string v_;
      57              : };
      58              : 
      59              : } // (anon)
      60              : 
      61              : // Access-Control-Allow-Origin
      62            0 : static void setOrigin(
      63              :     Vary& v,
      64              :     route_params const&,
      65              :     cors_options const& options)
      66              : {
      67            0 :     if( options.origin.empty() ||
      68            0 :         options.origin == "*")
      69              :     {
      70            0 :         v.set(field::access_control_allow_origin, "*");
      71            0 :         return;
      72              :     }
      73              : 
      74            0 :     v.set(
      75              :         field::access_control_allow_origin,
      76            0 :         options.origin);
      77            0 :     v.append(field::vary, to_string(field::origin));
      78              : }
      79              : 
      80              : // Access-Control-Allow-Methods
      81            0 : static void setMethods(
      82              :     Vary& v,
      83              :     cors_options const& options)
      84              : {
      85            0 :     if(! options.methods.empty())
      86              :     {
      87            0 :         v.set(
      88              :             field::access_control_allow_methods,
      89            0 :             options.methods);
      90            0 :         return;
      91              :     }
      92            0 :     v.set(
      93              :         field::access_control_allow_methods,
      94              :         "GET,HEAD,PUT,PATCH,POST,DELETE");
      95              : }
      96              : 
      97              : // Access-Control-Allow-Credentials
      98            0 : static void setCredentials(
      99              :     Vary& v,
     100              :     cors_options const& options)
     101              : {
     102            0 :     if(! options.credentials)
     103            0 :         return;
     104            0 :     v.set(
     105              :         field::access_control_allow_credentials,
     106              :         "true");
     107              : }
     108              : 
     109              : // Access-Control-Allowed-Headers
     110            0 : static void setAllowedHeaders(
     111              :     Vary& v,
     112              :     route_params const& p,
     113              :     cors_options const& options)
     114              : {
     115            0 :     if(! options.allowedHeaders.empty())
     116              :     {
     117            0 :         v.set(
     118              :             field::access_control_allow_headers,
     119            0 :             options.allowedHeaders);
     120            0 :         return;
     121              :     }
     122            0 :     auto s = p.res.value_or(
     123              :         field::access_control_request_headers, "");
     124            0 :     if(! s.empty())
     125              :     {
     126            0 :         v.set(field::access_control_allow_headers, s);
     127            0 :         v.append(field::vary, s);
     128              :     }
     129              : }
     130              : 
     131              : // Access-Control-Expose-Headers
     132            0 : static void setExposeHeaders(
     133              :     Vary& v,
     134              :     cors_options const& options)
     135              : {
     136            0 :     if(options.exposedHeaders.empty())
     137            0 :         return;
     138            0 :     v.set(
     139              :         field::access_control_expose_headers,
     140            0 :         options.exposedHeaders);
     141              : }
     142              : 
     143              : // Access-Control-Max-Age
     144            0 : static void setMaxAge(
     145              :     Vary& v,
     146              :     cors_options const& options)
     147              : {
     148            0 :     if(options.max_age.count() == 0)
     149            0 :         return;
     150            0 :     v.set(
     151              :         field::access_control_max_age,
     152            0 :         std::to_string(
     153              :             options.max_age.count()));
     154              : }
     155              : 
     156              : route_result
     157            0 : cors::
     158              : operator()(
     159              :     route_params& p) const
     160              : {
     161            0 :     Vary v(p);
     162            0 :     if(p.req.method() ==
     163              :         method::options)
     164              :     {
     165              :         // preflight
     166            0 :         setOrigin(v, p, options_);
     167            0 :         setMethods(v, options_);
     168            0 :         setCredentials(v, options_);
     169            0 :         setAllowedHeaders(v, p, options_);
     170            0 :         setMaxAge(v, options_);
     171            0 :         setExposeHeaders(v, options_);
     172              : 
     173            0 :         if(options_.preFligthContinue)
     174            0 :             return route::next;
     175              :         // Safari and others need this for 204 or may hang
     176            0 :         p.res.set_status(options_.result);
     177            0 :         p.res.set_content_length(0);
     178            0 :         p.serializer.start(p.res);
     179            0 :         return route::send;
     180              :     }
     181              :     // actual response
     182            0 :     setOrigin(v, p, options_);
     183            0 :     setCredentials(v, options_);
     184            0 :     setExposeHeaders(v, options_);
     185            0 :     return route::next;
     186            0 : }
     187              : 
     188              : } // http_proto
     189              : } // boost
        

Generated by: LCOV version 2.1