Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Incoming Properties #88

Merged
merged 13 commits into from
Jan 24, 2024
3 changes: 3 additions & 0 deletions _examples/incoming/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build
node_modules
.wrangler
12 changes: 12 additions & 0 deletions _examples/incoming/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: dev
dev:
wrangler dev

.PHONY: build
build:
go run ../../cmd/workers-assets-gen
tinygo build -o ./build/app.wasm -target wasm -no-debug ./...

.PHONY: deploy
deploy:
wrangler deploy
7 changes: 7 additions & 0 deletions _examples/incoming/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/syumai/workers/_examples/hello
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
module github.com/syumai/workers/_examples/hello
module github.com/syumai/workers/_examples/incoming


go 1.21.3

require github.com/syumai/workers v0.0.0

replace github.com/syumai/workers => ../../
2 changes: 2 additions & 0 deletions _examples/incoming/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/syumai/workers v0.1.0 h1:z5QfQR2X+PCKzom7RodpI5J4D5YF7NT7Qwzb9AM9dgY=
github.com/syumai/workers v0.1.0/go.mod h1:alXIDhTyeTwSzh0ZgQ3cb9HQPyyYfIejupE4Z3efr14=
24 changes: 24 additions & 0 deletions _examples/incoming/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"encoding/json"
"fmt"
"net/http"

"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare/incoming"
)

func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
p := incoming.NewProperties(req.Context())

encoder := json.NewEncoder(w)
w.Header().Set("Content-Type", "application/json")
if err := encoder.Encode(p); err != nil {
http.Error(w, fmt.Sprintf("Error encoding JSON: %v", err), http.StatusInternalServerError)
return
}
})
workers.Serve(handler)
}
9 changes: 9 additions & 0 deletions _examples/incoming/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "incoming"
main = "./build/worker.mjs"
compatibility_date = "2022-05-13"
compatibility_flags = [
"streams_enable_constructors"
]

[build]
command = "make build"
4 changes: 2 additions & 2 deletions cloudflare/cron/cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"syscall/js"
"time"

"github.com/syumai/workers/internal/cfcontext"
"github.com/syumai/workers/internal/jsutil"
"github.com/syumai/workers/internal/runtimecontext"
)

// Event represents information about the Cron that invoked this worker.
Expand Down Expand Up @@ -42,7 +42,7 @@ func ScheduleTask(task Task) {
}

func runScheduler(eventObj js.Value, runtimeCtxObj js.Value) error {
ctx := runtimecontext.New(context.Background(), runtimeCtxObj)
ctx := cfcontext.New(context.Background(), runtimeCtxObj, js.Value{})
event, err := toEvent(eventObj)
if err != nil {
return err
Expand Down
159 changes: 159 additions & 0 deletions cloudflare/incoming/property.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package incoming
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incoming seems a part of fetch feature.
Can we merge these package?


import (
"context"
"syscall/js"

"github.com/syumai/workers/internal/cfcontext"
"github.com/syumai/workers/internal/jsutil"
)

type BotManagementJsDetection struct {
Passed bool
}

func NewBotManagementJsDetection(obj js.Value) *BotManagementJsDetection {
if obj.IsUndefined() {
return nil
}
return &BotManagementJsDetection{
Passed: obj.Get("passed").Bool(),
}
}

type BotManagement struct {
CorporateProxy bool
VerifiedBot bool
JsDetection *BotManagementJsDetection
StaticResource bool
Score int
}

func NewBotManagement(obj js.Value) *BotManagement {
if obj.IsUndefined() {
return nil
}
return &BotManagement{
CorporateProxy: obj.Get("corporateProxy").Bool(),
VerifiedBot: obj.Get("verifiedBot").Bool(),
JsDetection: NewBotManagementJsDetection(obj.Get("jsDetection")),
StaticResource: obj.Get("staticResource").Bool(),
Score: obj.Get("score").Int(),
}
}

type TLSClientAuth struct {
CertIssuerDNLegacy string
CertIssuerSKI string
CertSubjectDNRFC2253 string
CertSubjectDNLegacy string
CertFingerprintSHA256 string
CertNotBefore string
CertSKI string
CertSerial string
CertIssuerDN string
CertVerified string
CertNotAfter string
CertSubjectDN string
CertPresented string
CertRevoked string
CertIssuerSerial string
CertIssuerDNRFC2253 string
CertFingerprintSHA1 string
}

func NewTLSClientAuth(obj js.Value) *TLSClientAuth {
if obj.IsUndefined() {
return nil
}
return &TLSClientAuth{
CertIssuerDNLegacy: jsutil.MaybeString(obj.Get("certIssuerDNLegacy")),
CertIssuerSKI: jsutil.MaybeString(obj.Get("certIssuerSKI")),
CertSubjectDNRFC2253: jsutil.MaybeString(obj.Get("certSubjectDNRFC2253")),
CertSubjectDNLegacy: jsutil.MaybeString(obj.Get("certSubjectDNLegacy")),
CertFingerprintSHA256: jsutil.MaybeString(obj.Get("certFingerprintSHA256")),
CertNotBefore: jsutil.MaybeString(obj.Get("certNotBefore")),
CertSKI: jsutil.MaybeString(obj.Get("certSKI")),
CertSerial: jsutil.MaybeString(obj.Get("certSerial")),
CertIssuerDN: jsutil.MaybeString(obj.Get("certIssuerDN")),
CertVerified: jsutil.MaybeString(obj.Get("certVerified")),
CertNotAfter: jsutil.MaybeString(obj.Get("certNotAfter")),
CertSubjectDN: jsutil.MaybeString(obj.Get("certSubjectDN")),
CertPresented: jsutil.MaybeString(obj.Get("certPresented")),
CertRevoked: jsutil.MaybeString(obj.Get("certRevoked")),
CertIssuerSerial: jsutil.MaybeString(obj.Get("certIssuerSerial")),
CertIssuerDNRFC2253: jsutil.MaybeString(obj.Get("certIssuerDNRFC2253")),
CertFingerprintSHA1: jsutil.MaybeString(obj.Get("certFingerprintSHA1")),
}
}

type TLSExportedAuthenticator struct {
ClientFinished string
ClientHandshake string
ServerHandshake string
ServerFinished string
}

func NewTLSExportedAuthenticator(obj js.Value) *TLSExportedAuthenticator {
if obj.IsUndefined() {
return nil
}
return &TLSExportedAuthenticator{
ClientFinished: jsutil.MaybeString(obj.Get("clientFinished")),
ClientHandshake: jsutil.MaybeString(obj.Get("clientHandshake")),
ServerHandshake: jsutil.MaybeString(obj.Get("serverHandshake")),
ServerFinished: jsutil.MaybeString(obj.Get("serverFinished")),
}
}

type Properties struct {
Longitude string
Latitude string
TlsCipher string
Continent string
Asn int
ClientAcceptEncoding string
Country string
TLSClientAuth *TLSClientAuth
TLSExportedAuthenticator *TLSExportedAuthenticator
TlsVersion string
Colo string
Timezone string
City string
VerifiedBotCategory string
// EdgeRequestKeepAliveStatus int
RequestPriority string
HttpProtocol string
Region string
RegionCode string
AsOrganization string
PostalCode string
BotManagement *BotManagement
}

func NewProperties(ctx context.Context) *Properties {
obj := cfcontext.MustExtractIncomingProperty(ctx)
return &Properties{
Longitude: jsutil.MaybeString(obj.Get("longitude")),
Latitude: jsutil.MaybeString(obj.Get("latitude")),
TlsCipher: jsutil.MaybeString(obj.Get("tlsCipher")),
Continent: jsutil.MaybeString(obj.Get("continent")),
Asn: obj.Get("asn").Int(),
ClientAcceptEncoding: jsutil.MaybeString(obj.Get("clientAcceptEncoding")),
Country: jsutil.MaybeString(obj.Get("country")),
TLSClientAuth: NewTLSClientAuth(obj.Get("tlsClientAuth")),
TLSExportedAuthenticator: NewTLSExportedAuthenticator(obj.Get("tlsExportedAuthenticator")),
TlsVersion: obj.Get("tlsVersion").String(),
Colo: obj.Get("colo").String(),
Timezone: obj.Get("timezone").String(),
City: jsutil.MaybeString(obj.Get("city")),
VerifiedBotCategory: jsutil.MaybeString(obj.Get("verifiedBotCategory")),
RequestPriority: jsutil.MaybeString(obj.Get("requestPriority")),
HttpProtocol: obj.Get("httpProtocol").String(),
Region: jsutil.MaybeString(obj.Get("region")),
RegionCode: jsutil.MaybeString(obj.Get("regionCode")),
AsOrganization: obj.Get("asOrganization").String(),
PostalCode: jsutil.MaybeString(obj.Get("postalCode")),
BotManagement: NewBotManagement(obj.Get("botManagement")),
}
}
4 changes: 2 additions & 2 deletions cloudflare/internal/cfruntimecontext/cfruntimecontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"errors"
"syscall/js"

"github.com/syumai/workers/internal/runtimecontext"
"github.com/syumai/workers/internal/cfcontext"
)

/**
Expand Down Expand Up @@ -49,7 +49,7 @@ var ErrValueNotFound = errors.New("execution context value for specified key not
// GetRuntimeContextValue gets value for specified key from RuntimeContext.
// - if the value is undefined, return error.
func GetRuntimeContextValue(ctx context.Context, key string) (js.Value, error) {
runtimeCtxValue := runtimecontext.MustExtract(ctx)
runtimeCtxValue := cfcontext.MustExtractRuntimeContext(ctx)
v := runtimeCtxValue.Get(key)
if v.IsUndefined() {
return js.Value{}, ErrValueNotFound
Expand Down
4 changes: 2 additions & 2 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"net/http"
"syscall/js"

"github.com/syumai/workers/internal/cfcontext"
"github.com/syumai/workers/internal/jshttp"
"github.com/syumai/workers/internal/jsutil"
"github.com/syumai/workers/internal/runtimecontext"
)

var httpHandler http.Handler
Expand Down Expand Up @@ -49,7 +49,7 @@ func handleRequest(reqObj js.Value, runtimeCtxObj js.Value) (js.Value, error) {
if err != nil {
panic(err)
}
ctx := runtimecontext.New(context.Background(), runtimeCtxObj)
ctx := cfcontext.New(context.Background(), runtimeCtxObj, reqObj.Get("cf"))
req = req.WithContext(ctx)
reader, writer := io.Pipe()
w := &jshttp.ResponseWriter{
Expand Down
39 changes: 39 additions & 0 deletions internal/cfcontext/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cfcontext

import (
"context"
"errors"
"syscall/js"
)

type runtimeCtxKey struct{}
type incomingPropertyKey struct{}

func New(ctx context.Context, runtimeCtxObj, incomingPropertyObj js.Value) context.Context {
aki-0421 marked this conversation as resolved.
Show resolved Hide resolved
ctx = context.WithValue(ctx, runtimeCtxKey{}, runtimeCtxObj)
ctx = context.WithValue(ctx, incomingPropertyKey{}, incomingPropertyObj)
return ctx
}

var ErrRuntimeContextNotFound = errors.New("runtime context was not found")
var ErrIncomingPropertyNotFound = errors.New("incoming property was not found")

// MustExtractRuntimeContext extracts runtime context object from context.
// This function panics when runtime context object was not found.
func MustExtractRuntimeContext(ctx context.Context) js.Value {
v, ok := ctx.Value(runtimeCtxKey{}).(js.Value)
if !ok {
panic(ErrRuntimeContextNotFound)
}
return v
}

// MustExtractIncomingProperty extracts incoming property object from context.
// This function panics when incoming property object was not found.
func MustExtractIncomingProperty(ctx context.Context) js.Value {
v, ok := ctx.Value(incomingPropertyKey{}).(js.Value)
if !ok {
panic(ErrIncomingPropertyNotFound)
}
return v
}
25 changes: 0 additions & 25 deletions internal/runtimecontext/context.go

This file was deleted.

Loading