Divide the MSB source codes into two repos
[msb/apigateway.git] / openresty-ext / src / assembly / resources / openresty / nginx / luaext / rewrite / commonrewrite.lua
1 --[[\r
2 \r
3     Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)\r
4 \r
5     Licensed under the Apache License, Version 2.0 (the "License");\r
6     you may not use this file except in compliance with the License.\r
7     You may obtain a copy of the License at\r
8 \r
9             http://www.apache.org/licenses/LICENSE-2.0\r
10 \r
11     Unless required by applicable law or agreed to in writing, software\r
12     distributed under the License is distributed on an "AS IS" BASIS,\r
13     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14     See the License for the specific language governing permissions and\r
15     limitations under the License.\r
16 \r
17 --]]\r
18 \r
19 local dbclient  =  require('dao.db_access')\r
20 local tbl_util  =  require('lib.utils.table_util')\r
21 local svc_util  =  require('lib.utils.svc_util')\r
22 local log_util  =  require('lib.utils.log_util')\r
23 local error_handler  =  require('lib.utils.error_handler')\r
24 \r
25 local tbl_concat = table.concat\r
26 local tbl_isempty = tbl_util.isempty\r
27 local svc_isactive = svc_util.isactive\r
28 local svc_get_url = svc_util.get_url\r
29 local svc_get_backend_protocol = svc_util.get_backend_protocol\r
30 local svc_use_own_upstream = svc_util.use_own_upstream\r
31 local svc_get_key_prefix = svc_util.get_key_prefix\r
32 local svc_is_api_related_types = svc_util.is_api_related_types\r
33 local error_svc_not_found = error_handler.svc_not_found\r
34 local error_upstream_not_found = error_handler.upstream_not_found\r
35 \r
36 local str_sub = string.sub\r
37 local str_len = string.len\r
38 local str_low = string.lower\r
39 local ngx_var = ngx.var\r
40 local ngx_ctx = ngx.ctx\r
41 local log = log_util.log\r
42 \r
43 ---------------------------------------------------------------\r
44 --preCheck:\r
45 --     determine whether it is websocket request \r
46 --     and do internal redirect\r
47 ---------------------------------------------------------------\r
48 local http_upgrade = ngx_var.http_upgrade\r
49 if(ngx_var.websocket_internal_redirect == "on") and http_upgrade and str_low(http_upgrade) == "websocket" then\r
50         --ngx.log(ngx.ERR, "Websocket request and redirect to @commonwebsocket")\r
51         return ngx.exec("@commonwebsocket");\r
52 end\r
53 \r
54 ---------------------------------------------------------------\r
55 --step0:Preparation\r
56 --      svc_info_key\r
57 --      svc_server_keypattern\r
58 ---------------------------------------------------------------\r
59 local svc_name = ngx_var.svc_name\r
60 local req_res  = ngx_var.req_res\r
61 local svc_type = ngx_var.svc_type\r
62 \r
63 local key_prefix = svc_get_key_prefix()\r
64 \r
65 local svc_key = ""\r
66 if(svc_is_api_related_types(svc_type)) then\r
67         -- process version info first\r
68         local version1 = ngx_var.svc_version1\r
69         local version2 = ngx_var.svc_version2\r
70         local version = ""\r
71         -- check version info appearing befor or after\r
72         if(not version2) then version2 = "" end --convert nil to empty sting avoiding throw error\r
73         if(not version1 or version1 == "") then\r
74                 version = version2\r
75         else\r
76                 version = version1\r
77                 req_res = version2..req_res\r
78         end\r
79         -- remove the slash in front of the version (e.g. /V1.0)\r
80         local svc_version=str_sub(version,2,str_len(version))\r
81         svc_key = tbl_concat({key_prefix,"api",svc_name,svc_version},":")\r
82 else\r
83         svc_key = tbl_concat({key_prefix,"iui",svc_name},":")\r
84 end\r
85 \r
86 ---------------------------------------------------------------\r
87 --step1:query the service info from share memory or back db\r
88 --      svcinfo: the requested service information\r
89 ---------------------------------------------------------------\r
90 local svcinfo = dbclient.load_serviceinfo(svc_key)\r
91 if tbl_isempty(svcinfo) then\r
92         error_svc_not_found("No route found for this request!","common not match. key--"..svc_key)\r
93 end\r
94 if not svc_isactive(svcinfo) then\r
95         error_svc_not_found("Service is disabled!","common not match. key--"..svc_key)\r
96 end\r
97 \r
98 local svc_url = svc_get_url(svcinfo,svc_type)\r
99 \r
100 ---------------------------------------------------------------\r
101 --step2:rewrite the request uri using the svcinfo\r
102 ---------------------------------------------------------------\r
103 local rewrited_uri = svc_url..req_res\r
104 --special handling: avoid throws internal error when it is empty\r
105 --if (rewrited_uri == "") then rewrited_uri = "/" end\r
106 if (rewrited_uri == "") then return ngx.redirect(ngx.var.uri.."/") end \r
107 ngx.req.set_uri(rewrited_uri)\r
108 \r
109 log("matched",svc_name)\r
110 --log("rewrited_uri",rewrited_uri)\r
111 ---------------------------------------------------------------\r
112 --step2.1:store the svcinfo in the context, plugins may use it\r
113 ---------------------------------------------------------------\r
114 ngx_ctx.svcinfo = svcinfo\r
115 \r
116 ---------------------------------------------------------------\r
117 --step3:process the proxy upstream part\r
118 -- con1-using consul template:set the upstream name\r
119 -- con2-using msb balancer:query the server list and store in the ctx\r
120 ---------------------------------------------------------------\r
121 --set the http_protocol used by proxy_pass directive\r
122 ngx_var.http_protocol = svc_get_backend_protocol(svcinfo)\r
123 \r
124 if svc_use_own_upstream(svcinfo) then\r
125         local consul_servicename = svcinfo.spec["consulServiceName"]\r
126         if not consul_servicename or consul_servicename == "" then\r
127                 error_upstream_not_found()\r
128         end\r
129         ngx_var.backend = consul_servicename\r
130         ngx.ctx.use_ownupstream = true\r
131 else\r
132         local backservers = svcinfo.spec.nodes\r
133         if tbl_isempty(backservers) then\r
134                 error_svc_not_found("No active backend server found!"," key--"..svc_key)\r
135         end\r
136         ngx_ctx.backservers = backservers\r
137         ngx_ctx.svc_key = svc_key\r
138 end