diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index 1ab6c07cb..35f7ab02d 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -901,13 +901,44 @@ nxt_ruby_hash_info(VALUE r_key, VALUE r_value, VALUE arg) goto fail; } - if (nxt_slow_path(TYPE(r_value) != T_STRING && TYPE(r_value) != T_NIL)) { + if (nxt_slow_path(TYPE(r_value) != T_STRING + && TYPE(r_value) != T_ARRAY + && TYPE(r_value) != T_NIL)) + { nxt_unit_req_error(headers_info->req, "Ruby: Wrong header entry 'value' from application"); goto fail; } + if (TYPE(r_value) == T_ARRAY) { + int i; + int arr_len = RARRAY_LEN(r_value); + VALUE item; + size_t len = 0; + + for (i = 0; i < arr_len; i++) { + item = rb_ary_entry(r_value, i); + if (TYPE(item) != T_STRING && TYPE(item) != T_NIL) { + nxt_unit_req_error(headers_info->req, + "Ruby: Wrong header entry in 'value' array " + "from application"); + goto fail; + } + + if (TYPE(item) == T_STRING) { + len += RSTRING_LEN(item); + } + + len += 2; /* +2 for '; ' */ + } + + headers_info->fields++; + headers_info->size += RSTRING_LEN(r_key) + len - 2; + + return ST_CONTINUE; + } + NXT_RUBY_SET_HDR_VALUE(r_value, value, value_end); pos = value; @@ -953,6 +984,53 @@ nxt_ruby_hash_add(VALUE r_key, VALUE r_value, VALUE arg) key_len = RSTRING_LEN(r_key); + if (TYPE(r_value) == T_ARRAY) { + int i; + int arr_len = RARRAY_LEN(r_value); + char *field, *p; + VALUE item; + size_t len = 0; + + for (i = 0; i < arr_len; i++) { + item = rb_ary_entry(r_value, i); + + if (TYPE(item) == T_STRING) { + len += RSTRING_LEN(item); + } + + len += 2; /* +2 for '; ' */ + } + + field = nxt_malloc(len); + if (field == NULL) { + goto fail; + } + + p = field; + + for (i = 0; i < arr_len; i++) { + item = rb_ary_entry(r_value, i); + if (TYPE(item) == T_STRING) { + p = nxt_cpymem(p, RSTRING_PTR(item), RSTRING_LEN(item)); + } + + p = nxt_cpymem(p, "; ", 2); + } + + len -= 2; + + *rc = nxt_unit_response_add_field(headers_info->req, + RSTRING_PTR(r_key), key_len, + field, len); + nxt_free(field); + + if (nxt_slow_path(*rc != NXT_UNIT_OK)) { + goto fail; + } + + return ST_CONTINUE; + } + NXT_RUBY_SET_HDR_VALUE(r_value, value, value_end); pos = value;