str.start = request->method.data;
str.length = request->method.len;
+ if (request->method.len == 0
+ || ngx_js_check_request_line_component(request->method.data,
+ request->method.len)
+ != NGX_OK)
+ {
+ njs_vm_error(vm, "invalid Request method");
+ return NJS_ERROR;
+ }
+
for (m = &forbidden[0]; m->length != 0; m++) {
if (njs_strstr_case_eq(&str, m)) {
njs_vm_error(vm, "forbidden method: %V", m);
int trim_c0_control_or_space);
void ngx_js_http_trim_ows(u_char **value, size_t *len);
ngx_int_t ngx_js_check_header_name(u_char *name, size_t len);
+ngx_int_t ngx_js_check_request_line_component(u_char *value, size_t len);
ngx_int_t ngx_js_check_header_value(u_char *value, size_t len);
ngx_buf_t *ngx_js_chain_to_buf(ngx_pool_t *pool, njs_chb_t *chain);
ngx_null_string,
};
+ if (request->method.len == 0
+ || ngx_js_check_request_line_component(request->method.data,
+ request->method.len)
+ != NGX_OK)
+ {
+ JS_ThrowInternalError(cx, "invalid Request method");
+ return NGX_ERROR;
+ }
+
for (m = &forbidden[0]; m->len != 0; m++) {
if (request->method.len == m->len
&& ngx_strncasecmp(request->method.data, m->data, m->len) == 0)
}, 'OK'],
['method', () => {
const methods = ['get', 'hEad', 'Post', 'OPTIONS', 'PUT',
- 'DELETE', 'CONNECT'];
- try {
- methods.forEach(m => {
- var r = new Request("http://nginx.org", {method: m});
- if (r.method != m.toUpperCase()) {
- throw new Error(`r.method != \${m}`);
+ 'DELETE'];
+ const forbidden = ['CONNECT', 'TRACE', 'TRACK'];
+ const invalid = ['', 'GET ', ' GET', 'GE T', 'GE\\tT',
+ 'GE\\nT', 'GE\\rT', 'GE\\x00T',
+ 'GET\\r\\nX: y',
+ 'GE' + String.fromCharCode(0x7f) + 'T'];
+ const high = 'G' + String.fromCharCode(0xc9) + 'T';
+ const extensions = ['PROPFIND', 'propfind', 'M-SEARCH',
+ high, 'FOO/BAR'];
+
+ methods.forEach(m => {
+ var r = new Request("http://nginx.org", {method: m});
+ if (r.method != m.toUpperCase()) {
+ throw new Error(`r.method != \${m}`);
+ }
+ });
+
+ forbidden.forEach(m => {
+ try {
+ new Request("http://nginx.org", {method: m});
+ throw new Error('no error');
+
+ } catch (e) {
+ if (!e.message.startsWith(`forbidden method: \${m}`)) {
+ throw e;
}
- })
+ }
+ });
- } catch (e) {
- if (!e.message.startsWith('forbidden method: CONNECT')) {
- throw e;
+ invalid.forEach(m => {
+ try {
+ new Request("http://nginx.org", {method: m});
+ throw new Error('no error');
+
+ } catch (e) {
+ if (e.message != 'invalid Request method') {
+ throw e;
+ }
}
- }
+ });
+
+ extensions.forEach(m => {
+ var r = new Request("http://nginx.org", {method: m});
+ if (r.method != m) {
+ throw new Error(`r.method != \${m}`);
+ }
+ });
return 'OK';