Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request help: support http proxy #53

Closed
GhangZh opened this issue Dec 10, 2021 · 8 comments
Closed

request help: support http proxy #53

GhangZh opened this issue Dec 10, 2021 · 8 comments

Comments

@GhangZh
Copy link

GhangZh commented Dec 10, 2021

Issue description

I want to support the forward-auth , but how does go-pugin-runner support me to proxy the current request directly to the url, and then process the response and pass it on?
I wrote a version in lua, but our technology stack is unified with go, so I want to use go to implement

    local core = require("apisix.core")
    local http = require("resty.http")
    local http_new = http.new()
    local res, err = http_new:request_uri("https://forward-auth.xxx.com", {
        ssl_verify = false,
        method = "GET",
        headers = {
            ["X-Forwarded-User"] = core.request.header(ctx, "X-Forwarded-User"),
            ["X-Forwarded-UID"] = core.request.header(ctx, "X-Forwarded-UID"),
            ["Cookie"]=core.request.header(ctx,"Cookie")
        },
    })
    if err ~= nil then
        core.log.error("==== Serverless Request Error: ", err)
        return
    end
    if (res ~= nil) then
        for k, v in pairs(res.headers) do
            core.response.set_header(k, v)
        end
    end
    if res.status == 302 then
        core.response.set_header("Location", res.headers.location)
        core.response.exit(302)
        return
    end

Environment

  • APISIX Go Plugin Runner's version:
  • APISIX version:
  • Go version:
  • OS (cmd: uname -a):
@spacewander
Copy link
Member

  1. you can get/set the header via Request.Header, see https://pkg.go.dev/github.com/apache/apisix-go-plugin-runner@v0.2.0/pkg/http#Header
  2. you can stop the request with headers, see
    w.Header().Add("X-Resp-A6-Runner", "Go")
  3. currently, there is no way to set response header without stopping the request (the core.response.set_header(k, v) in your example). Maybe you can open an issue to track it?

@GhangZh
Copy link
Author

GhangZh commented Dec 10, 2021

  1. you can get/set the header via Request.Header, see https://pkg.go.dev/github.com/apache/apisix-go-plugin-runner@v0.2.0/pkg/http#Header
  2. you can stop the request with headers, see
    w.Header().Add("X-Resp-A6-Runner", "Go")
  3. currently, there is no way to set response header without stopping the request (the core.response.set_header(k, v) in your example). Maybe you can open an issue to track it?

I want to proxy all the responses. Is there any way to do that?

@GhangZh
Copy link
Author

GhangZh commented Dec 13, 2021

I wrote a demo, but I found that the response body is empty ,For example, if I add this plugin to luacode.com, and I request a.com, the plugin will request b.com and do the processing, now the processing is successful but there is no response content from luacode.com.

package plugins

import (
	"encoding/json"
	"fmt"
	pkgHTTP "github.com/apache/apisix-go-plugin-runner/pkg/http"
	"github.com/apache/apisix-go-plugin-runner/pkg/log"
	"github.com/apache/apisix-go-plugin-runner/pkg/plugin"
	"github.com/sirupsen/logrus"
	"net/http"
	"time"
)

func init() {
	err := plugin.RegisterPlugin(&ForwardAuth{})
	if err != nil {
		log.Fatalf("failed to register plugin ForwardAuth: %s", err)
	}
}

// ForwardAuth is a demo to show how to return data directly instead of proxying
// it to the upstream.
type ForwardAuth struct {
}

type ForwardAuthConf struct {
	Body string `json:"body"`
}

func (p *ForwardAuth) Name() string {
	return "forward-auth"
}

func (p *ForwardAuth) ParseConf(in []byte) (interface{}, error) {
	conf := ForwardAuthConf{}
	err := json.Unmarshal(in, &conf)
	return conf, err
}
func (p *ForwardAuth) Filter(conf interface{}, w http.ResponseWriter, r pkgHTTP.Request) {
	req, err := http.NewRequest("GET", "http://b.com", nil)
	if err != nil {
		logrus.Errorf("send request failed err:%v", err)
		return
	}
	//req.Header.Set("Cookie", r.Header().Get("Cookie"))
	client := http.Client{
		Timeout: 5 * time.Second,
	}
	resp, err := client.Do(req)
	if err != nil {
		logrus.Errorf("get response failed err:%v", err)
		return
	}
	if resp == nil {
		logrus.Errorf("response is nil")
		return
	}
	defer resp.Body.Close()

	if len(resp.Header) > 0 {
		for k, v := range resp.Header {
			if v != nil {
				w.Header().Set(k, v[0])
			}
		}
	}

	w.Header().Add("X-Resp-A6-Runner", "Go")
	return

}

not use plugin
image
after use pulgin
image

@GhangZh
Copy link
Author

GhangZh commented Dec 14, 2021

1.I found that after I use core.response.set_header(k, v) then the response body of the service I requested was empty.
2.What do you mean by this? @spacewander

  1. you can stop the request with headers, see
    w.Header().Add("X-Resp-A6-Runner", "Go")
  2. currently, there is no way to set response header without stopping the request (the core.response.set_header(k, v) in your example). Maybe you can open an issue to track it?

@spacewander
Copy link
Member

Currently, setting response data will mean stopping the current process and returning immediately without proxying the request to upstream.

@GhangZh
Copy link
Author

GhangZh commented Dec 14, 2021

Currently, setting response data will mean stopping the current process and returning immediately without proxying the request to upstream.

How should I change to proxy the request to upstream ?
I've tried both severless-plugin and go-plugin-runner plugins to support forward-auth,But none of these are currently met, And not having this plugin would cause all our services not being accessible

@shuaijinchao
Copy link
Member

@GhangZh try w.Header().Add("X-Resp-A6-Runner", "Go") change to r.Header().Set("X-Resp-A6-Runner", "Go")

@GhangZh
Copy link
Author

GhangZh commented Dec 14, 2021

Thanks, change to r.Header().Set("X-Resp-A6-Runner", "Go") solved my problem

@GhangZh GhangZh closed this as completed Dec 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants