diff --git a/apisix/init.lua b/apisix/init.lua index 92d3451b6326..1494dc3c80de 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -803,7 +803,21 @@ function _M.stream_preread_phase() if up_id then api_ctx.matched_upstream = get_upstream_by_id(up_id) else - api_ctx.matched_upstream = matched_route.value.upstream + if matched_route.has_domain then + local err + matched_route, err = parse_domain_in_route(matched_route) + if err then + core.log.error("failed to get resolved route: ", err) + return ngx_exit(1) + end + + api_ctx.matched_route = matched_route + end + + local route_val = matched_route.value + api_ctx.matched_upstream = (matched_route.dns_value and + matched_route.dns_value.upstream) + or route_val.upstream end local plugins = core.tablepool.fetch("plugins", 32, 0) diff --git a/t/stream-node/upstream-domain.t b/t/stream-node/upstream-domain.t new file mode 100644 index 000000000000..0036d00a7e10 --- /dev/null +++ b/t/stream-node/upstream-domain.t @@ -0,0 +1,201 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use t::APISIX 'no_plan'; + +log_level('info'); +no_root_location(); + +add_block_preprocessor(sub { + my ($block) = @_; + + if (!$block->request) { + $block->set_value("stream_enable", 1); + + if (!$block->stream_request) { + $block->set_value("stream_request", "mmm"); + } + } + + if ((!defined $block->error_log) && (!defined $block->no_error_log)) { + $block->set_value("no_error_log", "[error]"); + } +}); + +run_tests(); + +__DATA__ + +=== TEST 1: set upstream & stream_routes (id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/upstreams/1', + ngx.HTTP_PUT, + [[{ + "nodes": { + "localhost:1995": 1 + }, + "type": "roundrobin" + }]] + ) + if code >= 300 then + ngx.status = code + return + end + local code, body = t('/apisix/admin/stream_routes/1', + ngx.HTTP_PUT, + [[{ + "remote_addr": "127.0.0.1", + "upstream_id": "1" + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 2: hit route +--- stream_response +hello world + + + +=== TEST 3: set stream_routes with upstream(id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/stream_routes/1', + ngx.HTTP_PUT, + [[{ + "remote_addr": "127.0.0.1", + "upstream": { + "nodes": { + "localhost:1995": 1 + }, + "type": "roundrobin" + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 4: hit route +--- stream_response +hello world + + + +=== TEST 5: bad domain in the upstream +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/upstreams/1', + ngx.HTTP_PUT, + [[{ + "nodes": { + "local:1995": 1 + }, + "type": "roundrobin" + }]] + ) + if code >= 300 then + ngx.status = code + return + end + local code, body = t('/apisix/admin/stream_routes/1', + ngx.HTTP_PUT, + [[{ + "remote_addr": "127.0.0.1", + "upstream_id": "1" + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 6: hit route +--- stream_response +receive stream response error: connection reset by peer +--- error_log + + + +=== TEST 7: bad domain in the stream route +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/stream_routes/1', + ngx.HTTP_PUT, + [[{ + "remote_addr": "127.0.0.1", + "upstream": { + "nodes": { + "local:1995": 1 + }, + "type": "roundrobin" + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 8: hit route +--- stream_response +receive stream response error: connection reset by peer +--- error_log +no valid upstream node