如何使用 proxy.ModifyResponse?
How do I use proxy.ModifyResponse?
我已经实现了最基本的反向代理来提取页面,然后向正文添加一些内容。不幸的是,我尝试添加到 html 没有生效。下面的代码只显示原始页面,但没有 "monkeys" 我在响应前添加。需要什么额外的电话才能让它工作?我最终想用它来替换自定义 css 的 css。
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
"fmt"
"github.com/PuerkitoBio/goquery"
"bytes"
)
type Director func(*http.Request)
func (f Director) Then(g Director) Director {
return func(req *http.Request) {
f(req)
g(req)
}
}
func hostDirector(host string) Director {
return func(req *http.Request) {
req.Host = host
}
}
func UpdateResponse(r *http.Response) error {
doc, err := goquery.NewDocumentFromReader(r.Body)
if err != nil{
//log.New("Research")
log.Fatal("Bad doc %v", err)
return err
}
html, err := goquery.OuterHtml(doc.First())
if err != nil{
log.Fatal("Bad html %v", err)
return err
}
fmt.Printf("Body %v", html)
r.Write(bytes.NewBufferString("monkeys"+html))
return nil
}
func main() {
url, _ := url.Parse("http://cnn.com/")
proxy := httputil.NewSingleHostReverseProxy(url)
d := proxy.Director
// sequence the default director with our host director
proxy.Director = Director(d).Then(hostDirector(url.Hostname()))
proxy.ModifyResponse = UpdateResponse
http.Handle("/", proxy)
log.Fatal(http.ListenAndServe(":9090", nil))
}
您的 ModifyResponse
代码没有修改响应。在您的代码中,您有:
r.Write(bytes.NewBufferString("monkeys"+html))
看来您是在写回复,但不是。 r
属于 *http.Response
,它有一个 Write
方法:
func (r *Response) Write(w io.Writer) error
document 说:
Write writes r to w in the HTTP/1.x server response format, including the status line, headers, body, and optional trailer.
由于 bytes.Buffer
也实现了 io.Writer
,代码编译,但不是写入缓冲区的响应,而是将响应写入缓冲区,这是绝对不需要的。
事实是,http.Response
根本没有提供修改其 Body
的方法。很明显Bodey
是一个io.ReadCloser
。您可以做的是用正文创建一个新的 io.ReadCloser
。请记住更改 Header
中的 Content-Length
字段,否则可能会导致问题。
func UpdateResponse(r *http.Response) error {
b, _ := ioutil.ReadAll(r.Body)
buf := bytes.NewBufferString("Monkey")
buf.Write(b)
r.Body = ioutil.NopCloser(buf)
r.Header["Content-Length"] = []string{fmt.Sprint(buf.Len())}
return nil
}
我已经实现了最基本的反向代理来提取页面,然后向正文添加一些内容。不幸的是,我尝试添加到 html 没有生效。下面的代码只显示原始页面,但没有 "monkeys" 我在响应前添加。需要什么额外的电话才能让它工作?我最终想用它来替换自定义 css 的 css。
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
"fmt"
"github.com/PuerkitoBio/goquery"
"bytes"
)
type Director func(*http.Request)
func (f Director) Then(g Director) Director {
return func(req *http.Request) {
f(req)
g(req)
}
}
func hostDirector(host string) Director {
return func(req *http.Request) {
req.Host = host
}
}
func UpdateResponse(r *http.Response) error {
doc, err := goquery.NewDocumentFromReader(r.Body)
if err != nil{
//log.New("Research")
log.Fatal("Bad doc %v", err)
return err
}
html, err := goquery.OuterHtml(doc.First())
if err != nil{
log.Fatal("Bad html %v", err)
return err
}
fmt.Printf("Body %v", html)
r.Write(bytes.NewBufferString("monkeys"+html))
return nil
}
func main() {
url, _ := url.Parse("http://cnn.com/")
proxy := httputil.NewSingleHostReverseProxy(url)
d := proxy.Director
// sequence the default director with our host director
proxy.Director = Director(d).Then(hostDirector(url.Hostname()))
proxy.ModifyResponse = UpdateResponse
http.Handle("/", proxy)
log.Fatal(http.ListenAndServe(":9090", nil))
}
您的 ModifyResponse
代码没有修改响应。在您的代码中,您有:
r.Write(bytes.NewBufferString("monkeys"+html))
看来您是在写回复,但不是。 r
属于 *http.Response
,它有一个 Write
方法:
func (r *Response) Write(w io.Writer) error
document 说:
Write writes r to w in the HTTP/1.x server response format, including the status line, headers, body, and optional trailer.
由于 bytes.Buffer
也实现了 io.Writer
,代码编译,但不是写入缓冲区的响应,而是将响应写入缓冲区,这是绝对不需要的。
事实是,http.Response
根本没有提供修改其 Body
的方法。很明显Bodey
是一个io.ReadCloser
。您可以做的是用正文创建一个新的 io.ReadCloser
。请记住更改 Header
中的 Content-Length
字段,否则可能会导致问题。
func UpdateResponse(r *http.Response) error {
b, _ := ioutil.ReadAll(r.Body)
buf := bytes.NewBufferString("Monkey")
buf.Write(b)
r.Body = ioutil.NopCloser(buf)
r.Header["Content-Length"] = []string{fmt.Sprint(buf.Len())}
return nil
}