Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
energye
energy
提交
d096eab3
energy
项目概览
energye
/
energy
通知
13
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
energy
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d096eab3
编写于
8月 25, 2023
作者:
yanghye
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加内置资源代理 支持HttpServer和本地与内置方式加载资源.
上级
3d0af1a8
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
277 addition
and
52 deletion
+277
-52
cef/local-load-resource.go
cef/local-load-resource.go
+66
-52
cef/local-load-xhr-proxy.go
cef/local-load-xhr-proxy.go
+167
-0
cef/types-post-data-element.go
cef/types-post-data-element.go
+7
-0
cef/types-post-data.go
cef/types-post-data.go
+7
-0
cef/types-string-multi-map.go
cef/types-string-multi-map.go
+7
-0
cef/types.go
cef/types.go
+3
-0
consts/consts.go
consts/consts.go
+20
-0
未找到文件。
cef/local-load-resource.go
浏览文件 @
d096eab3
...
...
@@ -12,12 +12,13 @@ package cef
import
(
"embed"
"github.com/energye/energy/v2/consts"
.
"github.com/energye/energy/v2/consts"
"github.com/energye/energy/v2/logger"
"io/ioutil"
"net/url"
"os"
"path/filepath"
"strings"
"unsafe"
)
...
...
@@ -25,15 +26,6 @@ const (
localDomain
=
"energy"
// default energy
)
// LocalCustomerScheme 本地资源加载自定义固定协议
// file, fs
type
LocalCustomerScheme
string
const
(
LocalCSFile
LocalCustomerScheme
=
"file"
// 本地目录 file://energy/index.html
LocalCSFS
LocalCustomerScheme
=
"fs"
// 内置 fs://energy/index.html
)
// 本地加载资源
var
localLoadRes
*
LocalLoadResource
...
...
@@ -63,14 +55,8 @@ type LocalLoadConfig struct {
Scheme
LocalCustomerScheme
// 自定义协议, file: 本地磁盘目录加载, fs: 内置到执行程序加载
FileRoot
string
// 资源根目录, scheme是file时为本地目录(默认当前程序执行目录) scheme是fs时为资源文件夹名
FS
*
embed
.
FS
// 内置加载资源对象, scheme是fs时必须填入
Proxy
XHRProxy
// 数据请求代理, 在浏览器发送xhr请求时可通过该配置转发
}
// XHRProxy
// 数据请求代理
type
XHRProxy
struct
{
IP
string
Port
int
Proxy
IXHRProxy
// 数据请求代理, 在浏览器发送xhr请求时可通过该配置转发, 你可可以实现该 IXHRProxy 接口自己实现
Home
string
// 默认首页: /index.html, /home.html, /other.html, default: /index.html
}
// 请求和响应资源
...
...
@@ -78,12 +64,13 @@ type source struct {
path
string
// 资源路径, 根据请求URL地址
fileExt
string
// 资源扩展名, 用于拿到 MimeType
bytes
[]
byte
// 资源数据
err
error
// 读取资源
的错误
err
error
// 获取资源时
的错误
readPosition
int
// 读取资源时的地址偏移
status
int32
// 响应状态码
statusText
string
// 响应状态文本
mimeType
string
// 响应的资源 MimeType
resourceType
consts
.
TCefResourceType
// 资源类型
header
map
[
string
][]
string
// 响应头
resourceType
TCefResourceType
// 资源类型
}
// 初始化本地加载配置对象
...
...
@@ -103,6 +90,18 @@ func localLoadResourceInit(config LocalLoadConfig) {
if
config
.
Scheme
!=
LocalCSFile
&&
config
.
Scheme
!=
LocalCSFS
{
config
.
Scheme
=
LocalCSFS
}
if
config
.
Home
==
""
{
config
.
Home
=
"/index.html"
}
else
if
config
.
Home
[
0
]
!=
'/'
{
config
.
Home
=
"/"
+
config
.
Home
}
//if config.Proxy != nil {
// if proxy, ok := config.Proxy.(*XHRProxy); ok {
// if proxy.Scheme == LpsTcp {
// proxy.tcpListen()
// }
// }
//}
localLoadRes
.
LocalLoadConfig
=
config
}
...
...
@@ -138,12 +137,13 @@ func (m *LocalLoadResource) ext(path string) string {
// 使用本地资源加载时,先验证每个请求的合法性
// 所支持的scheme, domain
// URL格式, fs://energy/index.html, 文件路径必须包含扩展名
// 这里返回false后不会创建资源处理对象
func
(
m
*
LocalLoadResource
)
checkRequest
(
request
*
ICefRequest
)
(
*
source
,
bool
)
{
rt
:=
request
.
ResourceType
()
// 根据资源类型跳过哪些资源不被本地加载
// TODO: rt_media 类型应该在此去除
switch
rt
{
case
consts
.
RT_XHR
,
consts
.
RT_MEDIA
,
consts
.
RT_PING
,
consts
.
RT_CSP_REPORT
,
consts
.
RT_PLUGIN_RESOURCE
:
case
RT_MEDIA
,
RT_PING
,
RT_CSP_REPORT
,
RT_PLUGIN_RESOURCE
:
return
nil
,
false
}
reqUrl
,
err
:=
url
.
Parse
(
request
.
URL
())
...
...
@@ -161,8 +161,11 @@ func (m *LocalLoadResource) checkRequest(request *ICefRequest) (*source, bool) {
return
nil
,
false
}
path
:=
reqUrl
.
Path
if
path
==
""
||
path
==
"/"
{
path
=
m
.
Home
}
ext
:=
m
.
ext
(
path
)
if
ext
==
""
{
if
ext
==
""
&&
rt
!=
RT_XHR
{
logger
.
Error
(
"LocalLoadResource Incorrect resources should: file.[ext](MimeType)"
)
return
nil
,
false
}
...
...
@@ -179,70 +182,81 @@ func (m *LocalLoadResource) checkRequest(request *ICefRequest) (*source, bool) {
return
&
source
{
path
:
path
,
fileExt
:
ext
,
mimeType
:
m
.
getMimeType
(
ext
),
resourceType
:
rt
},
true
}
// 读取
文件
// 读取
本地或内置资源
func
(
m
*
source
)
readFile
()
bool
{
// 必须设置文件根目录, scheme是file时, fileRoot为本地文件目录, scheme是fs时, fileRoot为fs的目录名
if
localLoadRes
.
FileRoot
!=
""
{
if
localLoadRes
.
Scheme
==
LocalCSFile
{
m
.
bytes
,
m
.
err
=
ioutil
.
ReadFile
(
filepath
.
Join
(
localLoadRes
.
FileRoot
,
m
.
path
))
// 在本地读取
data
,
err
:=
ioutil
.
ReadFile
(
filepath
.
Join
(
localLoadRes
.
FileRoot
,
m
.
path
))
if
err
==
nil
{
m
.
bytes
=
data
if
m
.
err
==
nil
{
return
true
}
logger
.
Error
(
"ReadFile:"
,
err
.
Error
())
logger
.
Error
(
"ReadFile:"
,
m
.
err
.
Error
())
}
else
if
localLoadRes
.
Scheme
==
LocalCSFS
&&
localLoadRes
.
FS
!=
nil
{
//在fs读取
data
,
err
:=
localLoadRes
.
FS
.
ReadFile
(
localLoadRes
.
FileRoot
+
m
.
path
)
if
err
==
nil
{
m
.
bytes
=
data
m
.
bytes
,
m
.
err
=
localLoadRes
.
FS
.
ReadFile
(
localLoadRes
.
FileRoot
+
m
.
path
)
if
m
.
err
==
nil
{
return
true
}
logger
.
Error
(
"ReadFile:"
,
err
.
Error
())
logger
.
Error
(
"ReadFile:"
,
m
.
err
.
Error
())
}
}
//失败时,返回404,文件不存在
return
false
}
// 打开资源
//
checkRequest = true,
打开资源
func
(
m
*
source
)
open
(
request
*
ICefRequest
,
callback
*
ICefCallback
)
(
handleRequest
,
result
bool
)
{
m
.
readPosition
=
0
// 当前资源的响应设置默认值
m
.
status
=
404
m
.
statusText
=
"Not Found"
m
.
err
=
nil
m
.
header
=
nil
// xhr 请求, 需要通过代理转发出去
if
m
.
resourceType
==
RT_XHR
&&
localLoadRes
.
Proxy
!=
nil
{
if
result
,
err
:=
localLoadRes
.
Proxy
.
Send
(
request
);
err
==
nil
{
m
.
bytes
,
m
.
err
=
result
.
Data
,
err
m
.
status
=
result
.
StatusCode
m
.
header
=
result
.
Header
return
true
,
true
}
}
else
{
// 如果开启缓存,直接在缓存取
if
localLoadRes
.
EnableCache
{
if
m
.
bytes
==
nil
{
if
!
m
.
readFile
()
{
return
true
,
true
}
m
.
readFile
()
}
}
else
{
if
!
m
.
readFile
()
{
return
true
,
true
m
.
readFile
()
}
}
if
m
.
resourceType
==
consts
.
RT_MEDIA
{
m
.
status
=
206
}
else
{
if
m
.
err
==
nil
{
m
.
status
=
200
m
.
statusText
=
"OK"
}
else
{
m
.
statusText
=
m
.
err
.
Error
()
}
callback
.
Cont
()
return
true
,
true
}
// 设置响应信息
//
checkRequest = true,
设置响应信息
func
(
m
*
source
)
response
(
response
*
ICefResponse
)
(
responseLength
int64
,
redirectUrl
string
)
{
response
.
SetStatus
(
m
.
status
)
response
.
SetStatusText
(
m
.
statusText
)
response
.
SetMimeType
(
m
.
mimeType
)
responseLength
=
int64
(
len
(
m
.
bytes
))
if
m
.
header
!=
nil
{
for
key
,
value
:=
range
m
.
header
{
response
.
SetHeaderByName
(
key
,
strings
.
Join
(
value
,
","
),
true
)
}
}
return
}
// 读取bytes, 返回到dataOut
//
checkRequest = true,
读取bytes, 返回到dataOut
func
(
m
*
source
)
read
(
dataOut
uintptr
,
bytesToRead
int32
,
callback
*
ICefResourceReadCallback
)
(
bytesRead
int32
,
result
bool
)
{
if
m
.
bytes
!=
nil
&&
len
(
m
.
bytes
)
>
0
{
var
i
int32
=
0
// 默认 0
...
...
cef/local-load-xhr-proxy.go
0 → 100644
浏览文件 @
d096eab3
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
//
//----------------------------------------
package
cef
import
(
"bytes"
"errors"
"fmt"
.
"github.com/energye/energy/v2/consts"
"github.com/energye/energy/v2/logger"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strconv"
)
var
jar
,
_
=
cookiejar
.
New
(
nil
)
type
IXHRProxy
interface
{
Send
(
request
*
ICefRequest
)
(
*
XHRProxyResponse
,
error
)
}
// XHRProxy
// 数据请求代理
type
XHRProxy
struct
{
Scheme
LocalProxyScheme
// http/https/tcp default: http
IP
string
// default localhost
Port
int
// default 80
SSLCert
string
// /to/path/cert.pem
SSLKey
string
// /to/path/key.pem
}
// XHRProxyResponse
type
XHRProxyResponse
struct
{
Data
[]
byte
DataSize
int
StatusCode
int32
Header
map
[
string
][]
string
}
func
(
m
*
XHRProxy
)
Send
(
request
*
ICefRequest
)
(
*
XHRProxyResponse
,
error
)
{
if
m
.
Scheme
==
LpsHttp
{
return
m
.
sendHttp
(
request
)
}
else
if
m
.
Scheme
==
LpsHttps
{
return
m
.
sendHttps
(
request
)
}
else
if
m
.
Scheme
==
LpsTcp
{
return
m
.
sendTcp
(
request
)
}
return
nil
,
errors
.
New
(
"incorrect scheme"
)
}
func
(
m
*
XHRProxy
)
sendHttp
(
request
*
ICefRequest
)
(
*
XHRProxyResponse
,
error
)
{
reqUrl
,
err
:=
url
.
Parse
(
request
.
URL
())
if
err
!=
nil
{
return
nil
,
err
}
targetUrl
:=
new
(
bytes
.
Buffer
)
targetUrl
.
WriteString
(
"http"
)
targetUrl
.
WriteString
(
"://"
)
targetUrl
.
WriteString
(
m
.
IP
)
if
m
.
Port
>
0
{
targetUrl
.
WriteString
(
strconv
.
Itoa
(
m
.
Port
))
}
targetUrl
.
WriteString
(
reqUrl
.
Path
)
targetUrl
.
WriteString
(
reqUrl
.
RawQuery
)
// 读取请求数据
requestData
:=
new
(
bytes
.
Buffer
)
postData
:=
request
.
GetPostData
()
if
postData
.
IsValid
()
{
dataCount
:=
int
(
postData
.
GetElementCount
())
elements
:=
postData
.
GetElements
()
for
i
:=
0
;
i
<
dataCount
;
i
++
{
element
:=
elements
.
Get
(
uint32
(
i
))
fmt
.
Println
(
"element-type:"
,
element
.
GetType
())
switch
element
.
GetType
()
{
case
PDE_TYPE_EMPTY
:
case
PDE_TYPE_BYTES
:
if
byt
,
c
:=
element
.
GetBytes
();
c
>
0
{
requestData
.
Write
(
byt
)
}
case
PDE_TYPE_FILE
:
if
f
:=
element
.
GetFile
();
f
!=
""
{
if
byt
,
err
:=
ioutil
.
ReadFile
(
f
);
err
==
nil
{
requestData
.
Write
(
byt
)
}
}
}
element
.
Free
()
}
postData
.
Free
()
}
logger
.
Debug
(
"XHRProxy TargetURL:"
,
targetUrl
.
String
(),
"dataLength:"
,
len
(
requestData
.
Bytes
()))
httpRequest
,
err
:=
http
.
NewRequest
(
request
.
Method
(),
targetUrl
.
String
(),
requestData
)
if
err
!=
nil
{
return
nil
,
err
}
// 设置请求头
header
:=
request
.
GetHeaderMap
()
if
header
.
IsValid
()
{
size
:=
header
.
GetSize
()
for
i
:=
0
;
i
<
int
(
size
);
i
++
{
key
:=
header
.
GetKey
(
uint32
(
i
))
//value := header.GetValue(uint32(i))
//httpRequest.Header.Add(key, value)
c
:=
header
.
FindCount
(
key
)
for
j
:=
0
;
j
<
int
(
c
);
j
++
{
value
:=
header
.
GetEnumerate
(
key
,
uint32
(
j
))
httpRequest
.
Header
.
Add
(
key
,
value
)
fmt
.
Println
(
"XHRProxy header:"
,
key
,
"="
,
value
)
}
}
header
.
Free
()
}
// 创建 client
cli
:=
&
http
.
Client
{
Jar
:
jar
,
}
httpResponse
,
err
:=
cli
.
Do
(
httpRequest
)
if
err
!=
nil
{
return
nil
,
err
}
defer
httpResponse
.
Body
.
Close
()
// 读取响应头
responseHeader
:=
make
(
map
[
string
][]
string
)
for
k
,
v
:=
range
httpResponse
.
Header
{
for
_
,
vs
:=
range
v
{
if
header
,
ok
:=
responseHeader
[
k
];
ok
{
responseHeader
[
k
]
=
append
(
header
,
vs
)
}
else
{
responseHeader
[
k
]
=
[]
string
{
vs
}
}
}
}
// 读取响应数据
buf
:=
new
(
bytes
.
Buffer
)
c
,
err
:=
buf
.
ReadFrom
(
httpResponse
.
Body
)
result
:=
&
XHRProxyResponse
{
Data
:
buf
.
Bytes
(),
DataSize
:
int
(
c
),
StatusCode
:
int32
(
httpResponse
.
StatusCode
),
Header
:
responseHeader
,
}
return
result
,
nil
}
func
(
m
*
XHRProxy
)
sendHttps
(
request
*
ICefRequest
)
(
*
XHRProxyResponse
,
error
)
{
return
nil
,
errors
.
New
(
"https unrealized"
)
}
func
(
m
*
XHRProxy
)
tcpListen
()
{
}
func
(
m
*
XHRProxy
)
sendTcp
(
request
*
ICefRequest
)
(
*
XHRProxyResponse
,
error
)
{
return
nil
,
errors
.
New
(
"tcp unrealized"
)
}
cef/types-post-data-element.go
浏览文件 @
d096eab3
...
...
@@ -53,6 +53,13 @@ func (m *ICefPostDataElement) IsValid() bool {
return
true
}
func
(
m
*
ICefPostDataElement
)
Free
()
{
if
m
.
instance
!=
nil
{
m
.
base
.
Free
(
m
.
Instance
())
m
.
instance
=
nil
}
}
func
(
m
*
ICefPostDataElement
)
IsReadOnly
()
bool
{
if
!
m
.
IsValid
()
{
return
false
...
...
cef/types-post-data.go
浏览文件 @
d096eab3
...
...
@@ -51,6 +51,13 @@ func (m *ICefPostData) IsValid() bool {
return
true
}
func
(
m
*
ICefPostData
)
Free
()
{
if
m
.
instance
!=
nil
{
m
.
base
.
Free
(
m
.
Instance
())
m
.
instance
=
nil
}
}
func
(
m
*
ICefPostData
)
IsReadOnly
()
bool
{
if
!
m
.
IsValid
()
{
return
false
...
...
cef/types-string-multi-map.go
浏览文件 @
d096eab3
...
...
@@ -96,3 +96,10 @@ func (m *ICefStringMultiMap) Append(key, value string) bool {
func
(
m
*
ICefStringMultiMap
)
Clear
()
{
imports
.
Proc
(
def
.
StringMultimap_Clear
)
.
Call
(
m
.
Instance
())
}
func
(
m
*
ICefStringMultiMap
)
Free
()
{
if
m
.
instance
!=
nil
{
m
.
base
.
Free
(
m
.
Instance
())
m
.
instance
=
nil
}
}
cef/types.go
浏览文件 @
d096eab3
...
...
@@ -465,16 +465,19 @@ type ICefMenuModelDelegate struct {
// ICefStringMultiMap 实例
type
ICefStringMultiMap
struct
{
base
TCefBaseRefCounted
instance
unsafe
.
Pointer
}
// ICefPostData
type
ICefPostData
struct
{
base
TCefBaseRefCounted
instance
unsafe
.
Pointer
}
// ICefPostDataElement
type
ICefPostDataElement
struct
{
base
TCefBaseRefCounted
instance
unsafe
.
Pointer
}
...
...
consts/consts.go
浏览文件 @
d096eab3
...
...
@@ -1591,3 +1591,23 @@ const (
UitGtk3
// linux
UitCocoa
// macos
)
// LocalCustomerScheme 本地资源加载自定义固定协议
// file, fs
type
LocalCustomerScheme
string
const
(
LocalCSFile
LocalCustomerScheme
=
"file"
// 本地目录 file://energy/index.html
LocalCSFS
LocalCustomerScheme
=
"fs"
// 内置 fs://energy/index.html
)
// LocalProxyScheme
// 本地加载资源,在浏览器发起xhr请求时的代理协议
// http, https, tcp
type
LocalProxyScheme
int
const
(
LpsHttp
LocalProxyScheme
=
iota
// http
LpsHttps
// https
LpsTcp
// tcp
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录