nginx通过自定义header对象来转发

原文链接:https://www.cnblogs.com/xiao987334176/p/11263649.html

一,自定义的header头部

因为需要上线灰度发布,只要nginx接收到头部为:

x_app:123456

就会跳转到另外一个url,比如:

1.0.0.10:8080

通过配置nginx 匹配请求头wx_unionid 来转发到灰度环境。
核心:客户端自定义的http header,在nginx的配置文件里能直接读取到。
条件:header必须用减号“-”分隔单词,nginx里面会转换为对应的下划线“_”连接的小写单词。

二、修改Nginx配置

安装nginx

apt-get install -y nginx

编辑主页

cd /etc/nginx/sites-enabled
vim home.conf

内容如下:

upstream wx {
    server 127.0.0.1:8080;
}

server {
    listen 8008;
    server_name localhost;

    root html;
    index index.html;

    charset utf-8;
    underscores_in_headers on;
    location / {
        #测试header转发
        if ($http_x_app = "123456") {
            proxy_pass http://wx;
        }
    }
} 

参数配置说明

underscores_in_headers on:nginx是支持读取非nginx标准的用户自定义header的,但是需要在http或者server下开启header的下划线支持:
比如我们自定义header为wx_unionid,获取该header时需要这样:$http_wx_unionid(一律采用小写,而且前面多了个http_)

如果需要把自定义header传递到下一个nginx:
1.如果是在nginx中自定义采用proxy_set_header X_CUSTOM_HEADER $http_host;
2.如果是在用户请求时自定义的header,例如curl
–head -H “X_CUSTOM_HEADER: foo”
http://domain.com/api/test,则需要通过proxy_pass_header X_CUSTOM_HEADER来传递

编辑调整页

vim wx.conf

内容如下:

server {
    listen 8080;
    server_name localhost;

    root /var/www/html;
    index wx.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

增加测试页面

vim /var/www/html/wx.html

内容如下:

<h1>微信小程序测试平台</h1>

三、测试结果

加自定义头部

[email protected]:~# curl -v -H ‘wx_unionid:123456‘ 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 07:49:46 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 37
< Connection: keep-alive
< Last-Modified: Mon, 29 Jul 2019 06:23:49 GMT
< ETag: "5d3e90f5-25"
< Accept-Ranges: bytes
<
<h1>微信小程序测试平台</h1>
* Connection #0 to host 127.0.0.1 left intact

不加头部

[email protected]:~# curl -v 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 07:50:13 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
< Connection: keep-alive
< ETag: "5890a6b7-264"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

四、匹配多条件

现在又多了一个需求,需要对客户端ip为:192.168.0.45,同时也增加自定义头部wx_unionid:123456,才会转发,否则不做转发。

nginx的配置中不支持if条件的逻辑与&& 逻辑或|| 运算 ,而且不支持if的嵌套语法,否则会报下面的错误:nginx: [emerg] invalid condition。

我们可以用变量的方式来间接实现。

要实现的语句:

if ($remote_addr ~* "192.168.0.45" && $http_wx_unionid = "123456"){
    proxy_pass http://wx;
}

如果按照这样来配置,就会报nginx: [emerg] invalid condition错误。

如下:

nginx: [emerg] invalid condition "$http_wx_unionid" in /etc/nginx/sites-enabled/home.conf:16
nginx: configuration file /etc/nginx/nginx.conf test failed

可以这么来实现,如下所示:

upstream wx {
    server 127.0.0.1:8080;
}

server {
    listen 8008;
    server_name localhost;

    root html;
    index index.html;

    charset utf-8;
    underscores_in_headers on;
    location / {
        #测试header转发
        # 标志位
        set $flag 0;
        if ($remote_addr ~* "192.168.0.45"){
             # 末尾追加1,此时$flag=01
             set $flag "${flag}1";
        }
        if ($http_wx_unionid = "123456"){
            # 末尾追加1,此时$flag=011
            set $flag "${flag}1";
        }
        # 当为011时,表示条件都匹配
        if ($flag = "011") {
            proxy_pass http://wx;
        }
    }
} 

重新加载配置

nginx -s reload

再次使用本机测试,增加头部

[email protected]:~# curl -v -H ‘wx_unionid:123456‘ 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 08:01:30 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
< Connection: keep-alive
< ETag: "5890a6b7-264"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

登录到192.168.0.45,增加头部测试

[email protected]:~# curl -v -H ‘wx_unionid:123456‘ 192.168.0.162:8008
* Rebuilt URL to: 192.168.0.162:8008/
*   Trying 192.168.0.162...
* Connected to 192.168.0.162 (192.168.0.162) port 8008 (#0)
> GET / HTTP/1.1
> Host: 192.168.0.162:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 08:02:01 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 37
< Connection: keep-alive
< Last-Modified: Mon, 29 Jul 2019 06:23:49 GMT
< ETag: "5d3e90f5-25"
< Accept-Ranges: bytes
<
<h1>微信小程序测试平台</h1>
* Connection #0 to host 192.168.0.162 left intact

原文地址:https://www.cnblogs.com/kaishirenshi/p/12120639.html

时间: 2024-10-09 19:58:16

nginx通过自定义header对象来转发的相关文章

apache设置自定义header

1. 在设置自定义header前,需要先检测一下你的httpd是否加载了mod_headers /usr/local/apache2/bin/apachectl  -l 如果,显示有mode_headers.c  则是加载了这个模块,否则就需要重新编译一下了.另外,如果你使用的是rpm安装的话,那肯定是已经加载了mod_headers这个模块的. 2.  在httpd.conf 中加入 Header add MyHeader "Hello" 保存后,重启apache就可以了双引号中的内

nginx反向代理proxy_set_header自定义header头无效的问题

###案例1环境nginx,linux,tomcat域名访问是走nginx给后端服务器处理的,问题是域名经过nginx访问直接不能获取到headers,直接tomcat访问可以那么问题肯定在nginx上无法处理headers的问题了, 经过查询上面资料得到是nginx的锅,hearders有下划线的锅,nginx设置underscores_in_headers on,参照上面配置说.就可以处理,测试:http://apistore.baidu.com/astore/toolshttpproxyA

nginx 自定义header 如何获取

PHP如何获取http头信息 http://www.oschina.net/question/1419181_178319 这个老问题里的答案没有一个回答对题主的问题: 问题的解决办法是 想获取到自定义的头如:USERNAME:OSCCHINA 网站的vhost看看 用到是nginx/conf下的fastcgi_params还是fastcgi.conf 在配置里添加下一行 fastcgi_param HTTP_USERNAME  $http_username; 重启nginx,然后在用$_SER

nginx日志输出自定义header头字段

这段时间做了一个web的项目,要求在日志中输出自定义的http header字段token和have-deleted的值, nginx版本为1.1.19,以下是具体的log配置: log_format  main      '$remote_addr - $remote_user [$time_local] $http_token                        $http_have_deleted "$request" '                       '

Laravel 5.5 的自定义验证对象/类

本文和大家分享的主要是Laravel 5.5 的自定义验证对象/类相关内容,一起来看看吧,希望对大家学习Laravel有所帮助. Laravel 5.5 将提供一个全新的自定义验证规则的对象,以作为原来的 Validator::extend 方法的替代. Laravel 中的表单验证是比较方便的,而且内置了大量的可用验证规则,但不管官方提供了多少,总还是会有满足不了需求的时候.很多时候我们会直接用正则表达式来处理这种特殊的验证,也有时候我们会选择用 Validator::extend来扩展一个自

自定义动态对象

1,自定义动态对象需要继承DynamicObject类 2,可根据需要,重写不同的DynamicObject方法 -----------------------------------------------------DynamicClass.cs  using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using S

在JavaScript中生成自定义的对象

使用对象便于组织信息.下面我们介绍如何在JavaScript中生成自定义的对象. ---------------------- JavaScript 对象 在前面几章中我们学到JavaScript中有些内置的对象,比如String, Date, Array等等.除此之外,你还可以定义自己的对象. 对象是一种特殊的数据,含有属性和函数. 下面让我们用一个例子来说明:比如一个人是一个对象.属性是与对象有联系的值,比如人的属性包括姓名,身高,体重,年龄,肤色,眼睛的颜色等等.所有人都有这些属性,但是每

QT: QByteArray储存二进制数据(包括结构体,自定义QT对象)

因为利用QByteArray可以很方便的利用其API对内存数据进行访问和修改, 构建数据库blob字段时必不可少; 那如何向blob内写入自定义的结构体和类 1. 利用memcpy拷贝内存数据 //自定义person结构体 Cpp代码   typedef struct { int age; char name[20]; }Person; //向QByteArray写入多个结构体 void writeStruct() { QByteArray ba; ba.resize(2*sizeof(Pers

对NSArray中自定义的对象进行排序

本文译自How to sort NSArray with custom objects. 我们开发的每个程序都会使用到一些数据,而这些数据一般被封装在一个自定义的类中.例如一个音乐程序可能会有一个Song类,聊天程序则又一个Friend类,点菜程序会有一个Recipe类等.有时候我们希望在程序中显示的列表数据是按照一定顺序进行排列的,本文我们就来看看在iOS中有哪些方法可以对NSArray中的对象进行排序.下面是目录: 小引 使用NSComparator进行排序 使用NSDescriptor进行