Ejemplo n.º 1
0
// Marshal converts an object to JSONP.
func (c *JsonPCodec) Marshal(object interface{}, options map[string]interface{}) ([]byte, error) {

	if len(options) == 0 {
		return nil, ErrorMissingCallback
	}

	json, err := jsonEncoding.Marshal(object)

	if err != nil {
		return nil, err
	}

	// #codec-context-options
	// the assumption is options[0] is the callback parameter,
	// and options[1] is the client-context (NB: not *Context) string.

	var callbackFunctionName string
	var callbackString string
	var clientContextString string
	var ok bool

	if callbackFunctionName, ok = options[constants.OptionKeyClientCallback].(string); !ok {
		panic("stretchrcom/codecs: JSONP requires the options to contain the constants.OptionKeyClientCallback value.")
	}

	clientContextString, hasClientContext := options[constants.OptionKeyClientContext].(string)

	if !hasClientContext {
		callbackString = stewstrings.MergeStrings(callbackFunctionName, "(", string(json), ");")
	} else {
		callbackString = stewstrings.MergeStrings(options[constants.OptionKeyClientCallback].(string), "(", string(json), `,"`, clientContextString, `"`, ");")
	}

	return []byte(callbackString), nil
}
Ejemplo n.º 2
0
func (p *PathPattern) String() string {
	return stewstrings.MergeStrings("{PathPattern:\"", p.RawPath, "\"}")
}
Ejemplo n.º 3
0
// MapController maps a controller to a specified path prefix.
//
// For more information, see goweb.MapController.
func (h *HttpHandler) MapController(options ...interface{}) error {

	var matcherFuncStartPos int = -1
	var path string
	var controller interface{}

	if len(options) == 0 {
		// no arguments is an error
		panic("goweb: Cannot call MapController with no arguments")
	}

	switch options[0].(type) {
	case string: // (path, controller)
		if len(options) == 1 {
			// we need more than just a string
			panic("goweb: Cannot call MapController without a Controller")
		}
		path = options[0].(string)
		controller = options[1]
		matcherFuncStartPos = 2
	default: // (controller)
		if restfulController, ok := options[0].(controllers.RestfulController); ok {
			controller = restfulController
			path = restfulController.Path()
		} else {
			// use the default path
			controller = options[0]
			path = paths.PathPrefixForClass(options[0])
		}
		matcherFuncStartPos = 1
	}

	// store the matcher function slice
	var matcherFuncs []MatcherFunc = findMatcherFuncs(options[matcherFuncStartPos:]...)

	// get the specialised paths that we might need
	pathWithID := stewstrings.MergeStrings(path, "/{", RestfulIDParameterName, "}")         // e.g.  people/123
	pathWithOptionalID := stewstrings.MergeStrings(path, "/[", RestfulIDParameterName, "]") // e.g.  people/[123]

	// get the HTTP methods that we will end up mapping
	collectiveMethods := optionsListForResourceCollection(h, controller)
	singularMethods := optionsListForSingleResource(h, controller)

	// BeforeHandler
	if beforeController, ok := controller.(controllers.BeforeHandler); ok {

		// map the collective before handler
		h.MapBefore(collectiveMethods, path, beforeController.Before, matcherFuncs)

		// map the singular before handler
		h.MapBefore(singularMethods, pathWithID, beforeController.Before, matcherFuncs)

	}

	// AfterHandler
	if afterController, ok := controller.(controllers.AfterHandler); ok {

		// map the collective after handler
		h.MapAfter(collectiveMethods, path, afterController.After, matcherFuncs)

		// map the singular after handler
		h.MapAfter(singularMethods, pathWithID, afterController.After, matcherFuncs)

	}

	// POST /resource  -  Create
	if restfulController, ok := controller.(controllers.RestfulCreator); ok {
		h.Map(h.HttpMethodForCreate, path, restfulController.Create, matcherFuncs)
	}

	// GET /resource/{id}  -  Read
	if restfulController, ok := controller.(controllers.RestfulReader); ok {
		h.Map(h.HttpMethodForReadOne, pathWithID, func(ctx context.Context) error {
			return restfulController.Read(ctx.PathParams().Get(RestfulIDParameterName).Str(), ctx)
		}, matcherFuncs)
	}

	// GET /resource  -  ReadMany
	if restfulController, ok := controller.(controllers.RestfulManyReader); ok {
		h.Map(h.HttpMethodForReadMany, path, restfulController.ReadMany, matcherFuncs)
	}

	// DELETE /resource/{id}  -  Delete
	if restfulController, ok := controller.(controllers.RestfulDeletor); ok {
		h.Map(h.HttpMethodForDeleteOne, pathWithID, func(ctx context.Context) error {
			return restfulController.Delete(ctx.PathParams().Get(RestfulIDParameterName).Str(), ctx)
		}, matcherFuncs)
	}

	// DELETE /resource  -  DeleteMany
	if restfulController, ok := controller.(controllers.RestfulManyDeleter); ok {
		h.Map(h.HttpMethodForDeleteMany, path, restfulController.DeleteMany, matcherFuncs)
	}

	// PATCH /resource/{id}  -  Update
	if restfulController, ok := controller.(controllers.RestfulUpdater); ok {
		h.Map(h.HttpMethodForUpdateOne, pathWithID, func(ctx context.Context) error {
			return restfulController.Update(ctx.PathParams().Get(RestfulIDParameterName).Str(), ctx)
		}, matcherFuncs)
	}

	// PATCH /resource  -  UpdateMany
	if restfulController, ok := controller.(controllers.RestfulManyUpdater); ok {
		h.Map(h.HttpMethodForUpdateMany, path, restfulController.UpdateMany, matcherFuncs)
	}

	// PUT /resource/{id}  -  Replace
	if restfulController, ok := controller.(controllers.RestfulReplacer); ok {
		h.Map(h.HttpMethodForReplace, pathWithID, func(ctx context.Context) error {
			return restfulController.Replace(ctx.PathParams().Get(RestfulIDParameterName).Str(), ctx)
		}, matcherFuncs)
	}

	// HEAD /resource/[id]  -  Head
	if restfulController, ok := controller.(controllers.RestfulHead); ok {
		h.Map(h.HttpMethodForHead, pathWithOptionalID, restfulController.Head, matcherFuncs)
	}

	// OPTIONS /resource/[id]  -  Options
	if restfulController, ok := controller.(controllers.RestfulOptions); ok {

		h.Map(h.HttpMethodForOptions, pathWithOptionalID, restfulController.Options, matcherFuncs)

	} else {

		// use the default options implementation

		h.Map(http.MethodOptions, path, func(ctx context.Context) error {
			ctx.HttpResponseWriter().Header().Set("Allow", strings.Join(collectiveMethods, ","))
			ctx.HttpResponseWriter().WriteHeader(200)
			return nil
		}, matcherFuncs)

		h.Map(http.MethodOptions, pathWithID, func(ctx context.Context) error {
			ctx.HttpResponseWriter().Header().Set("Allow", strings.Join(singularMethods, ","))
			ctx.HttpResponseWriter().WriteHeader(200)
			return nil
		}, matcherFuncs)

	}

	// everything ok
	return nil

}