[GH-ISSUE #4403] [Feature Request] 基于uri路径的http代理模式 #3478

Closed
opened 2026-05-05 14:14:10 -06:00 by gitea-mirror · 2 comments
Owner

Originally created by @lqian on GitHub (Aug 24, 2024).
Original GitHub issue: https://github.com/fatedier/frp/issues/4403

Describe the feature request

目前很多智能设备内置了HTTP服务用于管理设备,这些设备http服务的使用率并不高。如果用customDomain去做http代理,则需要为这些设备申请域名,如果用端口模式的http代理,则这些端口的利用率非常低。
比如有一系列的设备序列号a,b,c,d,,,,,,且假设有一个域名ops.xxx.top, 能否支持基于uri路径的http代理模式,
http://ops.xxx.top/a 映射到设备a的http 80端口
http://ops.xxx.top/b 映射到设备b的http 80端口 ?

Describe alternatives you've considered

No response

Affected area

  • Docs
  • Installation
  • Performance and Scalability
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
Originally created by @lqian on GitHub (Aug 24, 2024). Original GitHub issue: https://github.com/fatedier/frp/issues/4403 ### Describe the feature request 目前很多智能设备内置了HTTP服务用于管理设备,这些设备http服务的使用率并不高。如果用customDomain去做http代理,则需要为这些设备申请域名,如果用端口模式的http代理,则这些端口的利用率非常低。 比如有一系列的设备序列号a,b,c,d,,,,,,且假设有一个域名ops.xxx.top, 能否支持基于uri路径的http代理模式, http://ops.xxx.top/a 映射到设备a的http 80端口 http://ops.xxx.top/b 映射到设备b的http 80端口 ? ### Describe alternatives you've considered _No response_ ### Affected area - [ ] Docs - [ ] Installation - [X] Performance and Scalability - [ ] Security - [ ] User Experience - [ ] Test and Release - [X] Developer Infrastructure - [ ] Client Plugin - [X] Server Plugin - [ ] Extensions - [ ] Others
Author
Owner

@xjetry commented on GitHub (Aug 25, 2024):

You can do this with OpenResty

server side:

frps.toml

vhostHTTPPort=8080

nginx server block

server {
    listen 80;
    server_name foo.bar;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name foo.bar;

    ssl_certificate /path/to/crt/foo.bar.crt;
    ssl_certificate_key /path/to/key/foo.bar.key;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

client side:

frpc.toml

[[proxies]]
type = "http"
localPort = 5000
localIP = "openresty"
customDomains = ["foo.bar"]

requestHeaders.set.frp-dest = "10.0.0.2:8080"
locations = ["/a"]
requestHeaders.set.frp-route-path = "/a"
name = "example"

open-resty server block

server {
    listen 5000;
    server_name localhost;
    error_log /opt/bitnami/openresty/nginx/logs/debug.log debug;
    set_by_lua_block $frp_dest {
        local frp_dest = ngx.var.http_frp_dest
        if frp_dest == nil or frp_dest == '' then
            ngx.status = 400
            ngx.say('Bad Request: Missing frp-dest header')
            ngx.exit(ngx.HTTP_BAD_REQUEST)
        end
        return frp_dest
    }

    set_by_lua_block $frp_route_path {
        return ngx.var.http_frp_route_path or ''
    }

    location / {
        access_by_lua_block {
            local frp_route_path = ngx.var.frp_route_path
            if frp_route_path and frp_route_path ~= '' then
                local new_uri, n, err = ngx.re.sub(ngx.var.uri, "^" .. frp_route_path .. "/(.*)", "/$1", "jo")
                if new_uri then
                    ngx.req.set_uri(new_uri, false)
                else
                    ngx.log(ngx.ERR, "error on rewrite: ", err)
                    return ngx.exit(500)
                end
            end
        }
        proxy_pass http://$frp_dest;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

docker-compose:

version: '3'

services:
  openresty:
    image: bitnami/openresty:latest
    container_name: openresty
    volumes:
      - ./openresty.conf:/opt/bitnami/openresty/nginx/conf/server_blocks/frpc.conf:ro

  frpc:
    image: snowdreamtech/frpc:latest
    container_name: frpc
    volumes:
      - ./frpc.toml:/frpc.toml:ro
    command: -c /frpc.toml
    depends_on:
      - openresty

visit: https://foo.bar/a/echo

<!-- gh-comment-id:2308676753 --> @xjetry commented on GitHub (Aug 25, 2024): You can do this with OpenResty ## server side: ### frps.toml ```toml vhostHTTPPort=8080 ``` ### nginx server block ```conf server { listen 80; server_name foo.bar; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name foo.bar; ssl_certificate /path/to/crt/foo.bar.crt; ssl_certificate_key /path/to/key/foo.bar.key; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ## client side: frpc.toml ```toml [[proxies]] type = "http" localPort = 5000 localIP = "openresty" customDomains = ["foo.bar"] requestHeaders.set.frp-dest = "10.0.0.2:8080" locations = ["/a"] requestHeaders.set.frp-route-path = "/a" name = "example" ``` open-resty server block ```conf server { listen 5000; server_name localhost; error_log /opt/bitnami/openresty/nginx/logs/debug.log debug; set_by_lua_block $frp_dest { local frp_dest = ngx.var.http_frp_dest if frp_dest == nil or frp_dest == '' then ngx.status = 400 ngx.say('Bad Request: Missing frp-dest header') ngx.exit(ngx.HTTP_BAD_REQUEST) end return frp_dest } set_by_lua_block $frp_route_path { return ngx.var.http_frp_route_path or '' } location / { access_by_lua_block { local frp_route_path = ngx.var.frp_route_path if frp_route_path and frp_route_path ~= '' then local new_uri, n, err = ngx.re.sub(ngx.var.uri, "^" .. frp_route_path .. "/(.*)", "/$1", "jo") if new_uri then ngx.req.set_uri(new_uri, false) else ngx.log(ngx.ERR, "error on rewrite: ", err) return ngx.exit(500) end end } proxy_pass http://$frp_dest; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` docker-compose: ```yml version: '3' services: openresty: image: bitnami/openresty:latest container_name: openresty volumes: - ./openresty.conf:/opt/bitnami/openresty/nginx/conf/server_blocks/frpc.conf:ro frpc: image: snowdreamtech/frpc:latest container_name: frpc volumes: - ./frpc.toml:/frpc.toml:ro command: -c /frpc.toml depends_on: - openresty ``` visit: https://foo.bar/a/echo
Author
Owner

@lqian commented on GitHub (Aug 25, 2024):

great!

<!-- gh-comment-id:2308754182 --> @lqian commented on GitHub (Aug 25, 2024): great!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/frp#3478
No description provided.