mirror of
https://github.com/syumai/workers.git
synced 2025-03-10 17:29:11 +00:00
implement put and delete of R2
This commit is contained in:
parent
f0149a86de
commit
47a5378664
@ -41,8 +41,8 @@ func handler(w http.ResponseWriter, req *http.Request) {
|
||||
w.Header().Set("Cache-Control", "public, max-age=14400")
|
||||
w.Header().Set("ETag", fmt.Sprintf("W/%s", imgObj.HTTPETag))
|
||||
contentType := "application/octet-stream"
|
||||
if imgObj.HTTPMetadata.ContentType != nil {
|
||||
contentType = *imgObj.HTTPMetadata.ContentType
|
||||
if imgObj.HTTPMetadata.ContentType != "" {
|
||||
contentType = imgObj.HTTPMetadata.ContentType
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
io.Copy(w, imgObj.Body)
|
||||
|
25
jsutil.go
25
jsutil.go
@ -18,6 +18,8 @@ var (
|
||||
errorClass = global.Get("Error")
|
||||
readableStreamClass = global.Get("ReadableStream")
|
||||
stringClass = global.Get("String")
|
||||
dateClass = global.Get("Date")
|
||||
numberClass = global.Get("Number")
|
||||
)
|
||||
|
||||
func newObject() js.Value {
|
||||
@ -77,24 +79,19 @@ func strRecordToMap(v js.Value) map[string]string {
|
||||
}
|
||||
|
||||
// maybeString returns string value of given JavaScript value or returns nil if the value is undefined.
|
||||
func maybeString(v js.Value) *string {
|
||||
func maybeString(v js.Value) string {
|
||||
if v.IsUndefined() {
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
s := v.String()
|
||||
return &s
|
||||
return v.String()
|
||||
}
|
||||
|
||||
// maybeDate returns time.Time value of given JavaScript Date value or returns nil if the value is undefined.
|
||||
func maybeDate(v js.Value) (*time.Time, error) {
|
||||
func maybeDate(v js.Value) (time.Time, error) {
|
||||
if v.IsUndefined() {
|
||||
return nil, nil
|
||||
return time.Time{}, nil
|
||||
}
|
||||
d, err := dateToTime(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &d, nil
|
||||
return dateToTime(v)
|
||||
}
|
||||
|
||||
// dateToTime converts JavaScript side's Data object into time.Time.
|
||||
@ -106,3 +103,9 @@ func dateToTime(v js.Value) (time.Time, error) {
|
||||
}
|
||||
return time.UnixMilli(milli), nil
|
||||
}
|
||||
|
||||
// timeToDate converts Go side's time.Time into Date object.
|
||||
func timeToDate(t time.Time) js.Value {
|
||||
milliStr := strconv.FormatInt(t.UnixMilli(), 10)
|
||||
return dateClass.New(numberClass.Call(milliStr))
|
||||
}
|
||||
|
53
r2bucket.go
53
r2bucket.go
@ -12,7 +12,7 @@ import (
|
||||
type R2Bucket interface {
|
||||
Head(key string) (*R2Object, error)
|
||||
Get(key string) (*R2Object, error)
|
||||
Put(key string, value io.Reader) error
|
||||
Put(key string, value io.ReadCloser, opts *R2PutOptions) (*R2Object, error)
|
||||
Delete(key string) error
|
||||
List() (*R2Objects, error)
|
||||
}
|
||||
@ -66,12 +66,57 @@ func (r *r2Bucket) Get(key string) (*R2Object, error) {
|
||||
return toR2Object(v)
|
||||
}
|
||||
|
||||
func (r *r2Bucket) Put(key string, value io.Reader) error {
|
||||
panic("implement me")
|
||||
type R2PutOptions struct {
|
||||
HTTPMetadata R2HTTPMetadata
|
||||
CustomMetadata map[string]string
|
||||
MD5 string
|
||||
}
|
||||
|
||||
func (opts *R2PutOptions) toJS() js.Value {
|
||||
if opts == nil {
|
||||
return js.Undefined()
|
||||
}
|
||||
obj := newObject()
|
||||
if opts.HTTPMetadata != (R2HTTPMetadata{}) {
|
||||
obj.Set("httpMetadata", opts.HTTPMetadata.toJS())
|
||||
}
|
||||
if opts.CustomMetadata != nil {
|
||||
// convert map[string]string to map[string]any.
|
||||
// This makes the map convertible to JS.
|
||||
// see: https://pkg.go.dev/syscall/js#ValueOf
|
||||
customMeta := make(map[string]any, len(opts.CustomMetadata))
|
||||
for k, v := range opts.CustomMetadata {
|
||||
customMeta[k] = v
|
||||
}
|
||||
obj.Set("customMetadata", customMeta)
|
||||
}
|
||||
if opts.MD5 != "" {
|
||||
obj.Set("md5", opts.MD5)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// Put returns the result of `put` call to R2Bucket.
|
||||
// * Body field of *R2Object is always nil for Put call.
|
||||
// * if a network error happens, returns error.
|
||||
func (r *r2Bucket) Put(key string, value io.ReadCloser, opts *R2PutOptions) (*R2Object, error) {
|
||||
body := convertReaderToReadableStream(value)
|
||||
p := r.instance.Call("put", key, body, opts.toJS())
|
||||
v, err := awaitPromise(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toR2Object(v)
|
||||
}
|
||||
|
||||
// Delete returns the result of `delete` call to R2Bucket.
|
||||
// * if a network error happens, returns error.
|
||||
func (r *r2Bucket) Delete(key string) error {
|
||||
panic("implement me")
|
||||
p := r.instance.Call("delete", key)
|
||||
if _, err := awaitPromise(p); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns the result of `list` call to R2Bucket.
|
||||
|
32
r2object.go
32
r2object.go
@ -71,12 +71,12 @@ func toR2Object(v js.Value) (*R2Object, error) {
|
||||
// R2HTTPMetadata represents metadata of R2Object.
|
||||
// * https://github.com/cloudflare/workers-types/blob/3012f263fb1239825e5f0061b267c8650d01b717/index.d.ts#L1053
|
||||
type R2HTTPMetadata struct {
|
||||
ContentType *string
|
||||
ContentLanguage *string
|
||||
ContentDisposition *string
|
||||
ContentEncoding *string
|
||||
CacheControl *string
|
||||
CacheExpiry *time.Time
|
||||
ContentType string
|
||||
ContentLanguage string
|
||||
ContentDisposition string
|
||||
ContentEncoding string
|
||||
CacheControl string
|
||||
CacheExpiry time.Time
|
||||
}
|
||||
|
||||
func toR2HTTPMetadata(v js.Value) (R2HTTPMetadata, error) {
|
||||
@ -93,3 +93,23 @@ func toR2HTTPMetadata(v js.Value) (R2HTTPMetadata, error) {
|
||||
CacheExpiry: cacheExpiry,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (md *R2HTTPMetadata) toJS() js.Value {
|
||||
obj := newObject()
|
||||
kv := map[string]string{
|
||||
"contentType": md.ContentType,
|
||||
"contentLanguage": md.ContentLanguage,
|
||||
"contentDisposition": md.ContentDisposition,
|
||||
"contentEncoding": md.ContentEncoding,
|
||||
"cacheControl": md.CacheControl,
|
||||
}
|
||||
for k, v := range kv {
|
||||
if v != "" {
|
||||
obj.Set(k, v)
|
||||
}
|
||||
}
|
||||
if !md.CacheExpiry.IsZero() {
|
||||
obj.Set("cacheExpiry", timeToDate(md.CacheExpiry))
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user