minio/gateway.go

134 lines
2.9 KiB
Go

package minio
import (
"errors"
"fmt"
"github.com/gorilla/mux"
"net/http"
)
type BucketRequest struct {
name string
context Context
callback chan Bucket
}
type Context interface{}
type BucketService interface {
Serve(chan BucketRequest) Bucket
}
type Bucket interface {
GetName(Context) string
Get(Context, string) ([]byte, error)
Put(Context, string, []byte) error
}
func GatewayHandler(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Gateway")
}
func GatewayGetObjectHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
bucket := vars["bucket"]
object := vars["object"]
fmt.Fprintf(w, "bucket: "+bucket)
fmt.Fprintf(w, "\r")
fmt.Fprintf(w, "object: "+object)
}
func RegisterGatewayHandlers(router *mux.Router) {
router.HandleFunc("/{bucket}/{object:.*}", GatewayGetObjectHandler).Methods("GET")
}
func SynchronizedBucketService(input chan BucketRequest) {
buckets := make(map[string]*SynchronizedBucket)
for request := range input {
if buckets[request.name] == nil {
bucketChannel := make(chan ObjectRequest)
go inMemoryBucketServer(bucketChannel)
buckets[request.name] = &SynchronizedBucket{
name: request.name,
channel: bucketChannel,
}
}
request.callback <- buckets[request.name]
}
for key := range buckets {
buckets[key].closeChannel()
}
}
type SynchronizedBucket struct {
name string
channel chan ObjectRequest
objects map[string][]byte
}
type ObjectRequest struct {
requestType string
path string
object []byte
callback chan interface{}
}
func (bucket SynchronizedBucket) GetName(context Context) string {
return bucket.name
}
func (bucket SynchronizedBucket) Get(context Context, path string) ([]byte, error) {
callback := make(chan interface{})
bucket.channel <- ObjectRequest{
requestType: "GET",
path: path,
callback: callback,
}
switch response := <-callback; response.(type) {
case []byte:
return response.([]byte), nil
case error:
return nil, response.(error)
default:
return nil, errors.New("Unexpected error, service failed")
}
}
func (bucket SynchronizedBucket) Put(context Context, path string, object []byte) error {
callback := make(chan interface{})
bucket.channel <- ObjectRequest{
requestType: "PUT",
path: path,
object: object,
callback: callback,
}
switch response := <-callback; response.(type) {
case error:
return response.(error)
case nil:
return nil
default:
return errors.New("Unexpected error, service failed")
}
}
func (bucket *SynchronizedBucket) closeChannel() {
close(bucket.channel)
}
func inMemoryBucketServer(input chan ObjectRequest) {
objects := make(map[string][]byte)
for request := range input {
fmt.Println(objects)
switch request.requestType {
case "GET":
request.callback <- objects[request.path]
case "PUT":
objects[request.path] = request.object
request.callback <- nil
default:
request.callback <- errors.New("Unexpected message")
}
}
}