diff options
Diffstat (limited to 'ext/session/session.c')
-rw-r--r-- | ext/session/session.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/ext/session/session.c b/ext/session/session.c index b1fcd3a239..700eeed94f 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1275,6 +1275,49 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */ #define COOKIE_SECURE "; secure" #define COOKIE_HTTPONLY "; HttpOnly" +/* + * Remove already sent session ID cookie. + * It must be directly removed from SG(sapi_header) because sapi_add_header_ex() + * removes all of matching cookie. i.e. It deletes all of Set-Cookie headers. + */ +static void php_session_remove_cookie() { + sapi_header_struct *header; + zend_llist *l = &SG(sapi_headers).headers; + zend_llist_element *next; + zend_llist_element *current; + char *session_cookie, *e_session_name; + int session_cookie_len, len = sizeof("Set-Cookie")-1; + + e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL); + spprintf(&session_cookie, 0, "Set-Cookie: %s=", e_session_name); + efree(e_session_name); + + session_cookie_len = strlen(session_cookie); + current = l->head; + while (current) { + header = (sapi_header_struct *)(current->data); + next = current->next; + if (header->header_len > len && header->header[len] == ':' + && !strncmp(header->header, session_cookie, session_cookie_len)) { + if (current->prev) { + current->prev->next = next; + } else { + l->head = next; + } + if (next) { + next->prev = current->prev; + } else { + l->tail = current->prev; + } + sapi_free_header(header); + efree(current); + --l->count; + } + current = next; + } + efree(session_cookie); +} + static void php_session_send_cookie(TSRMLS_D) /* {{{ */ { smart_str ncookie = {0}; @@ -1343,7 +1386,8 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */ smart_str_0(&ncookie); - sapi_add_header_ex(ncookie.c, ncookie.len, 0, 1 TSRMLS_CC); + php_session_remove_cookie(); /* remove already sent session ID cookie */ + sapi_add_header_ex(ncookie.c, ncookie.len, 0, 0 TSRMLS_CC); } /* }}} */ |