summary refs log tree commit diff
diff options
context:
space:
mode:
authorTed Unangst <tedu@tedunangst.com>2022-03-06 01:13:11 -0500
committerTed Unangst <tedu@tedunangst.com>2022-03-06 01:13:11 -0500
commit2163fff7274004d098815aafc9084b04215f1af7 (patch)
treeee3f120fb8e7b1299d609863b461af674870ab06
parent2b911d883a2afddd3a208ad85b1187d64363c202 (diff)
almost in place
-rw-r--r--filter.go5
-rw-r--r--interpreter.go94
-rw-r--r--miniwebproxy.go3
3 files changed, 88 insertions, 14 deletions
diff --git a/filter.go b/filter.go
index 4dc90a3..517237a 100644
--- a/filter.go
+++ b/filter.go
@@ -362,7 +362,9 @@ func dofiltering(interp *interpreter, under io.WriteCloser, w flushWriter, reade
 		return
 	}
 
-	interp.FilterHTML(w, req, root)
+	if !interp.FilterHTML(w, req, root) {
+		html.Render(w, root)
+	}
 }
 
 func filteronefile(fname string) {
@@ -380,6 +382,7 @@ func filteronefile(fname string) {
 	}
 	resp.Body = fd
 	interp := getinterpreter()
+	interp.ShouldIntercept(req.URL.Hostname())
 	filter(interp, os.Stdout, &resp, &req)
 	fmt.Printf("\n")
 }
diff --git a/interpreter.go b/interpreter.go
index 8b45e02..825f3b3 100644
--- a/interpreter.go
+++ b/interpreter.go
@@ -2,38 +2,110 @@ package main
 
 import (
 	"io"
+	"log"
 	"net/http"
+	"os"
+	"runtime"
+	"reflect"
 
+	"github.com/traefik/yaegi/stdlib"
 	"github.com/traefik/yaegi/interp"
 	"golang.org/x/net/html"
 )
 
 type interpreter struct {
-	interp *interp.Interpreter
-}
-
-func (interp *interpreter) NewConnection(r *http.Request) {
+	interp          *interp.Interpreter
+	newrequest      func(*http.Request)
+	shouldintercept func(string) bool
+	prefilter       func(*http.Request)
+	filterresponse  func(io.Writer, *http.Request, *http.Response) bool
+	filterhtml      func(io.Writer, *http.Request, *html.Node) bool
 }
 
 func (interp *interpreter) ShouldIntercept(hostname string) bool {
-	return true
+	return interp.shouldintercept(hostname)
 }
 
 func (interp *interpreter) Prefilter(req *http.Request) {
+	interp.prefilter(req)
 }
 
-func (interp *interpreter) FilterResponse(w io.Writer, req *http.Request, servresp *http.Response) bool {
-	return false
+func (interp *interpreter) FilterResponse(w io.Writer, req *http.Request, resp *http.Response) bool {
+	return interp.filterresponse(w, req, resp)
 }
 
-func (interp *interpreter) FilterHTML(w io.Writer, req *http.Request, root *html.Node) {
-	html.Render(w, root)
+func (interp *interpreter) FilterHTML(w io.Writer, req *http.Request, root *html.Node) bool {
+	return interp.filterhtml(w, req, root)
+}
+
+func defNewRequest(*http.Request) {
+}
+func defShouldIntercept(string) bool {
+	return true
+}
+func defPrefilter(*http.Request) {
+}
+func defFilterResponse(io.Writer, *http.Request, *http.Response) bool {
+	return false
+}
+func defFilterHTML(io.Writer, *http.Request, *html.Node) bool {
+	return false
 }
 
 func getinterpreter() *interpreter {
+	var err error
 	i := new(interpreter)
-	i.interp = interp.New(interp.Options{})
-	return nil
+	i.interp = interp.New(interp.Options{GoPath: runtime.GOROOT()})
+	i.interp.Use(stdlib.Symbols)
+	exports := make(interp.Exports)
+	exports["html/html"] = map[string]reflect.Value{
+		"Node": reflect.ValueOf((*html.Node)(nil)),
+	}
+	i.interp.Use(exports)
+	i.interp.ImportUsed()
+	rawsrc, err := os.ReadFile("scripts/script.go")
+	if err != nil {
+		log.Panicf("err load src: %s", err)
+	}
+	src := string(rawsrc)
+	_, err = i.interp.Eval(src)
+	if err != nil {
+		log.Panicf("err eval src: %s", err)
+	}
+
+	si, err := i.interp.Eval("filt.ShouldIntercept")
+	if err != nil {
+		log.Printf("err eval shouldintercept: %s", err)
+		i.shouldintercept = defShouldIntercept
+	} else {
+		i.shouldintercept = si.Interface().(func(string) bool)
+	}
+
+	pf, err := i.interp.Eval("filt.Prefilter")
+	if err != nil {
+		log.Printf("err eval prefilter: %s", err)
+		i.prefilter = defPrefilter
+	} else {
+		i.prefilter = pf.Interface().(func(*http.Request))
+	}
+
+	fr, err := i.interp.Eval("filt.FilterResponse")
+	if err != nil {
+		log.Printf("err eval filterresponse: %s", err)
+		i.filterresponse = defFilterResponse
+	} else {
+		i.filterresponse = fr.Interface().(func(io.Writer, *http.Request, *http.Response) bool)
+	}
+
+	fh, err := i.interp.Eval("filt.FilterHTML")
+	if err != nil {
+		log.Printf("err eval filterhtml: %s", err)
+		i.filterhtml = defFilterHTML
+	} else {
+		i.filterhtml = fh.Interface().(func(io.Writer, *http.Request, *html.Node) bool)
+	}
+
+	return i
 }
 
 func putinterpreter(interp *interpreter) {
diff --git a/miniwebproxy.go b/miniwebproxy.go
index d4ee7a5..4adbd65 100644
--- a/miniwebproxy.go
+++ b/miniwebproxy.go
@@ -111,7 +111,6 @@ func proxyreq(w http.ResponseWriter, r *http.Request) {
 
 	interp := getinterpreter()
 	defer finishinterpreter(interp)
-	interp.NewConnection(r)
 	if !interp.ShouldIntercept(r.URL.Hostname()) {
 		resp.Write(clientconn)
 		return
@@ -271,7 +270,6 @@ func (pxr *Proxer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	interp := getinterpreter()
 	defer finishinterpreter(interp)
-	interp.NewConnection(r)
 	if !interp.ShouldIntercept(desthost) {
 		serverconn, err := connect(ctx, dest, "")
 		if err != nil {
@@ -364,6 +362,7 @@ func main() {
 				log.Fatalf("bad argument count. need one filename.")
 			}
 			filteronefile(os.Args[2])
+			return
 		default:
 			log.Fatalf("unknown command")
 		}