-
Notifications
You must be signed in to change notification settings - Fork 218
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
528 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package js_inject | ||
|
||
import ( | ||
"github.com/eolinker/apinto/drivers" | ||
"github.com/eolinker/eosc" | ||
) | ||
|
||
type Config struct { | ||
Variables []Variable `json:"variables" label:"变量列表"` | ||
InjectCode string `json:"inject" label:"注入代码"` | ||
MatchContentType []string `json:"match_content_type" label:"匹配的Content-Type"` | ||
} | ||
|
||
type Variable struct { | ||
Key string `json:"key" label:"变量名"` | ||
Value string `json:"value" label:"变量值"` | ||
} | ||
|
||
func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { | ||
e := &executor{ | ||
WorkerBase: drivers.Worker(id, name), | ||
} | ||
e.reset(conf) | ||
return e, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package js_inject | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/eolinker/apinto/utils" | ||
|
||
"github.com/eolinker/eosc/log" | ||
|
||
"github.com/eolinker/apinto/drivers" | ||
"github.com/eolinker/eosc" | ||
"github.com/eolinker/eosc/eocontext" | ||
http_service "github.com/eolinker/eosc/eocontext/http-context" | ||
) | ||
|
||
var _ eocontext.IFilter = (*executor)(nil) | ||
var _ http_service.HttpFilter = (*executor)(nil) | ||
var _ eosc.IWorker = (*executor)(nil) | ||
|
||
type executor struct { | ||
drivers.WorkerBase | ||
injectCode string | ||
matchContentType []string | ||
} | ||
|
||
func (e *executor) DoFilter(ctx eocontext.EoContext, next eocontext.IChain) (err error) { | ||
return http_service.DoHttpFilter(e, ctx, next) | ||
} | ||
|
||
func (e *executor) DoHttpFilter(ctx http_service.IHttpContext, next eocontext.IChain) (err error) { | ||
if next != nil { | ||
err = next.DoChain(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
contentType := ctx.Response().ContentType() | ||
for _, ct := range e.matchContentType { | ||
if contentType == ct { | ||
body := ctx.Response().GetBody() | ||
res, err := injectJavaScript(string(body), e.injectCode) | ||
if err != nil { | ||
log.Error(err) | ||
return nil | ||
} | ||
ctx.Response().SetBody([]byte(res)) | ||
} | ||
} | ||
return | ||
} | ||
|
||
func (e *executor) Destroy() { | ||
return | ||
} | ||
|
||
func (e *executor) Start() error { | ||
return nil | ||
} | ||
|
||
func (e *executor) Reset(conf interface{}, workers map[eosc.RequireId]eosc.IWorker) error { | ||
return nil | ||
} | ||
|
||
func (e *executor) reset(conf *Config) error { | ||
decodeData, err := utils.B64Decode(conf.InjectCode) | ||
if err != nil { | ||
return err | ||
} | ||
injectCode := string(decodeData) | ||
for _, v := range conf.Variables { | ||
injectCode = strings.Replace(injectCode, fmt.Sprintf("{{%s}}", v.Key), v.Value, -1) | ||
} | ||
e.injectCode = fmt.Sprintf("%s", injectCode) | ||
e.matchContentType = conf.MatchContentType | ||
return nil | ||
} | ||
|
||
func (e *executor) Stop() error { | ||
e.Destroy() | ||
return nil | ||
} | ||
|
||
func (e *executor) CheckSkill(skill string) bool { | ||
return http_service.FilterSkillName == skill | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package js_inject | ||
|
||
import ( | ||
"github.com/eolinker/apinto/drivers" | ||
"github.com/eolinker/eosc" | ||
) | ||
|
||
const ( | ||
Name = "js_inject" | ||
) | ||
|
||
func Register(register eosc.IExtenderDriverRegister) { | ||
register.RegisterExtenderDriver(Name, NewFactory()) | ||
} | ||
|
||
func NewFactory() eosc.IExtenderDriverFactory { | ||
return drivers.NewFactory[Config](Create) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package js_inject | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
|
||
"golang.org/x/net/html" | ||
) | ||
|
||
// injectJavaScript将JavaScript代码插入到HTML中 | ||
func injectJavaScript(originalHTML, jsCode string) (string, error) { | ||
// 解析 HTML 字符串 | ||
doc, err := html.Parse(bytes.NewReader([]byte(originalHTML))) | ||
if err != nil { | ||
return "", fmt.Errorf("parse html error: %w", err) | ||
} | ||
node := findHead(doc) | ||
if node == nil { | ||
// 在每个 HTML 标签后添加 <head> 元素 | ||
addHeadAfterTags(doc) | ||
node = findHead(doc) | ||
} | ||
insertCodeInHead(node, jsCode) | ||
// 将修改后的 HTML 打印出来 | ||
var modifiedHTML bytes.Buffer | ||
if err := html.Render(&modifiedHTML, doc); err != nil { | ||
return "", fmt.Errorf("render html error: %w", err) | ||
} | ||
|
||
return modifiedHTML.String(), nil | ||
|
||
} | ||
|
||
func findHead(node *html.Node) *html.Node { | ||
if node.Type == html.ElementNode && node.Data == "head" { | ||
return node | ||
} | ||
|
||
for child := node.FirstChild; child != nil; child = child.NextSibling { | ||
if found := findHead(child); found != nil { | ||
return found | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func addHeadAfterTags(node *html.Node) { | ||
if node.Type == html.ElementNode { | ||
// 创建 <head> 元素 | ||
newHead := &html.Node{ | ||
Type: html.ElementNode, | ||
DataAtom: 0, | ||
Data: "head", | ||
} | ||
// 在当前元素后插入 <head> 元素 | ||
node.Parent.InsertBefore(newHead, node) | ||
// 递归处理子节点 | ||
for child := node.FirstChild; child != nil; child = child.NextSibling { | ||
addHeadAfterTags(child) | ||
} | ||
} | ||
|
||
// 递归处理下一个兄弟节点 | ||
if node.NextSibling != nil { | ||
addHeadAfterTags(node.NextSibling) | ||
} | ||
} | ||
|
||
func insertCodeInHead(headNode *html.Node, jsCode string) { | ||
// 创建一个新的 <script> 元素(示例代码) | ||
newScript := &html.Node{ | ||
Type: html.ElementNode, | ||
Data: "script", | ||
DataAtom: 0, | ||
} | ||
|
||
// 在 <script> 中插入要添加的代码 | ||
newScript.AppendChild(&html.Node{ | ||
Type: html.TextNode, | ||
Data: jsCode, | ||
}) | ||
|
||
// 将新的 <script> 元素插入到 <head> 的第一个子标签位置 | ||
if headNode.LastChild != nil { | ||
headNode.InsertBefore(newScript, headNode.FirstChild) | ||
} else { | ||
headNode.AppendChild(newScript) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package rsa_filter | ||
|
||
import ( | ||
"github.com/eolinker/apinto/drivers" | ||
"github.com/eolinker/eosc" | ||
) | ||
|
||
type Config struct { | ||
PrivateKey string `json:"private_key" label:"私钥" description:"对请求体进行解密,对响应体进行签名"` | ||
PublicKey string `json:"public_key" label:"公钥" description:"对请求体进行验签,对响应体进行加密"` | ||
RequestSignHeader string `json:"request_sign_header" label:"请求签名头"` | ||
ResponseSignHeader string `json:"response_sign_header" label:"响应签名头"` | ||
Format string `json:"format" label:"密钥格式" enum:"origin,base64"` | ||
} | ||
|
||
func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) { | ||
e := &executor{ | ||
WorkerBase: drivers.Worker(id, name), | ||
} | ||
e.reset(conf) | ||
return e, nil | ||
} |
Oops, something went wrong.