mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
perf: precompiling proxy script callbacks
This commit is contained in:
parent
8f22e4a30c
commit
b0ee042229
3 changed files with 88 additions and 62 deletions
|
@ -1,5 +1,10 @@
|
||||||
package session_modules
|
package session_modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
type JSHeader struct {
|
type JSHeader struct {
|
||||||
Name string
|
Name string
|
||||||
Value string
|
Value string
|
||||||
|
@ -14,6 +19,23 @@ type JSRequest struct {
|
||||||
Body string
|
Body string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewJSRequest(req *http.Request) JSRequest {
|
||||||
|
headers := make([]JSHeader, 0)
|
||||||
|
for key, values := range req.Header {
|
||||||
|
for _, value := range values {
|
||||||
|
headers = append(headers, JSHeader{key, value})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSRequest{
|
||||||
|
Method: req.Method,
|
||||||
|
Version: fmt.Sprintf("%d.%d", req.ProtoMajor, req.ProtoMinor),
|
||||||
|
Path: req.URL.Path,
|
||||||
|
Hostname: req.Host,
|
||||||
|
Headers: headers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (j *JSRequest) ReadBody() string {
|
func (j *JSRequest) ReadBody() string {
|
||||||
return "TODO: read body"
|
return "TODO: read body"
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,27 @@ type JSResponse struct {
|
||||||
resp *http.Response
|
resp *http.Response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewJSResponse(res *http.Response) *JSResponse {
|
||||||
|
cType := ""
|
||||||
|
headers := ""
|
||||||
|
|
||||||
|
for name, values := range res.Header {
|
||||||
|
for _, value := range values {
|
||||||
|
if name == "Content-Type" {
|
||||||
|
cType = value
|
||||||
|
}
|
||||||
|
headers += name + ": " + value + "\r\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &JSResponse{
|
||||||
|
Status: res.StatusCode,
|
||||||
|
ContentType: cType,
|
||||||
|
Headers: headers,
|
||||||
|
resp: res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (j *JSResponse) Updated() {
|
func (j *JSResponse) Updated() {
|
||||||
j.wasUpdated = true
|
j.wasUpdated = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package session_modules
|
package session_modules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -14,9 +13,11 @@ type ProxyScript struct {
|
||||||
Source string
|
Source string
|
||||||
VM *otto.Otto
|
VM *otto.Otto
|
||||||
|
|
||||||
gil *sync.Mutex
|
gil *sync.Mutex
|
||||||
cbCacheLock *sync.Mutex
|
onRequestScript *otto.Script
|
||||||
cbCache map[string]bool
|
onResponseScript *otto.Script
|
||||||
|
cbCacheLock *sync.Mutex
|
||||||
|
cbCache map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadProxyScript(path string) (err error, s *ProxyScript) {
|
func LoadProxyScript(path string) (err error, s *ProxyScript) {
|
||||||
|
@ -28,22 +29,42 @@ func LoadProxyScript(path string) (err error, s *ProxyScript) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s = &ProxyScript{
|
s = &ProxyScript{
|
||||||
Path: path,
|
Path: path,
|
||||||
Source: string(raw),
|
Source: string(raw),
|
||||||
VM: otto.New(),
|
VM: otto.New(),
|
||||||
gil: &sync.Mutex{},
|
gil: &sync.Mutex{},
|
||||||
cbCacheLock: &sync.Mutex{},
|
onRequestScript: nil,
|
||||||
cbCache: make(map[string]bool),
|
onResponseScript: nil,
|
||||||
|
cbCacheLock: &sync.Mutex{},
|
||||||
|
cbCache: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.VM.Run(s.Source)
|
_, err = s.VM.Run(s.Source)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
if s.hasCallback("onLoad") {
|
return
|
||||||
_, err = s.VM.Run("onLoad()")
|
}
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Error while executing onLoad callback: %s", err)
|
if s.hasCallback("onLoad") {
|
||||||
return err, nil
|
_, err = s.VM.Run("onLoad()")
|
||||||
}
|
if err != nil {
|
||||||
|
log.Errorf("Error while executing onLoad callback: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.hasCallback("onRequest") {
|
||||||
|
s.onRequestScript, err = s.VM.Compile("", "onRequest(req, res)")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error while compiling onRequest callback: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.hasCallback("onResponse") {
|
||||||
|
s.onResponseScript, err = s.VM.Compile("", "onResponse(req, res)")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error while compiling onResponse callback: %s", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,46 +89,8 @@ func (s *ProxyScript) hasCallback(name string) bool {
|
||||||
return has
|
return has
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ProxyScript) reqToJS(req *http.Request) JSRequest {
|
|
||||||
headers := make([]JSHeader, 0)
|
|
||||||
for key, values := range req.Header {
|
|
||||||
for _, value := range values {
|
|
||||||
headers = append(headers, JSHeader{key, value})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSRequest{
|
|
||||||
Method: req.Method,
|
|
||||||
Version: fmt.Sprintf("%d.%d", req.ProtoMajor, req.ProtoMinor),
|
|
||||||
Path: req.URL.Path,
|
|
||||||
Hostname: req.Host,
|
|
||||||
Headers: headers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s ProxyScript) resToJS(res *http.Response) *JSResponse {
|
|
||||||
cType := ""
|
|
||||||
headers := ""
|
|
||||||
|
|
||||||
for name, values := range res.Header {
|
|
||||||
for _, value := range values {
|
|
||||||
if name == "Content-Type" {
|
|
||||||
cType = value
|
|
||||||
}
|
|
||||||
headers += name + ": " + value + "\r\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &JSResponse{
|
|
||||||
Status: res.StatusCode,
|
|
||||||
ContentType: cType,
|
|
||||||
Headers: headers,
|
|
||||||
resp: res,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ProxyScript) doRequestDefines(req *http.Request) (err error, jsres *JSResponse) {
|
func (s *ProxyScript) doRequestDefines(req *http.Request) (err error, jsres *JSResponse) {
|
||||||
jsreq := s.reqToJS(req)
|
jsreq := NewJSRequest(req)
|
||||||
if err = s.VM.Set("req", jsreq); err != nil {
|
if err = s.VM.Set("req", jsreq); err != nil {
|
||||||
log.Errorf("Error while defining request: %s", err)
|
log.Errorf("Error while defining request: %s", err)
|
||||||
return
|
return
|
||||||
|
@ -123,13 +106,13 @@ func (s *ProxyScript) doRequestDefines(req *http.Request) (err error, jsres *JSR
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ProxyScript) doResponseDefines(res *http.Response) (err error, jsres *JSResponse) {
|
func (s *ProxyScript) doResponseDefines(res *http.Response) (err error, jsres *JSResponse) {
|
||||||
jsreq := s.reqToJS(res.Request)
|
jsreq := NewJSRequest(res.Request)
|
||||||
if err = s.VM.Set("req", jsreq); err != nil {
|
if err = s.VM.Set("req", jsreq); err != nil {
|
||||||
log.Errorf("Error while defining request: %s", err)
|
log.Errorf("Error while defining request: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jsres = s.resToJS(res)
|
jsres = NewJSResponse(res)
|
||||||
if err = s.VM.Set("res", jsres); err != nil {
|
if err = s.VM.Set("res", jsres); err != nil {
|
||||||
log.Errorf("Error while defining response: %s", err)
|
log.Errorf("Error while defining response: %s", err)
|
||||||
return
|
return
|
||||||
|
@ -139,7 +122,7 @@ func (s *ProxyScript) doResponseDefines(res *http.Response) (err error, jsres *J
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ProxyScript) OnRequest(req *http.Request) *JSResponse {
|
func (s *ProxyScript) OnRequest(req *http.Request) *JSResponse {
|
||||||
if s.hasCallback("onRequest") {
|
if s.onRequestScript != nil {
|
||||||
s.gil.Lock()
|
s.gil.Lock()
|
||||||
defer s.gil.Unlock()
|
defer s.gil.Unlock()
|
||||||
|
|
||||||
|
@ -149,7 +132,7 @@ func (s *ProxyScript) OnRequest(req *http.Request) *JSResponse {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.VM.Run("onRequest(req, res)")
|
_, err = s.VM.Run(s.onRequestScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while executing onRequest callback: %s", err)
|
log.Errorf("Error while executing onRequest callback: %s", err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -164,7 +147,7 @@ func (s *ProxyScript) OnRequest(req *http.Request) *JSResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ProxyScript) OnResponse(res *http.Response) *JSResponse {
|
func (s *ProxyScript) OnResponse(res *http.Response) *JSResponse {
|
||||||
if s.hasCallback("onResponse") {
|
if s.onResponseScript != nil {
|
||||||
s.gil.Lock()
|
s.gil.Lock()
|
||||||
defer s.gil.Unlock()
|
defer s.gil.Unlock()
|
||||||
|
|
||||||
|
@ -174,7 +157,7 @@ func (s *ProxyScript) OnResponse(res *http.Response) *JSResponse {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.VM.Run("onResponse(req, res)")
|
_, err = s.VM.Run(s.onResponseScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error while executing onRequest callback: %s", err)
|
log.Errorf("Error while executing onRequest callback: %s", err)
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue