Search code examples
c++regexhttpcookiecpprest-sdk

How to parse multiple Set-Cookie generated by cpprestsdk?


tgw_l7_route=d0bf4a9ab78d53762b596c0a48dabcdf; Expires=Thu, 03-May-2018 11:42:51 GMT; Path=/, session=a1d25e28-0084-421d-ae71-9ae18c7f6b50; Expires=Sun, 03-Jun-2018 10:42:51 GMT; HttpOnly; Path=/

There are 2 Set-Cookie items joined by ', ', the problem with this string is that the expires date also contains ', '.

This string is generated by cpprestsdk library. I need to parse it and generate a 'Cookie' header in order to send to server in on-going requests.

// Example program
#include <iostream>
#include <string>
#include <regex>
#include <iterator>

int main()
{
  std::string cookieStr = "tgw_l7_route=d0bf4a9ab78d53762b596c0a48dabcdf; Expires=Thu, 03-May-2018 11:42:51 GMT; Path=/, session=a1d25e28-0084-421d-ae71-9ae18c7f6b50; Expires=Sun, 03-Jun-2018 10:42:51 GMT; HttpOnly; Path=/";
  std::regex rgx(", [^ ]+=");
  std::sregex_token_iterator iter(cookieStr.begin(),
    cookieStr.end(),
    rgx,
    -1);
  std::sregex_token_iterator end;
  for ( ; iter != end; ++iter)
    std::cout << *iter << '\n';
}

Above code outputs:

tgw_l7_route=d0bf4a9ab78d53762b596c0a48dabcdf; Expires=Thu, 03-May-2018 11:42:51 GMT; Path=/ 
a1d25e28-0084-421d-ae71-9ae18c7f6b50; Expires=Sun, 03-Jun-2018 10:42:51 GMT; HttpOnly; Path=/

Is there a way to keep "session=" in the second string?


Solution

  • You need to wrap the pattern you use into a positive lookahead, a non-consuming construct.

    "(?=, [^ ]+=)"
     ^^^        ^
    

    This construct matches a location in the string that is immediately followed with a ,, a space, and then 1+ chars other than space and then a = sign without pushing the value matched into the match stack. It means that the matched text is not split upon, and it remains in the resulting array of split chunks.

    See the regex demo.

    C++ demo:

    std::string cookieStr = "tgw_l7_route=d0bf4a9ab78d53762b596c0a48dabcdf; Expires=Thu, 03-May-2018 11:42:51 GMT; Path=/, session=a1d25e28-0084-421d-ae71-9ae18c7f6b50; Expires=Sun, 03-Jun-2018 10:42:51 GMT; HttpOnly; Path=/";
    std::regex rgx("(?=, [^ ]+=)");
    std::sregex_token_iterator iter(cookieStr.begin(),
      cookieStr.end(),
      rgx,
      -1);
    std::sregex_token_iterator end;
    for ( ; iter != end; ++iter)
        std::cout << *iter << '\n';
    

    Output:

    tgw_l7_route=d0bf4a9ab78d53762b596c0a48dabcdf; Expires=Thu, 03-May-2018 11:42:51 GMT; Path=/
    , session=a1d25e28-0084-421d-ae71-9ae18c7f6b50; Expires=Sun, 03-Jun-2018 10:42:51 GMT; HttpOnly; Path=/