Add data URL Link support to subscription

This commit is contained in:
Shelikhoo 2023-11-25 16:53:05 +00:00 committed by Xiaokang Wang (Shelikhoo)
parent c61820c7cd
commit f112667190
10 changed files with 121 additions and 2 deletions

View File

@ -0,0 +1,44 @@
package dataurlsingle
import (
"bytes"
"strings"
"github.com/vincent-petithory/dataurl"
"github.com/v2fly/v2ray-core/v5/app/subscription/containers"
"github.com/v2fly/v2ray-core/v5/common"
)
//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
func newSingularDataURLParser() containers.SubscriptionContainerDocumentParser {
return &parser{}
}
type parser struct{}
func (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {
dataURL, err := dataurl.Decode(bytes.NewReader(rawConfig))
if err != nil {
return nil, newError("unable to decode dataURL").Base(err)
}
if dataURL.MediaType.Type != "application" {
return nil, newError("unsupported media type: ", dataURL.MediaType.Type)
}
if !strings.HasPrefix(dataURL.MediaType.Subtype, "vnd.v2ray.subscription-singular") {
return nil, newError("unsupported media subtype: ", dataURL.MediaType.Subtype)
}
result := &containers.Container{}
result.Kind = "DataURLSingle"
result.Metadata = make(map[string]string)
result.ServerSpecs = append(result.ServerSpecs, containers.UnparsedServerConf{
KindHint: "",
Content: dataURL.Data,
})
return result, nil
}
func init() {
common.Must(containers.RegisterParser("DataURLSingle", newSingularDataURLParser()))
}

View File

@ -0,0 +1,9 @@
package dataurlsingle
import "github.com/v2fly/v2ray-core/v5/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@ -2,6 +2,10 @@ package dataurlfetcher
import (
"context"
"strings"
"github.com/vincent-petithory/dataurl"
"github.com/v2fly/v2ray-core/v5/app/subscription"
"github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher"
"github.com/v2fly/v2ray-core/v5/common"
@ -20,5 +24,15 @@ func init() {
type dataURLFetcher struct{}
func (d *dataURLFetcher) DownloadDocument(ctx context.Context, source *subscription.ImportSource, opts ...documentfetcher.FetcherOptions) ([]byte, error) {
panic("implement me")
dataURL, err := dataurl.DecodeString(source.Url)
if err != nil {
return nil, newError("unable to decode dataURL").Base(err)
}
if dataURL.MediaType.Type != "application" {
return nil, newError("unsupported media type: ", dataURL.MediaType.Type)
}
if !strings.HasPrefix(dataURL.MediaType.Subtype, "vnd.v2ray.subscription") {
return nil, newError("unsupported media subtype: ", dataURL.MediaType.Subtype)
}
return []byte(source.Url), nil
}

View File

@ -0,0 +1,9 @@
package dataurlfetcher
import "github.com/v2fly/v2ray-core/v5/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@ -21,11 +21,16 @@ func (s *SubscriptionManagerImpl) updateSubscription(subscriptionName string) er
trackedSub = trackedSubFound
}
importSource := trackedSub.importSource
docFetcher, err := documentfetcher.GetFetcher("http")
if err != nil {
return newError("failed to get fetcher: ", err)
}
if strings.HasPrefix(importSource.Url, "data:") {
docFetcher, err = documentfetcher.GetFetcher("dataurl")
if err != nil {
return newError("failed to get fetcher: ", err)
}
}
downloadedDocument, err := docFetcher.DownloadDocument(s.ctx, importSource)
if err != nil {

1
go.mod
View File

@ -26,6 +26,7 @@ require (
github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08
github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e
github.com/vincent-petithory/dataurl v1.0.0
github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432
go.starlark.net v0.0.0-20230612165344-9532f5667272
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35

2
go.sum
View File

@ -325,6 +325,8 @@ github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848 h1:p1UzXK6VAutXFFQMnre
github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848/go.mod h1:p80Bv154ZtrGpXMN15slDCqc9UGmfBuUzheDFBYaW/M=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI=
github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 h1:I/ATawgO2RerCq9ACwL0wBB8xNXZdE3J+93MCEHReRs=
github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432/go.mod h1:QN7Go2ftTVfx0aCTh9RXHV8pkpi0FtmbwQw40dy61wQ=

View File

@ -0,0 +1,32 @@
package engineering
import (
"flag"
"io"
"os"
"github.com/vincent-petithory/dataurl"
"github.com/v2fly/v2ray-core/v5/main/commands/base"
)
var cmdEncodeDataURLContentType *string
var cmdEncodeDataURL = &base.Command{
UsageLine: "{{.Exec}} engineering encodeDataURL",
Flag: func() flag.FlagSet {
fs := flag.NewFlagSet("", flag.ExitOnError)
cmdEncodeDataURLContentType = fs.String("type", "application/vnd.v2ray.subscription-singular", "")
return *fs
}(),
Run: func(cmd *base.Command, args []string) {
cmd.Flag.Parse(args)
content, err := io.ReadAll(os.Stdin)
if err != nil {
base.Fatalf("%s", err)
}
dataURL := dataurl.New(content, *cmdEncodeDataURLContentType)
dataURL.WriteTo(os.Stdout)
},
}

View File

@ -12,6 +12,7 @@ var cmdEngineering = &base.Command{
cmdNonNativeLinkExtract,
cmdNonNativeLinkExec,
cmdSubscriptionEntriesExtract,
cmdEncodeDataURL,
},
}

View File

@ -118,10 +118,12 @@ import (
// Subscription Containers: general purpose
_ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/base64urlline"
_ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/dataurlsingle"
_ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray"
_ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray/jsonified"
// Subscription Fetchers
_ "github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher/dataurlfetcher"
_ "github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher/httpfetcher"
// Subscription Entries Converters