mirror of https://gitee.com/bigwinds/arangodb
added cookie support
This commit is contained in:
parent
71a093e3d0
commit
2d8c547fc8
|
@ -270,6 +270,60 @@ static void ParseActionOptions (TRI_v8_global_t* v8g,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add cookie
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void addCookie (TRI_v8_global_t* v8g, HttpResponse* response, v8::Handle<v8::Object> data) {
|
||||
|
||||
string name;
|
||||
string value;
|
||||
int lifeTimeSeconds = 0;
|
||||
string path = "/";
|
||||
string domain = "";
|
||||
bool secure = false;
|
||||
bool httpOnly = false;
|
||||
|
||||
if (data->Has(v8g->CookieName)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookieName);
|
||||
name = TRI_ObjectToString(v);
|
||||
}
|
||||
else {
|
||||
// something is wrong here
|
||||
return;
|
||||
}
|
||||
if (data->Has(v8g->CookieValue)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookieValue);
|
||||
value = TRI_ObjectToString(v);
|
||||
}
|
||||
else {
|
||||
// something is wrong here
|
||||
return;
|
||||
}
|
||||
if (data->Has(v8g->CookieLiveTime)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookieLiveTime);
|
||||
lifeTimeSeconds = TRI_ObjectToInt64(v);
|
||||
}
|
||||
if (data->Has(v8g->CookiePath)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookiePath);
|
||||
path = TRI_ObjectToString(v);
|
||||
}
|
||||
if (data->Has(v8g->CookieDomain)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookieDomain);
|
||||
domain = TRI_ObjectToString(v);
|
||||
}
|
||||
if (data->Has(v8g->CookieSecure)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookieSecure);
|
||||
secure = TRI_ObjectToBoolean(v);
|
||||
}
|
||||
if (data->Has(v8g->CookieHttpOnly)) {
|
||||
v8::Handle<v8::Value> v = data->Get(v8g->CookieHttpOnly);
|
||||
httpOnly = TRI_ObjectToBoolean(v);
|
||||
}
|
||||
|
||||
response->setCookie(name, value, lifeTimeSeconds, path, domain, secure, httpOnly);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes an action
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -311,6 +365,10 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
// "user-agent" : "Mozilla/5.0"
|
||||
// },
|
||||
//
|
||||
// "cookies" : {
|
||||
// "ARANGODB_SESSION_ID" : "0cwuzusd23nw3qiwui84uwqwqw23e"
|
||||
// },
|
||||
//
|
||||
// "requestType" : "GET",
|
||||
// "requestBody" : "... only for PUT and POST ...",
|
||||
// "user" : "authenticatedUser"
|
||||
|
@ -489,6 +547,18 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
|
||||
req->Set(v8g->ParametersKey, valuesObject);
|
||||
|
||||
// copy cookies
|
||||
v8::Handle<v8::Object> cookiesObject = v8::Object::New();
|
||||
|
||||
map<string, string> const& cookies = request->cookieValues();
|
||||
iter = cookies.begin();
|
||||
|
||||
for (; iter != cookies.end(); ++iter) {
|
||||
cookiesObject->Set(v8::String::New(iter->first.c_str()), v8::String::New(iter->second.c_str()));
|
||||
}
|
||||
|
||||
req->Set(v8g->CookiesKey, cookiesObject);
|
||||
|
||||
// execute the callback
|
||||
v8::Handle<v8::Object> res = v8::Object::New();
|
||||
v8::Handle<v8::Value> args[2] = { req, res };
|
||||
|
@ -599,6 +669,30 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
}
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// cookies
|
||||
// .............................................................................
|
||||
|
||||
if (res->Has(v8g->CookiesKey)) {
|
||||
v8::Handle<v8::Value> val = res->Get(v8g->CookiesKey);
|
||||
v8::Handle<v8::Object> v8Cookies = val.As<v8::Object>();
|
||||
|
||||
if (v8Cookies->IsArray()) {
|
||||
v8::Handle<v8::Array> v8Array = v8Cookies.As<v8::Array>();
|
||||
|
||||
for (uint32_t i = 0; i < v8Array->Length(); i++) {
|
||||
v8::Handle<v8::Value> v8Cookie = v8Array->Get(i);
|
||||
if (v8Cookie->IsObject()) {
|
||||
addCookie(v8g, response, v8Cookie.As<v8::Object>());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (v8Cookies->IsObject()) {
|
||||
// one cookie
|
||||
addCookie(v8g, response, v8Cookies);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
@ -774,6 +868,14 @@ void TRI_InitV8Actions (v8::Handle<v8::Context> context, ApplicationV8* applicat
|
|||
v8g->BodyFromFileKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("bodyFromFile"));
|
||||
v8g->ContentTypeKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("contentType"));
|
||||
v8g->HeadersKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("headers"));
|
||||
v8g->CookiesKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("cookies"));
|
||||
v8g->CookieName = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("name"));
|
||||
v8g->CookieValue = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("value"));
|
||||
v8g->CookieLiveTime = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("liveTime"));
|
||||
v8g->CookiePath = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("path"));
|
||||
v8g->CookieDomain = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("domain"));
|
||||
v8g->CookieSecure = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("secure"));
|
||||
v8g->CookieHttpOnly = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("httpOnly"));
|
||||
v8g->ParametersKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("parameters"));
|
||||
v8g->PathKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("path"));
|
||||
v8g->PrefixKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("prefix"));
|
||||
|
|
|
@ -1937,6 +1937,48 @@ function pathHandler (req, res, options, next) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add a cookie
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function addCookie (res, name, value, liveTime, path, domain, secure, httpOnly) {
|
||||
'use strict';
|
||||
|
||||
if (name === undefined) {
|
||||
return;
|
||||
}
|
||||
if (value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cookie = {
|
||||
'name' : name,
|
||||
'value' : value
|
||||
};
|
||||
|
||||
if (liveTime !== undefined && liveTime !== null) {
|
||||
cookie.liveTime = parseInt(liveTime);
|
||||
}
|
||||
if (path !== undefined && path !== null) {
|
||||
cookie.path = path;
|
||||
}
|
||||
if (domain !== undefined && domain !== null) {
|
||||
cookie.path = domain;
|
||||
}
|
||||
if (secure !== undefined && secure !== null) {
|
||||
cookie.secure = (secure) ? true : false;
|
||||
}
|
||||
if (httpOnly !== undefined && httpOnly !== null) {
|
||||
cookie.httpOnly = (httpOnly) ? true : false;
|
||||
}
|
||||
|
||||
if (res.cookies === undefined || res.cookies === null) {
|
||||
res.cookies = [];
|
||||
}
|
||||
|
||||
res.cookies.push(cookie);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1959,6 +2001,7 @@ exports.reloadRouting = reloadRouting;
|
|||
exports.firstRouting = firstRouting;
|
||||
exports.nextRouting = nextRouting;
|
||||
exports.routingCache = function() { return RoutingCache; };
|
||||
exports.addCookie = addCookie;
|
||||
|
||||
// standard HTTP responses
|
||||
exports.badParameter = badParameter;
|
||||
|
|
|
@ -66,6 +66,7 @@ HttpRequest::HttpRequest (char const* header, size_t length)
|
|||
_headers(5),
|
||||
_values(10),
|
||||
_arrayValues(10),
|
||||
_cookies(1),
|
||||
_contentLength(0),
|
||||
_body(0),
|
||||
_bodySize(0),
|
||||
|
@ -95,6 +96,7 @@ HttpRequest::HttpRequest ()
|
|||
_headers(1),
|
||||
_values(1),
|
||||
_arrayValues(1),
|
||||
_cookies(1),
|
||||
_contentLength(0),
|
||||
_body(0),
|
||||
_bodySize(0),
|
||||
|
@ -252,6 +254,30 @@ void HttpRequest::write (TRI_string_buffer_t* buffer) const {
|
|||
TRI_AppendStringStringBuffer(buffer, value);
|
||||
TRI_AppendString2StringBuffer(buffer, "\r\n", 2);
|
||||
}
|
||||
|
||||
first = true;
|
||||
for (_cookies.range(begin, end); begin < end; ++begin) {
|
||||
char const* key = begin->_key;
|
||||
|
||||
if (key == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
TRI_AppendString2StringBuffer(buffer, "Cookie: ", 8);
|
||||
}
|
||||
else {
|
||||
TRI_AppendString2StringBuffer(buffer, "; ", 2);
|
||||
}
|
||||
|
||||
const size_t keyLength = strlen(key);
|
||||
TRI_AppendString2StringBuffer(buffer, key, keyLength);
|
||||
TRI_AppendString2StringBuffer(buffer, "=", 2);
|
||||
|
||||
char const* value = begin->_value;
|
||||
TRI_AppendUrlEncodedStringStringBuffer(buffer, value);
|
||||
}
|
||||
|
||||
TRI_AppendString2StringBuffer(buffer, "content-length: ", 16);
|
||||
TRI_AppendInt64StringBuffer(buffer, _contentLength);
|
||||
|
@ -441,6 +467,61 @@ map<string, vector<char const*>* > HttpRequest::arrayValues () const {
|
|||
/// {@inheritDoc}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* HttpRequest::cookieValue (char const* key) const {
|
||||
Dictionary<char const*>::KeyValue const* kv = _cookies.lookup(key);
|
||||
|
||||
if (kv == 0) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
else {
|
||||
return kv->_value;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// {@inheritDoc}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* HttpRequest::cookieValue (char const* key, bool& found) const {
|
||||
Dictionary<char const*>::KeyValue const* kv = _cookies.lookup(key);
|
||||
|
||||
if (kv == 0) {
|
||||
found = false;
|
||||
return EMPTY_STR;
|
||||
}
|
||||
else {
|
||||
found = true;
|
||||
return kv->_value;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// {@inheritDoc}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
map<string, string> HttpRequest::cookieValues () const {
|
||||
basics::Dictionary<char const*>::KeyValue const* begin;
|
||||
basics::Dictionary<char const*>::KeyValue const* end;
|
||||
|
||||
map<string, string> result;
|
||||
|
||||
for (_cookies.range(begin, end); begin < end; ++begin) {
|
||||
char const* key = begin->_key;
|
||||
|
||||
if (key == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result[key] = begin->_value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// {@inheritDoc}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* HttpRequest::body () const {
|
||||
return _body == 0 ? EMPTY_STR : _body;
|
||||
}
|
||||
|
@ -480,9 +561,13 @@ void HttpRequest::setHeader (char const* key, size_t keyLength, char const* valu
|
|||
|
||||
_contentLength = TRI_Int64String(value);
|
||||
}
|
||||
else if (keyLength == 6 && memcmp(key, "cookie", keyLength) == 0) { // 6 = strlen("cookie")
|
||||
parseCookies(value);
|
||||
}
|
||||
else {
|
||||
_headers.insert(key, keyLength, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1206,6 +1291,128 @@ void HttpRequest::setArrayValue (char* key, size_t length, char const* value) {
|
|||
v->push_back(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set cookie
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HttpRequest::setCookie (char* key, size_t length, char const* value) {
|
||||
_cookies.insert(key, length, value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse value of a cookie header field
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HttpRequest::parseCookies (const char* buffer) {
|
||||
char* keyBegin = 0;
|
||||
char* key = 0;
|
||||
|
||||
char* valueBegin = 0;
|
||||
char* value = 0;
|
||||
|
||||
enum { KEY, VALUE } phase = KEY;
|
||||
enum { NORMAL, HEX1, HEX2 } reader = NORMAL;
|
||||
|
||||
int hex = 0;
|
||||
|
||||
char const AMB = ';';
|
||||
char const EQUAL = '=';
|
||||
char const PERCENT = '%';
|
||||
char const SPACE = ' ';
|
||||
|
||||
char* buffer2 = (char*) buffer;
|
||||
char* end = buffer2 + strlen(buffer);
|
||||
|
||||
for (keyBegin = key = buffer2; buffer2 < end; buffer2++) {
|
||||
char next = *buffer2;
|
||||
|
||||
if (phase == KEY && next == EQUAL) {
|
||||
phase = VALUE;
|
||||
|
||||
valueBegin = value = buffer2 + 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (next == AMB) {
|
||||
phase = KEY;
|
||||
|
||||
*key = '\0';
|
||||
|
||||
// check for missing value phase
|
||||
if (valueBegin == 0) {
|
||||
valueBegin = value = key;
|
||||
}
|
||||
else {
|
||||
*value = '\0';
|
||||
}
|
||||
|
||||
setCookie(keyBegin, key - keyBegin, valueBegin);
|
||||
|
||||
//keyBegin = key = buffer2 + 1;
|
||||
while ( *(keyBegin = key = buffer2 + 1) == SPACE && buffer2 < end) {
|
||||
buffer2++;
|
||||
}
|
||||
valueBegin = value = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (next == PERCENT) {
|
||||
reader = HEX1;
|
||||
continue;
|
||||
}
|
||||
else if (reader == HEX1) {
|
||||
int h1 = StringUtils::hex2int(next, -1);
|
||||
|
||||
if (h1 == -1) {
|
||||
reader = NORMAL;
|
||||
--buffer2;
|
||||
continue;
|
||||
}
|
||||
|
||||
hex = h1 * 16;
|
||||
reader = HEX2;
|
||||
continue;
|
||||
}
|
||||
else if (reader == HEX2) {
|
||||
int h1 = StringUtils::hex2int(next, -1);
|
||||
|
||||
if (h1 == -1) {
|
||||
--buffer2;
|
||||
}
|
||||
else {
|
||||
hex += h1;
|
||||
}
|
||||
|
||||
reader = NORMAL;
|
||||
next = static_cast<char>(hex);
|
||||
}
|
||||
|
||||
if (phase == KEY) {
|
||||
*key++ = next;
|
||||
}
|
||||
else {
|
||||
*value++ = next;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyBegin != key) {
|
||||
*key = '\0';
|
||||
|
||||
// check for missing value phase
|
||||
if (valueBegin == 0) {
|
||||
valueBegin = value = key;
|
||||
}
|
||||
else {
|
||||
*value = '\0';
|
||||
}
|
||||
|
||||
setCookie(keyBegin, key - keyBegin, valueBegin);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -405,6 +405,29 @@ namespace triagens {
|
|||
|
||||
map<string, vector<char const*>* > arrayValues () const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the value of a cookie
|
||||
///
|
||||
/// Returns the value of a cookie.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* cookieValue (char const* key) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the value of a cookie
|
||||
///
|
||||
/// Returns the value of a cookie. found is true if the client specified the key.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* cookieValue (char const* key, bool& found) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns all cookies
|
||||
///
|
||||
/// Returns all key/value pairs of the request.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
map<string, string > cookieValues () const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -536,6 +559,18 @@ namespace triagens {
|
|||
|
||||
void setArrayValue (char* key, size_t length, char const* value);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set cookie
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setCookie (char* key, size_t length, char const* value);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse value of a cookie header field
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseCookies (const char* buffer);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -575,6 +610,12 @@ namespace triagens {
|
|||
|
||||
basics::Dictionary< vector<char const*>* > _arrayValues;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cookies
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
basics::Dictionary<char const*> _cookies;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief content length
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -495,6 +495,66 @@ void HttpResponse::setHeaders (string const& headers, bool includeLine0) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief swaps data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void HttpResponse::setCookie (string const& name, string const& value,
|
||||
int lifeTimeSeconds, string const& path, string const& domain,
|
||||
bool secure, bool httpOnly) {
|
||||
|
||||
triagens::basics::StringBuffer* buffer = new triagens::basics::StringBuffer(TRI_UNKNOWN_MEM_ZONE);
|
||||
|
||||
string tmp = StringUtils::trim(name);
|
||||
buffer->appendText(tmp.c_str(), tmp.length());
|
||||
buffer->appendChar('=');
|
||||
|
||||
tmp = StringUtils::urlEncode(value);
|
||||
buffer->appendText(tmp.c_str(), tmp.length());
|
||||
|
||||
if (lifeTimeSeconds > 0) {
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
char buffer2 [80];
|
||||
|
||||
time(&rawtime);
|
||||
rawtime += lifeTimeSeconds;
|
||||
|
||||
if (rawtime > 0) {
|
||||
timeinfo = gmtime(&rawtime);
|
||||
strftime(buffer2, 80, "%a, %d-%b-%Y %H:%M:%S %Z", timeinfo);
|
||||
buffer->appendText("; expires=");
|
||||
buffer->appendText(buffer2);
|
||||
}
|
||||
}
|
||||
|
||||
if (path != "") {
|
||||
buffer->appendText("; path=");
|
||||
buffer->appendText(path);
|
||||
}
|
||||
|
||||
if (domain != "") {
|
||||
buffer->appendText("; domain=");
|
||||
buffer->appendText(domain);
|
||||
}
|
||||
|
||||
|
||||
if (secure) {
|
||||
buffer->appendText("; secure");
|
||||
}
|
||||
|
||||
if (httpOnly) {
|
||||
buffer->appendText("; HttpOnly");
|
||||
}
|
||||
|
||||
char const* l = StringUtils::duplicate(buffer->c_str());
|
||||
buffer->clear();
|
||||
free(buffer);
|
||||
|
||||
_cookies.push_back(l);
|
||||
|
||||
_freeables.push_back(l);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief swaps data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -560,6 +620,13 @@ void HttpResponse::writeHeader (StringBuffer* output) {
|
|||
output->appendText("\r\n", 2);
|
||||
}
|
||||
|
||||
for (vector<char const*>::iterator iter = _cookies.begin();
|
||||
iter != _cookies.end(); ++iter) {
|
||||
output->appendText("Set-Cookie: ", 12);
|
||||
output->appendText(*iter);
|
||||
output->appendText("\r\n", 2);
|
||||
}
|
||||
|
||||
if (seenTransferEncoding && transferEncoding == "chunked") {
|
||||
output->appendText("transfer-encoding: chunked\r\n\r\n", 30);
|
||||
}
|
||||
|
|
|
@ -310,6 +310,16 @@ namespace triagens {
|
|||
|
||||
void setHeaders (string const& headers, bool includeLine0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets a cookie
|
||||
///
|
||||
/// The name is automatically trimmed.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setCookie (string const& name, string const& value,
|
||||
int lifeTimeSeconds, string const& path, string const& domain,
|
||||
bool secure, bool httpOnly);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief swaps data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -378,6 +388,13 @@ namespace triagens {
|
|||
|
||||
basics::Dictionary<char const*> _headers;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cookies
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<char const*> _cookies;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief body
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue