在 Nginx 上将 TCP 连接转发到 HTTP

问题描述 投票:0回答:3

我正在运行一个应用程序,它接受来自 GPS 记录器的数据,这些数据通过 SMS、HTTP 或 TCP 发送。我使用 HTTP 连接来传输数据,通过我的 Rails 应用程序上的 GET 请求可以直接接收数据。

为了节省电池,我们将连接更改为纯 TCP,并且 nginx 目前不接受这些请求:

来自nginx的access.log:

HTTP:

xx.xx.xx.xxx - - [03/Mar/2013:20:17:45 -0500] "GET /?imei=123456789012345&rmc=$GPRMC,035106.000,A,4145.1451,N,08506.8784,W,1.56,176.49,010213,,*13,3656mV,AUTO HTTP/1.1" 302 247 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22"

TCP:

xx.xx.xx.xxx - - [03/Mar/2013:18:31:22 -0500] "imei=123456789012345&rmc=$GPRMC,233012.000,A,4221.6614,N,07106.1014,W,17.25,218.94,030313,,*21,4102mV,AUTO,310,260,ADB7,13EF,057,310,260,0000,0000,044,310,260,0000,0000,055,310,260,0000,0000,05A,310,260,0000,0000,059,310,260,0000,0000,05E,0,0,0000,0000,000,2" 400 172 "-" "-"

有谁知道在 Nginx 上过滤这些 TCP 请求并将其处理为 HTTP GET 请求以通过 Rails 应用程序使用的方法吗?

提前致谢

答案:

我能够通过使用 em-proxy 和 Faraday 创建自定义代理来实现此目的:

require 'em-proxy'
require 'faraday'

Proxy.start(:host => "0.0.0.0", :port => 8080, :debug => false) do |conn|

  conn.on_data do |data|
    http = Faraday.new(:url => 'http://example.com') do |faraday|
      faraday.request  :url_encoded             # form-encode POST params
      faraday.response :logger                  # log requests to STDOUT
      faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
    end
    http.get "/upload?#{data}"
  end
end
ruby-on-rails ruby http tcp nginx
3个回答
0
投票

你应该看看网络套接字。 Nginx 现在对它们有本机支持,但是 Nginx 有一个旧模块也可以完成这项工作。

这是一个较旧的问题,提供了两种解决方案。


0
投票

示例脚本 nginx :

server 
{

        listen 443 default ssl;
        listen [::]:443 ssl;
        root /var/www/html/api_mobile/public;

        include snippets/ssl-params.conf;

        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Content-Type-Options "nosniff";
        index index.html index.php index.htm index.nginx-debian.html;

        server_name sitename.com;

        charset utf-8;
        location / {
             if ($scheme ="http") {
                # redirect all non api traffic to https block
                return 301 https://$server_name$request_uri;
             }           

            try_files $uri $uri/ /index.php?$query_string;
        }

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


        error_page 404 /index.php;
        location ~ \.php$ {
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            include fastcgi_params;
        }

    ssl_certificate /etc/letsencrypt/live/sites/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/site/privkey.pem; # managed by Certbot
}

关于计划条件:

if ($scheme ="http") 
{
                # redirect all non api traffic to https block
                return 301 https://$server_name$request_uri;
}   

它在一个端口 443 https 上重定向的核心强制 http 到 https


-2
投票

Nginx 是一个 HTTP 服务器,因此它期望客户端使用 HTTP。 不可能让客户端以您所描述的方式与 nginx 进行非 HTTP 协议(好吧,也许您可以编写一个自定义模块来做到这一点,但这似乎很愚蠢)。

我认为你需要做的是编写自己的代理服务器,它将原始 TCP 协议转换为 HTTP 请求。 您的 GPS 记录器将与代理通信,然后代理将与 nginx 通信。 这应该相当简单,因为 TCP 有效负载似乎只是一个 urlencoded 字符串,因此您可以直接使用它们。

© www.soinside.com 2019 - 2024. All rights reserved.