示例#1
0
文件: servers.go 项目: influx6/gu
// WrapForMW takes a giving interface and asserts it into a DriveMiddleware or
// wraps it if needed, returning the middleware.
func WrapForMW(wm interface{}) DriveMiddleware {
	var localWM DriveMiddleware

	switch wm.(type) {
	case func(context.Context, error, interface{}) (interface{}, error):
		localWM = WrapMiddleware(wm.(func(context.Context, error, interface{}) (interface{}, error)))
	case []func(context.Context, error, interface{}) (interface{}, error):
		fm := wm.([]fractals.Handler)
		localWM = WrapMiddleware(fm...)
	case func(interface{}) fractals.Handler:
		localWM = WrapMiddleware(wm.(func(interface{}) fractals.Handler)(fractals.IdentityHandler()))
	case func(context.Context, *Request) error:
		elx := wm.(func(context.Context, *Request) error)
		localWM = func(ctx context.Context, rw *Request) (*Request, error) {
			if err := elx(ctx, rw); err != nil {
				return nil, err
			}

			return rw, nil
		}
	case func(ctx context.Context, rw *Request) (*Request, error):
		localWM = wm.(func(ctx context.Context, rw *Request) (*Request, error))
	default:
		mws := fractals.MustWrap(wm)
		localWM = WrapMiddleware(mws)
	}

	return localWM
}
示例#2
0
文件: servers.go 项目: influx6/gu
// WrapMiddleware wraps a Handler or lifted Handler from the slices of Handlers
// which when runned must return either a (*Request, io.WriteTo, io.Reader,[]byte),
// if it matches others except a *Request, then their contents will be written to
// the response and the *Request passed in will be returned, this allows the
// flexibility of multiple writers based on some operations.
// if the returned value matches non of these types, then an error is returned.
// When running the Handler if it returns an error then that error is returned
// as well.
func WrapMiddleware(handlers ...fractals.Handler) DriveMiddleware {
	var handle fractals.Handler

	if len(handlers) > 1 {
		handle = fractals.Lift(handlers...)(fractals.IdentityHandler())
	} else {
		handle = handlers[0]
	}

	return func(ctx context.Context, rw *Request) (*Request, error) {
		res, err := handle(ctx, nil, rw)
		if err != nil {
			return nil, err
		}

		// If the response is nil, then forward the request object.
		if res == nil {
			return rw, nil
		}

		// If its not nil, then check if it matches a series of types else
		// return an error.
		switch res.(type) {
		case []byte:
			if _, err := rw.Res.Write(res.([]byte)); err != nil {
				return nil, err
			}

			return rw, nil
		case io.Reader:
			rd := res.(io.Reader)
			if _, err := io.Copy(rw.Res, rd); err != nil {
				return nil, err
			}

			return rw, nil

		case io.WriterTo:
			wt := res.(io.WriterTo)

			if _, err := wt.WriteTo(rw.Res); err != nil {
				return nil, err
			}

			return rw, nil
		case *Request:
			return res.(*Request), nil
		default:
			return nil, errors.New("Invalid Type, Require *Request type")
		}
	}
}
示例#3
0
文件: middlewares.go 项目: influx6/gu
// FileServer returns a handler capable of serving different files from the provided
// directory but using inputed URL path.
func FileServer(dir string, prefix string) fractals.Handler {
	var stripper fractals.Handler

	if prefix != "" {
		stripper = fs.StripPrefix(prefix)
	} else {
		stripper = fractals.IdentityHandler()
	}

	return fractals.SubLift(func(rw *Request, data []byte) (*Request, error) {
		if _, err := rw.Res.Write(data); err != nil {
			return nil, err
		}

		return rw, nil
	}, IdentityMiddlewareHandler(), MimeWriter(),
		PathName(), stripper, fs.ResolvePathStringIn(dir), fs.ReadFile())
}