@@ -840,11 +840,11 @@ httpGetContentEncoding(http_t *http) // I - HTTP connection
840840
841841
842842//
843- // 'httpGetCookie()' - Get "Cookie:" data from the HTTP connection.
843+ // 'httpGetCookie()' - Get cookie data from the HTTP connection.
844844//
845- // This function returns any HTTP "Cookie:" header data for the given HTTP
846- // connection as described in RFC 6265. Use the @link httpGetCookieValue@ to
847- // get the value of a named cookie .
845+ // This function returns any HTTP "Set- Cookie:" or "Cookie:" header data for the
846+ // given HTTP connection as described in RFC 6265. Use the
847+ // @link httpGetCookieValue@ to get the value of a named "Cookie:" value .
848848//
849849
850850const char * // O - Cookie data or `NULL`
@@ -2205,22 +2205,46 @@ httpSetBlocking(http_t *http, // I - HTTP connection
22052205
22062206
22072207//
2208- // 'httpSetCookie()' - Set the cookie value(s).
2208+ // 'httpSetCookie()' - Add Set-Cookie value(s).
2209+ //
2210+ // This function adds one or more Set-Cookie header values that will be sent to
2211+ // the client with the @link httpWriteResponse@ function. Each value conforms
2212+ // to the format defined in RFC 6265. Multiple values can be passed in the
2213+ // "cookie" string separated by a newline character.
2214+ //
2215+ // Call the @link httpClearCookies@ function to clear all Set-Cookie values.
22092216//
22102217
22112218void
22122219httpSetCookie (http_t * http , // I - Connection
22132220 const char * cookie ) // I - Cookie string
22142221{
2215- if (!http )
2222+ // Range check input...
2223+ if (!http || !cookie )
22162224 return ;
22172225
2218- free (http -> cookie );
2226+ // Set or append the Set-Cookie value....
2227+ if (http -> cookie )
2228+ {
2229+ // Append with a newline between values...
2230+ size_t clen , // Length of cookie string
2231+ ctotal ; // Total length of cookies
2232+ char * temp ; // Temporary value
22192233
2220- if (cookie )
2221- http -> cookie = strdup (cookie );
2234+ clen = strlen (http -> cookie );
2235+ ctotal = clen + strlen (cookie ) + 2 ;
2236+
2237+ if ((temp = realloc (http -> cookie , ctotal )) == NULL )
2238+ return ;
2239+
2240+ temp [clen ] = '\n' ;
2241+ cupsCopyString (temp + clen + 1 , cookie , ctotal - clen - 1 );
2242+ }
22222243 else
2223- http -> cookie = NULL ;
2244+ {
2245+ // Just copy/set this cookie...
2246+ http -> cookie = strdup (cookie );
2247+ }
22242248}
22252249
22262250
@@ -3050,26 +3074,35 @@ httpWriteResponse(http_t *http, // I - HTTP connection
30503074
30513075 if (http -> cookie )
30523076 {
3053- if (strchr (http -> cookie , ';' ))
3077+ char * start , // Start of cookie
3078+ * ptr ; // Pointer into cookie
3079+
3080+ for (start = http -> cookie ; start ; start = ptr )
30543081 {
3055- if (httpPrintf (http , "Set-Cookie: %s\r\n" , http -> cookie ) < 1 )
3082+ if ((ptr = strchr (start , '\n' )) != NULL )
3083+ * ptr = '\0' ;
3084+
3085+ if (strchr (start , ';' ))
3086+ {
3087+ if (httpPrintf (http , "Set-Cookie: %s\r\n" , start ) < 1 )
3088+ {
3089+ http -> status = HTTP_STATUS_ERROR ;
3090+ if (ptr )
3091+ * ptr = '\n' ;
3092+ return (false);
3093+ }
3094+ }
3095+ else if (httpPrintf (http , "Set-Cookie: %s; path=/; httponly;%s\r\n" , http -> cookie , http -> tls ? " secure;" : "" ) < 1 )
30563096 {
30573097 http -> status = HTTP_STATUS_ERROR ;
3098+ if (ptr )
3099+ * ptr = '\n' ;
30583100 return (false);
30593101 }
3060- }
3061- else if (httpPrintf (http , "Set-Cookie: %s; path=/; httponly;%s\r\n" , http -> cookie , http -> tls ? " secure;" : "" ) < 1 )
3062- {
3063- http -> status = HTTP_STATUS_ERROR ;
3064- return (false);
3065- }
3066- }
30673102
3068- // "Click-jacking" defense...
3069- if (httpPrintf (http , "X-Frame-Options: DENY\r\nContent-Security-Policy: frame-ancestors 'none'\r\n" ) < 1 )
3070- {
3071- http -> status = HTTP_STATUS_ERROR ;
3072- return (false);
3103+ if (ptr )
3104+ * ptr ++ = '\n' ;
3105+ }
30733106 }
30743107 }
30753108
0 commit comments