orange icon indicating copy to clipboard operation
orange copied to clipboard

orange invalid URL prefix in

Open liulei18 opened this issue 5 years ago • 19 comments

我查到的相关信息

我查到已经有人提了pr,修复了此bug:https://github.com/orlabs/orange/pull/240/commits/c718ce102425796d55be82c74faa28c68135399b 并且该pr我看已经合并到master中,但是该bug并没有解决。lol,版本及配置信息如下 注:我使用的orange是clone的最新的master分支的代码

使用的Orange版本

Orange: 0.7.0

需求或场景

将/appdata 重写成/api/appdata

使用的插件

Rewrite插件

具体的配置

nginx.conf

server {
        listen       80;
        server_name  orange.com;

        location = /favicon.ico {
            log_not_found off;
            access_log off;
        }

        location / {
            set $upstream_host $host;
            set $upstream_request_uri '';
            set $upstream_url '';
            set $upstream_scheme '';
            set $target '';

            rewrite_by_lua_block {
                local orange = context.orange
                orange.redirect()
                orange.rewrite()
            }

            access_by_lua_block {
                local orange = context.orange
                orange.access()
            }

            # proxy
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass $upstream_scheme$upstream_url$upstream_request_uri;

            header_filter_by_lua_block {
                local orange = context.orange
                orange.header_filter()
            }

            body_filter_by_lua_block {
                local orange = context.orange
                orange.body_filter()
            }

            log_by_lua_block {
                local orange = context.orange
                orange.log()
            }
        }

        location /robots.txt {
            return 200 'User-agent: *\nDisallow: /';
        }
    }

dashbord中规则如下

{
  "name": "appdata",
  "judge": {
    "type": 0,
    "conditions": [
      {
        "type": "URI",
        "operator": "match",
        "value": "appdata"
      }
    ]
  },
  "extractor": {
    "type": 1,
    "extractions": []
  },
  "handle": {
    "uri_tmpl": "/api/appdata",
    "log": true
  },
  "enable": true
}
期望的结果

浏览器访问:http://orange.com/appdata 日志报错

2019/07/08 19:11:08 [error] 87443#0: *26 invalid URL prefix in "", client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
错误的结果
2019/07/08 19:11:08 [info] 87443#0: *26 [lua] handler.lua:85: rewrite(): ==[Rewrite][PASS THROUGH SELECTOR:cf067719-ff7d-4401-a1bb-35df5def11ad], client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
2019/07/08 19:11:08 [info] 87443#0: *26 [lua] handler.lua:97: rewrite(): [Rewrite][PASS-SELECTOR:cf067719-ff7d-4401-a1bb-35df5def11ad] /appdata, client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
2019/07/08 19:11:08 [info] 87443#0: *26 [lua] handler.lua:36: filter_rules(): [Rewrite] /appdata to:/api/appdata, client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
2019/07/08 19:11:08 [info] 87443#0: *26 [lua] handler.lua:85: rewrite(): ==[Rewrite][PASS THROUGH SELECTOR:cf067719-ff7d-4401-a1bb-35df5def11ad], client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
2019/07/08 19:11:08 [info] 87443#0: *26 [lua] handler.lua:97: rewrite(): [Rewrite][PASS-SELECTOR:cf067719-ff7d-4401-a1bb-35df5def11ad] /api/appdata, client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
2019/07/08 19:11:08 [info] 87443#0: *26 [lua] handler.lua:95: access(): ==[Divide][PASS THROUGH SELECTOR:f302f4bf-1cb9-48c4-b40b-1f2051d4420e], client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
2019/07/08 19:11:08 [error] 87443#0: *26 invalid URL prefix in "", client: 192.168.90.26, server: orange.com, request: "GET /appdata HTTP/1.1", host: "orange.com"
从日志可见,URL确实被重写了,但是最终这个invalid URL prefix in "",我查找了源码,没有找到原因,希望帮忙解答,thanks

liulei18 avatar Jul 08 '19 11:07 liulei18

你在你的server段里加上一个 location /api就行了 server { listen 80; server_name orange.com;

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location / {
        set $upstream_host $host;
        set $upstream_request_uri '';
        set $upstream_url '';
        set $upstream_scheme '';
        set $target '';

        rewrite_by_lua_block {
            local orange = context.orange
            orange.redirect()
            orange.rewrite()
        }

        access_by_lua_block {
            local orange = context.orange
            orange.access()
        }

        # proxy
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Scheme $scheme;
        proxy_pass $upstream_scheme$upstream_url$upstream_request_uri;

        header_filter_by_lua_block {
            local orange = context.orange
            orange.header_filter()
        }

        body_filter_by_lua_block {
            local orange = context.orange
            orange.body_filter()
        }

        log_by_lua_block {
            local orange = context.orange
            orange.log()
        }
    }
   #  加上这个
    location /api {
        default_type text/plain;
        return 200 "this is appdata after rewrite";
    }

    location /robots.txt {
        return 200 'User-agent: *\nDisallow: /';
    }
}

zhangbao0325 avatar Jul 09 '19 07:07 zhangbao0325

疑问

  • nginx.conf 配置文件中location /{} 中这些变量是否必须配置,有什么作用,希望提供文档说明
            set $upstream_host $host;
            set $upstream_request_uri '';
            set $upstream_url '';
            set $upstream_scheme '';
            set $target '';
  • nginx.conf的location /xxxx中以下配置是否是必须?还是说,我需要用哪个插件,就配置相应的block块,比如,我需要用rewrite插件,将appdata 重写成/api/appdata,就在对应 location中只加入rewrite_by_lua_block {}?比如我只需要限速插件,只需要在location中添加access_by_lua_block {}相关配置,其他的不用配置?
            rewrite_by_lua_block {
                local orange = context.orange
                orange.redirect()
                orange.rewrite()
            }

            access_by_lua_block {
                local orange = context.orange
                orange.access()
            }
            proxy_pass $upstream_scheme$upstream_url$upstream_request_uri;

            header_filter_by_lua_block {
                local orange = context.orange
                orange.header_filter()
            }

            body_filter_by_lua_block {
                local orange = context.orange
                orange.body_filter()
            }

            log_by_lua_block {
                local orange = context.orange
                orange.log()
            }
  • 关于dashbord中URL重写插件中添加选择器和添加规则怎么使用? 选择器中可以配置规则,但是不可以做处理,那么我的规则都配置到selector下面,那么我在selector下面添加新规则的时候,只需要做处理,但是没有办法提交,提示我必须添加规则。但是我添加选择器的同时已经添加了两条规则,不需要再添加新规则,我只需要在新规则中进行处理就好了。
  1. 我的解决方案,将规则全部配置到selector下面,但是我不理解selector中也可以添加规则的意义在哪里?
  2. 既然selector中可以添加规则,那么我在配置完为什么不能再selector中做处理?
  3. 现在加入我在selector中添加了我的所有规则,只能去新规则中配置处理程序,但是新建规则必须添加一条规则,但是我的规则已经在selector中配置完了,难道我需要在配置一遍? image

liulei18 avatar Jul 09 '19 07:07 liulei18

第一个问题: 这些set配置不是必须的,这些变量是部分插件里会用到的,并且会根据你配的规则来改写这些变量的值,如果你不用相关插件,这些变量不配置也不会影响。 第二个问题: 每个插件的执行阶段是不一样的,有的在rewrite_by_lua阶段,有的在access_by_lua阶段,有的在balancer_by_lua阶段,如果有些插件功能你不用到,不配置也可以,但是建议去修改orange.conf里的配置来卸载和加载插件,而不是改nginx.conf配置。 第三个问题:你可以理解selector是 一个粗分,rule是细分。一般情况下,selector里可以配置成全流量选择器,表示对所有的请求对生效,然后在rule里设置对具体的接口匹配。或者是可以在selector里配置自定义选择器(比如按照域名进行一级筛分),然后在rule里配置更加细粒度的规则(比如uri match /appdata)。 具体的逻辑,你可以参照plugins下的各插件的源码分析。

zhangbao0325 avatar Jul 09 '19 07:07 zhangbao0325

第二个问题:也就是建议每一个location都需要配置以下这些配置吗,即使某一个插件在dashbord中是禁用状态?假如我需要卸载插件,去修改orange.conf? 也就是说:我假如将location中 rewrite_by_lua_block {}配置删除掉,即使我在dashbord启用了URL重写插件,但是重写的规则也不会生效,对吧?

        location / {
            
            rewrite_by_lua_block {
                local orange = context.orange
                orange.redirect()
                orange.rewrite()
            }

            access_by_lua_block {
                local orange = context.orange
                orange.access()
            }

            # proxy
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Scheme $scheme;
            proxy_pass xxxx;

            header_filter_by_lua_block {
                local orange = context.orange
                orange.header_filter()
            }

            body_filter_by_lua_block {
                local orange = context.orange
                orange.body_filter()
            }

            log_by_lua_block {
                local orange = context.orange
                orange.log()
            }
        }

第三个问题:我看过饭总的公开分享,我想知道的是全流量选择器和自定义选择器的优缺点,他们分别适用哪种情况,我应该在什么场景下用全流量选择器,什么情况下用自定义流量选择器,我稍微明白了一点自定义选择器根据上诉你的回答,但是全流量选择器在什么情况下使用? thanks...

liulei18 avatar Jul 09 '19 08:07 liulei18

1 配置rewrite_by_lua_block的本质目的是让它执行orange.rewrite(),你可以看到orange.rewrite里会去依次执行每个插件在rewrite阶段的逻辑。如果你删除了rewrite_by_lua_block,那你配置的rewrite插件规则都不会生效。另外,这个也不是说一定要写在server段里,如果你为了方便,写在http段里也是可以的,这样的话就会对所有的server配置都生效。 2 如果你配置了全流量选择器,那么只要一个请求过来了,这个selector都会匹配中,然后会进一步的去匹配这个full selector底下的rule,但这会影响效率。 比如我就希望A.com的这个域名下的所有接口都生效,那我完全可以在selector里配置成自定义的: host match A.com,然后在这个selector下去配具体的规则。这样如果来的请求是B.com,则它在selector的判断阶段都不通过,也不会再去多余的判断A.com底下有哪些规则了。说白了就是给你提供一个先一级筛分,再二级筛分的手段,避免不必要的遍历操作。

zhangbao0325 avatar Jul 09 '19 08:07 zhangbao0325

  1. 明白了,不知道大家在生产环境中的经验是怎样的,是将这些配置http段?server段还是location段?还是说要根据自己需求,比如我只有某个domain需要使用orange的插件,我就把这些配置配置到该server段,因为毕竟执行类似于orange.rewrite()这样的操作也是需要一些耗时的。我的理解对吗?

liulei18 avatar Jul 09 '19 08:07 liulei18

我们的生产环境中,selector全部配置的是按照域名筛分,即host == A.com, 然后在每个域名对应的selector下配置接口的规则。 如果只有一个domain用到了,可以只写在这里面,其他sever段的请求不受orange插件的影响。

zhangbao0325 avatar Jul 09 '19 09:07 zhangbao0325

如下配置:

        location /test {

            rewrite_by_lua_block {
                local orange = context.orange
                orange.redirect()
                orange.rewrite()
            }

            access_by_lua_block {
                local orange = context.orange
                orange.access()
            }

            # proxy
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Scheme $scheme;
            #proxy_pass $upstream_scheme$upstream_url$upstream_request_uri;
            proxy_pass xxxxx;


            header_filter_by_lua_block {
                local orange = context.orange
                orange.header_filter()
            }

            body_filter_by_lua_block {
                local orange = context.orange
                orange.body_filter()
            }

            log_by_lua_block {
                local orange = context.orange
                orange.log()
            }
        }

需求:假如我需要在rewrite阶段写一些自定义的lua代码,是否建议我直接在上面配置rewrite_by_lua_block{}中直接添加自定义的代码,假如可以,我自定义的代码应该加在下面代码的前面还是后面? local orange = context.orange orange.header_filter()

liulei18 avatar Jul 09 '19 09:07 liulei18

如果逻辑比较复杂,建议你去orange的项目里增加自己的逻辑代码,而不是写在nginx配置文件中,或者修改已有插件的逻辑,或者根据自己的需求打造一个插件,放在plugins目录下即可。

zhangbao0325 avatar Jul 09 '19 11:07 zhangbao0325

像以前的divide之类的插件,http://orange.sumory.com/docs/, 是有使用示例,v0.7.0新增的插件,比如balancer插件,jwt_auth插件...的相关文档,可以从哪里获取?

liulei18 avatar Jul 10 '19 03:07 liulei18

你好,我这边安装orange 一直没安装成功 orange start 启动报这个错 nginx: [error] init_by_lua error: ./lualib/resty/pl/path.lua:28: pl.path requires LuaFileSystem 但是 luafilesystem 1.7.0-2 is now built and installed in /usr/local (license: MIT/X11) 是装了的

okada8 avatar Jul 28 '19 02:07 okada8

你好,我这边安装orange 一直没安装成功 orange start 启动报这个错 nginx: [error] init_by_lua error: ./lualib/resty/pl/path.lua:28: pl.path requires LuaFileSystem 但是 luafilesystem 1.7.0-2 is now built and installed in /usr/local (license: MIT/X11) 是装了的

1 你可以在nginx.conf里将lua_package_path里加上你luafilesystem 1.7.0-2的安装路径。 2 尝试使用luarocks安装luafilesystem。

zhangbao0325 avatar Jul 28 '19 02:07 zhangbao0325

重新安装 centost7 启动报这个错 usr/local/openresty/nginx/sbin/nginx: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

okada8 avatar Jul 28 '19 05:07 okada8

nginx: [error] init_by_lua error: init_by_lua:2: module 'orange.orange' not found:

okada8 avatar Jul 28 '19 05:07 okada8

上面这些问题解决了 新问题来了

okada8 avatar Jul 28 '19 06:07 okada8

nginx: [error] [lua] orange.lua:75: init(): Startup error: ../orange/orange.lua:67: attempt to index upvalue 'config' (a nil value)

okada8 avatar Jul 28 '19 06:07 okada8

你们都是好几年前弄好,然后不断的在原来的基础上更新,修改,你们有测试过现在还能安装成功吗,坑一大堆,装都装不成功,怎么用

okada8 avatar Jul 28 '19 07:07 okada8

你们都是好几年前弄好,然后不断的在原来的基础上更新,修改,你们有测试过现在还能安装成功吗,坑一大堆,装都装不成功,怎么用

  • please follow the README.md strictly to install orange.here are some suggetsions, as you mentioned,you use make install to install Orange in the directory /usr/local/orange.and you should execute orange start in directory /usr/local/orange.by the way,i install successfully on the centos.

nginx: [error] [lua] orange.lua:75: init(): Startup error: ../orange/orange.lua:67: attempt to index upvalue 'config' (a nil value)

  • check the configure file conf/orange.conf.making sure it is a correct json format.

liulei18 avatar Jul 29 '19 03:07 liulei18

第一个问题:这些Set配置不是必须的,这些变量是部分插件里会用到的,并且会根据你配的规则来改写这些变量的值,如果你不用相关插件,这些变量不配置也不会影响. 第二个问题:每个插件的执行阶段是不一样的,有的在重写_by_lua_lua阶段,有的在access_by_lua阶段,有的在平衡器_by_lua阶段,如果有些插件功能你不用到,不配置也可以,但是建议去修改orange.conf里的配置来卸载和加载插件,而不是改nginx.conf配置。 第三个问题:你可以理解选择器是一个粗分,规则是细分。一般情况下,选择器里可以配置成全流量选择器,表示对所有的请求对生效,然后在规则里设置对具体的接口匹配.或者是可以在选择器里配置自定义选择器(比如按照域名进行一级筛分),然后在规则里配置更加细粒度的规则(比如uri Match/AppData)。 具体的逻辑,你可以参照插件下的各插件的源码分析。

你好,我在url重定向里面指向了百度,在rate limiting里面限制1小时1次,并没有进行限制,能帮忙解决一下吗?谢谢

guoxiankai avatar Sep 25 '19 04:09 guoxiankai