backnero opened a new issue #1508:
URL: https://github.com/apache/incubator-apisix/issues/1508


   ### Issue description
   Based on the proxy-rewriting plugin, the argex_host configuration item is 
added, and the purpose is to forward it to a.ns.svc.cluster.local when the user 
curl a.test.cp.io to access it.
   
   **The routing configuration is as follows**
   ```
   {
       "host": "*.test.me.com",
       "methods": [ ],
       "uri": "/*",
       "plugins": {
                           "pan-forward": {
                                            "regex_host": 
["(.).test.me.com","$1.test.svc.cluster.local"],
                                            "scheme": "http"
                                }
                       },
        "upstream": {
           "type": "roundrobin",
           "nodes": {
               "192.168.1.100:3000": 1
           }
       },
        "desc": "test url redirect"
   }
   ```
   If upstream is configured, it is not successfully forwarded to the host. If 
upstream is not configured, no upstream configuration error is reported in 
error.log.
   
   **pan-forward.lua:**
   ```
   
   local core        = require("apisix.core")
   local plugin_name = "pan-forward"
   local pairs       = pairs
   local ipairs      = ipairs
   local ngx         = ngx
   local type        = type
   local re_sub      = ngx.re.sub
   
   
   local schema = {
       type = "object",
       properties = {
           uri = {
               description = "new uri for upstream",
               type        = "string",
               minLength   = 1,
               maxLength   = 4096,
               pattern     = [[^\/.*]],
           },
           regex_uri = {
               description = "new uri that substitute from client uri " ..
                             "for upstream, lower priority than uri property",
               type        = "array",
               maxItems    = 2,
               minItems    = 2,
               items       = {
                   description = "regex uri",
                   type = "string",
               }
           },
           host = {
               description = "new host for upstream",
               type        = "string",
               pattern     = "^[0-9a-zA-Z-.]+$",
           },
           regex_host ={
               description = "new host that substitute from client host " ..
                             "for upstream, lower priority than host property",
               type        = "array",
               maxItems    = 2,
               minItems    = 2,
               items       = {
                   description = "regex host",
                   type = "string",
               }
           },
           scheme = {
               description = "new scheme for upstream",
               type    = "string",
               enum    = {"http", "https"}
           },
           headers = {
               description = "new headers for request",
               type = "object",
               minProperties = 1,
           },
       },
       minProperties = 1,
   }
   
   
   local _M = {
       version  = 0.1,
       priority = 1008,
       name     = plugin_name,
       schema   = schema,
   }
   
   
   function _M.check_schema(conf)
       local ok, err = core.schema.check(schema, conf)
       if not ok then
           return false, err
       end
   
       if conf.regex_uri and #conf.regex_uri > 0 then
           local _, _, err = re_sub("/fake_uri", conf.regex_uri[1],
                                      conf.regex_uri[2], "jo")
           if err then
               return false, "invalid regex_uri(" .. conf.regex_uri[1] ..
                               ", " .. conf.regex_uri[2] .. "): " .. err
           end
       end
   
       if conf.regex_host and #conf.regex_host > 0 then
           local _, _, err = re_sub("featue.test.qisuyun.cn", 
conf.regex_host[1],
                                      conf.regex_host[2], "jo")
           if err then
               return false, "invalid regex_host(" .. conf.regex_host[1] ..
                               ", " .. conf.regex_host[2] .. "): " .. err
           end
       end
   
       --reform header from object into array, so can avoid use pairs, which is 
NYI
       if conf.headers then
           conf.headers_arr = {}
   
           for field, value in pairs(conf.headers) do
               if type(field) == 'string'
                   and (type(value) == 'string' or type(value) == 'number') then
                   if #field == 0 then
                       return false, 'invalid field length in header'
                   end
                   core.table.insert(conf.headers_arr, field)
                   core.table.insert(conf.headers_arr, value)
               else
                   return false, 'invalid type as header value'
               end
           end
       end
       return true
   end
   
   
   do
       local upstream_vars = {
           scheme     = "upstream_scheme",
           -- host       = "upstream_host",
           upgrade    = "upstream_upgrade",
           connection = "upstream_connection",
       }
       local upstream_names = {}
       for name, _ in pairs(upstream_vars) do
           core.table.insert(upstream_names, name)
       end
   
   function _M.rewrite(conf, ctx)
       for _, name in ipairs(upstream_names) do
           if conf[name] then
               ctx.var[upstream_vars[name]] = conf[name]
           end
       end
       -- 重写host
       local upstream_host = ctx.var.host
       if conf.host ~= nil then
           upstream_host = conf.host
       elseif conf.regex_host ~= nil then
           local host, _, err = re_sub(ctx.var.host, conf.regex_host[1],
                                      conf.regex_host[2], "jo")
           if host then
               upstream_host = host
               print(upstream_host)
           else
               local msg = "failed to substitute the host " .. ctx.var.host ..
                           " (" .. conf.regex_host[1] .. ") with " ..
                           conf.regex_host[2] .. " : " .. err
               core.log.error(msg)
               return 500, {message = msg}
           end
       end
       -- 重写url
       local upstream_uri = ctx.var.uri
       if conf.uri ~= nil then
           upstream_uri = conf.uri
       elseif conf.regex_uri ~= nil then
           local uri, _, err = re_sub(ctx.var.uri, conf.regex_uri[1],
                                      conf.regex_uri[2], "jo")
           if uri then
               upstream_uri = uri
           else
               local msg = "failed to substitute the uri " .. ctx.var.uri ..
                           " (" .. conf.regex_uri[1] .. ") with " ..
                           conf.regex_uri[2] .. " : " .. err
               core.log.error(msg)
               return 500, {message = msg}
           end
       end
   
       if ctx.var.is_args == "?" then
           ctx.var.upstream_uri = upstream_uri .. "?" .. (ctx.var.args or "")
       else
           ctx.var.upstream_uri = upstream_uri
       end
   
       if conf.headers_arr then
           local field_cnt = #conf.headers_arr
           for i = 1, field_cnt, 2 do
               ngx.req.set_header(conf.headers_arr[i], conf.headers_arr[i+1])
           end
       end
   end
   
   end  -- do
   
   
   return _M
   
   ```
   
   
   ### Environment
   
   * apisix version (cmd: `apisix version`): 1.2
   * OS: centos7
   * Docker
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to