summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlexander Borisov <alexander.borisov@nginx.com>2018-12-19 15:56:30 +0300
committerAlexander Borisov <alexander.borisov@nginx.com>2018-12-19 15:56:30 +0300
commitdcf51274ce0953e577fbfffd81afb592319a2267 (patch)
tree50e9e7f893ec3103d61f6d66f6a54a4db5d7d256
parent607653c0f12a99981dbf3118b60b84ded4084d50 (diff)
downloadunit-dcf51274ce0953e577fbfffd81afb592319a2267.tar.gz
unit-dcf51274ce0953e577fbfffd81afb592319a2267.tar.bz2
Node.js: checking uniqueness of HTTP headers for different case.
-rwxr-xr-xsrc/nodejs/unit-http/http_server.js72
-rw-r--r--src/nodejs/unit-http/unit.cpp14
2 files changed, 62 insertions, 24 deletions
diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js
index 28f2303f..216c4394 100755
--- a/src/nodejs/unit-http/http_server.js
+++ b/src/nodejs/unit-http/http_server.js
@@ -47,24 +47,23 @@ ServerResponse.prototype.writeContinue = function writeContinue(cb) {
ServerResponse.prototype.writeProcessing = function writeProcessing(cb) {
};
-ServerResponse.prototype.setHeader = function setHeader(key, value) {
- if (typeof key !== 'string') {
- throw new TypeError('Key argument must be a string');
+ServerResponse.prototype.setHeader = function setHeader(name, value) {
+ if (typeof name !== 'string') {
+ throw new TypeError('Name argument must be a string');
}
- let header_key_len = Buffer.byteLength(key, 'latin1');
- let header_len = 0
- let header_count = 0;
+ let value_len = 0
+ let count = 0;
if (Array.isArray(value)) {
- header_count = value.length;
+ count = value.length;
value.forEach(function(val) {
if (typeof val !== 'string' && typeof val !== 'number') {
throw new TypeError('Array entries must be string or number');
}
- header_len += Buffer.byteLength(val + "", 'latin1');
+ value_len += Buffer.byteLength(val + "", 'latin1');
});
} else {
@@ -72,19 +71,27 @@ ServerResponse.prototype.setHeader = function setHeader(key, value) {
throw new TypeError('Value argument must be string, number, or array');
}
- header_count = 1;
- header_len = Buffer.byteLength(value + "", 'latin1');
+ count = 1;
+ value_len = Buffer.byteLength(value + "", 'latin1');
}
- this.removeHeader(key);
+ let lc_name = name.toLowerCase();
- this.headers[key] = value;
- this.headers_len += header_len + (header_key_len * header_count);
- this.headers_count += header_count;
+ if (lc_name in this.headers) {
+ this._removeHeader(lc_name);
+ }
+
+ let name_len = Buffer.byteLength(name, 'latin1');
+
+ this.headers[lc_name] = [name, value];
+ this.headers_len += value_len + (name_len * count);
+ this.headers_count += count;
};
ServerResponse.prototype.getHeader = function getHeader(name) {
- return this.headers[name];
+ const entry = this.headers[name.toLowerCase()];
+
+ return entry && entry[1];
};
ServerResponse.prototype.getHeaderNames = function getHeaderNames() {
@@ -92,22 +99,43 @@ ServerResponse.prototype.getHeaderNames = function getHeaderNames() {
};
ServerResponse.prototype.getHeaders = function getHeaders() {
- return this.headers;
+ const ret = Object.create(null);
+
+ if (this.headers) {
+ const keys = Object.keys(this.headers);
+
+ for (var i = 0; i < keys.length; i++) {
+ const key = keys[i];
+
+ ret[key] = this.headers[key][1];
+ }
+ }
+
+ return ret;
};
ServerResponse.prototype.hasHeader = function hasHeader(name) {
- return name in this.headers;
+ return name.toLowerCase() in this.headers;
};
ServerResponse.prototype.removeHeader = function removeHeader(name) {
- if (!(name in this.headers)) {
- return;
+ if (typeof name !== 'string') {
+ throw new TypeError('Name argument must be a string');
}
- let name_len = Buffer.byteLength(name + "", 'latin1');
- let value = this.headers[name];
+ let lc_name = name.toLowerCase();
+
+ if (lc_name in this.headers) {
+ this._removeHeader(lc_name);
+ }
+};
+
+ServerResponse.prototype._removeHeader = function _removeHeader(lc_name) {
+ let entry = this.headers[lc_name];
+ let name_len = Buffer.byteLength(entry[0] + "", 'latin1');
+ let value = entry[1];
- delete this.headers[name];
+ delete this.headers[lc_name];
if (Array.isArray(value)) {
this.headers_count -= value.length;
diff --git a/src/nodejs/unit-http/unit.cpp b/src/nodejs/unit-http/unit.cpp
index b233359c..36bc98db 100644
--- a/src/nodejs/unit-http/unit.cpp
+++ b/src/nodejs/unit-http/unit.cpp
@@ -737,7 +737,7 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
uint32_t keys_count, i, j;
uint16_t hash;
napi_value this_arg, headers, keys, name, value, array_val;
- napi_value req_num;
+ napi_value req_num, array_entry;
napi_status status;
napi_valuetype val_type;
nxt_unit_field_t *f;
@@ -814,7 +814,17 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
goto failed;
}
- status = napi_get_property(env, headers, name, &value);
+ status = napi_get_property(env, headers, name, &array_entry);
+ if (status != napi_ok) {
+ goto failed;
+ }
+
+ status = napi_get_element(env, array_entry, 0, &name);
+ if (status != napi_ok) {
+ goto failed;
+ }
+
+ status = napi_get_element(env, array_entry, 1, &value);
if (status != napi_ok) {
goto failed;
}