From 068529586d10a939fdef5e767aae322a53005c3a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 2 Sep 2015 22:38:57 +0900 Subject: [PATCH] nghttpx: Split up request class definition to dedicated files --- src/Makefile.am | 1 + src/shrpx_mruby_module.cc | 145 +++++------------------------- src/shrpx_mruby_module.h | 4 + src/shrpx_mruby_module_request.cc | 141 +++++++++++++++++++++++++++++ src/shrpx_mruby_module_request.h | 44 +++++++++ 5 files changed, 212 insertions(+), 123 deletions(-) create mode 100644 src/shrpx_mruby_module_request.cc create mode 100644 src/shrpx_mruby_module_request.h diff --git a/src/Makefile.am b/src/Makefile.am index bc3a6ce7..bcae9aaa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -126,6 +126,7 @@ NGHTTPX_SRCS = \ shrpx_memcached_result.h \ shrpx_mruby.cc shrpx_mruby.h \ shrpx_mruby_module.cc shrpx_mruby_module.h \ + shrpx_mruby_module_request.cc shrpx_mruby_module_request.h \ buffer.h memchunk.h template.h if HAVE_SPDYLAY diff --git a/src/shrpx_mruby_module.cc b/src/shrpx_mruby_module.cc index 9e0be077..0b58643e 100644 --- a/src/shrpx_mruby_module.cc +++ b/src/shrpx_mruby_module.cc @@ -24,140 +24,20 @@ */ #include "shrpx_mruby_module.h" +#include + #include #include #include #include -#include "shrpx_downstream.h" #include "shrpx_mruby.h" -#include "util.h" +#include "shrpx_mruby_module_request.h" namespace shrpx { namespace mruby { -namespace { -mrb_value create_headers_hash(mrb_state *mrb, const Headers &headers) { - auto hash = mrb_hash_new(mrb); - - for (auto &hd : headers) { - if (hd.name.empty() || hd.name[0] == ':') { - continue; - } - auto key = mrb_str_new(mrb, hd.name.c_str(), hd.name.size()); - auto ary = mrb_hash_get(mrb, hash, key); - if (mrb_nil_p(ary)) { - ary = mrb_ary_new(mrb); - mrb_hash_set(mrb, hash, key, ary); - } - mrb_ary_push(mrb, ary, mrb_str_new(mrb, hd.value.c_str(), hd.value.size())); - } - - return hash; -} -} // namespace - -namespace { -mrb_value request_init(mrb_state *mrb, mrb_value self) { return self; } -} // namespace - -namespace { -mrb_value request_get_path(mrb_state *mrb, mrb_value self) { - auto data = static_cast(mrb->ud); - auto downstream = data->downstream; - auto &path = downstream->get_request_path(); - - return mrb_str_new(mrb, path.c_str(), path.size()); -} -} // namespace - -namespace { -mrb_value request_set_path(mrb_state *mrb, mrb_value self) { - auto data = static_cast(mrb->ud); - auto downstream = data->downstream; - - const char *path; - mrb_int pathlen; - mrb_get_args(mrb, "s", &path, &pathlen); - if (pathlen == 0) { - mrb_raise(mrb, E_RUNTIME_ERROR, "path must not be empty string"); - } - - downstream->set_request_path(std::string(path, pathlen)); - - return self; -} -} // namespace - -namespace { -mrb_value request_get_headers(mrb_state *mrb, mrb_value self) { - auto data = static_cast(mrb->ud); - auto downstream = data->downstream; - return create_headers_hash(mrb, downstream->get_request_headers()); -} -} // namespace - -namespace { -mrb_value request_set_header(mrb_state *mrb, mrb_value self) { - auto data = static_cast(mrb->ud); - auto downstream = data->downstream; - - mrb_value key, values; - mrb_get_args(mrb, "oo", &key, &values); - - if (RSTRING_LEN(key) == 0) { - mrb_raise(mrb, E_RUNTIME_ERROR, "empty key is not allowed"); - } - - key = mrb_funcall(mrb, key, "downcase", 0); - - // making name empty will effectively delete header fields - for (auto &hd : downstream->get_request_headers()) { - if (util::streq(std::begin(hd.name), hd.name.size(), RSTRING_PTR(key), - RSTRING_LEN(key))) { - hd.name = ""; - } - } - - if (mrb_obj_is_instance_of(mrb, values, mrb->array_class)) { - auto n = mrb_ary_len(mrb, values); - for (int i = 0; i < n; ++i) { - auto value = mrb_ary_entry(values, i); - downstream->add_request_header( - std::string(RSTRING_PTR(key), RSTRING_LEN(key)), - std::string(RSTRING_PTR(value), RSTRING_LEN(value))); - } - } else { - downstream->add_request_header( - std::string(RSTRING_PTR(key), RSTRING_LEN(key)), - std::string(RSTRING_PTR(values), RSTRING_LEN(values))); - } - - data->request_headers_dirty = true; - - return mrb_nil_value(); -} -} // namespace - -namespace { -void init_request_class(mrb_state *mrb, RClass *module) { - auto request_class = - mrb_define_class_under(mrb, module, "Request", mrb->object_class); - - mrb_define_method(mrb, request_class, "initialize", request_init, - MRB_ARGS_NONE()); - mrb_define_method(mrb, request_class, "path", request_get_path, - MRB_ARGS_NONE()); - mrb_define_method(mrb, request_class, "path=", request_set_path, - MRB_ARGS_REQ(1)); - mrb_define_method(mrb, request_class, "headers", request_get_headers, - MRB_ARGS_NONE()); - mrb_define_method(mrb, request_class, "set_header", request_set_header, - MRB_ARGS_REQ(2)); -} -} // namespace - namespace { mrb_value run(mrb_state *mrb, mrb_value self) { mrb_value b; @@ -180,6 +60,25 @@ void init_module(mrb_state *mrb) { init_request_class(mrb, module); } +mrb_value create_headers_hash(mrb_state *mrb, const Headers &headers) { + auto hash = mrb_hash_new(mrb); + + for (auto &hd : headers) { + if (hd.name.empty() || hd.name[0] == ':') { + continue; + } + auto key = mrb_str_new(mrb, hd.name.c_str(), hd.name.size()); + auto ary = mrb_hash_get(mrb, hash, key); + if (mrb_nil_p(ary)) { + ary = mrb_ary_new(mrb); + mrb_hash_set(mrb, hash, key, ary); + } + mrb_ary_push(mrb, ary, mrb_str_new(mrb, hd.value.c_str(), hd.value.size())); + } + + return hash; +} + } // namespace mruby } // namespace shrpx diff --git a/src/shrpx_mruby_module.h b/src/shrpx_mruby_module.h index bec51934..f4e300a4 100644 --- a/src/shrpx_mruby_module.h +++ b/src/shrpx_mruby_module.h @@ -29,6 +29,8 @@ #include +#include "http2.h" + using namespace nghttp2; namespace shrpx { @@ -37,6 +39,8 @@ namespace mruby { void init_module(mrb_state *mrb); +mrb_value create_headers_hash(mrb_state *mrb, const Headers &headers); + } // namespace mruby } // namespace shrpx diff --git a/src/shrpx_mruby_module_request.cc b/src/shrpx_mruby_module_request.cc new file mode 100644 index 00000000..48d8167a --- /dev/null +++ b/src/shrpx_mruby_module_request.cc @@ -0,0 +1,141 @@ +/* + * nghttp2 - HTTP/2 C Library + * + * Copyright (c) 2015 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "shrpx_mruby_module_request.h" + +#include +#include +#include +#include + +#include "shrpx_downstream.h" +#include "shrpx_mruby.h" +#include "shrpx_mruby_module.h" +#include "util.h" + +namespace shrpx { + +namespace mruby { + +namespace { +mrb_value request_init(mrb_state *mrb, mrb_value self) { return self; } +} // namespace + +namespace { +mrb_value request_get_path(mrb_state *mrb, mrb_value self) { + auto data = static_cast(mrb->ud); + auto downstream = data->downstream; + auto &path = downstream->get_request_path(); + + return mrb_str_new(mrb, path.c_str(), path.size()); +} +} // namespace + +namespace { +mrb_value request_set_path(mrb_state *mrb, mrb_value self) { + auto data = static_cast(mrb->ud); + auto downstream = data->downstream; + + const char *path; + mrb_int pathlen; + mrb_get_args(mrb, "s", &path, &pathlen); + if (pathlen == 0) { + mrb_raise(mrb, E_RUNTIME_ERROR, "path must not be empty string"); + } + + downstream->set_request_path(std::string(path, pathlen)); + + return self; +} +} // namespace + +namespace { +mrb_value request_get_headers(mrb_state *mrb, mrb_value self) { + auto data = static_cast(mrb->ud); + auto downstream = data->downstream; + return create_headers_hash(mrb, downstream->get_request_headers()); +} +} // namespace + +namespace { +mrb_value request_set_header(mrb_state *mrb, mrb_value self) { + auto data = static_cast(mrb->ud); + auto downstream = data->downstream; + + mrb_value key, values; + mrb_get_args(mrb, "oo", &key, &values); + + if (RSTRING_LEN(key) == 0) { + mrb_raise(mrb, E_RUNTIME_ERROR, "empty key is not allowed"); + } + + key = mrb_funcall(mrb, key, "downcase", 0); + + // making name empty will effectively delete header fields + for (auto &hd : downstream->get_request_headers()) { + if (util::streq(std::begin(hd.name), hd.name.size(), RSTRING_PTR(key), + RSTRING_LEN(key))) { + hd.name = ""; + } + } + + if (mrb_obj_is_instance_of(mrb, values, mrb->array_class)) { + auto n = mrb_ary_len(mrb, values); + for (int i = 0; i < n; ++i) { + auto value = mrb_ary_entry(values, i); + downstream->add_request_header( + std::string(RSTRING_PTR(key), RSTRING_LEN(key)), + std::string(RSTRING_PTR(value), RSTRING_LEN(value))); + } + } else { + downstream->add_request_header( + std::string(RSTRING_PTR(key), RSTRING_LEN(key)), + std::string(RSTRING_PTR(values), RSTRING_LEN(values))); + } + + data->request_headers_dirty = true; + + return mrb_nil_value(); +} +} // namespace + +void init_request_class(mrb_state *mrb, RClass *module) { + auto request_class = + mrb_define_class_under(mrb, module, "Request", mrb->object_class); + + mrb_define_method(mrb, request_class, "initialize", request_init, + MRB_ARGS_NONE()); + mrb_define_method(mrb, request_class, "path", request_get_path, + MRB_ARGS_NONE()); + mrb_define_method(mrb, request_class, "path=", request_set_path, + MRB_ARGS_REQ(1)); + mrb_define_method(mrb, request_class, "headers", request_get_headers, + MRB_ARGS_NONE()); + mrb_define_method(mrb, request_class, "set_header", request_set_header, + MRB_ARGS_REQ(2)); +} + +} // namespace mruby + +} // namespace shrpx diff --git a/src/shrpx_mruby_module_request.h b/src/shrpx_mruby_module_request.h new file mode 100644 index 00000000..b27c569b --- /dev/null +++ b/src/shrpx_mruby_module_request.h @@ -0,0 +1,44 @@ +/* + * nghttp2 - HTTP/2 C Library + * + * Copyright (c) 2015 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef SHRPX_MRUBY_MODULE_REQUEST_H +#define SHRPX_MRUBY_MODULE_REQUEST_H + +#include "shrpx.h" + +#include + +using namespace nghttp2; + +namespace shrpx { + +namespace mruby { + +void init_request_class(mrb_state *mrb, RClass *module); + +} // namespace mruby + +} // namespace shrpx + +#endif // SHRPX_MRUBY_MODULE_REQUEST_H