Beispiel #1
0
// WriteResponseObject writes the status code and response object to the HttpResponseWriter in
// the specified context, in the format best suited based on the request.
//
// Goweb uses the WebCodecService to decide which codec to use when responding
// see http://godoc.org/github.com/stretchrcom/codecs/services#WebCodecService for more information.
//
// This method should be used when the Goweb Standard Response Object does not satisfy the needs of
// the API, but other Respond* methods are recommended.
func (a *GowebAPIResponder) WriteResponseObject(ctx context.Context, status int, responseObject interface{}) error {

	service := a.GetCodecService()

	acceptHeader := ctx.HttpRequest().Header.Get("Accept")
	extension := ctx.FileExtension()
	hasCallback := len(ctx.QueryValue("callback")) > 0

	codec, codecError := service.GetCodecForResponding(acceptHeader, extension, hasCallback)

	if codecError != nil {
		return codecError
	}

	var options map[string]interface{}

	// do we need to add some options?
	if hasCallback {
		options = map[string]interface{}{constants.OptionKeyClientCallback: ctx.QueryValue("callback")}
	}

	output, marshalErr := codec.Marshal(responseObject, options)

	if marshalErr != nil {
		return marshalErr
	}

	// use the HTTP responder to respond
	ctx.HttpResponseWriter().Header().Set("Content-Type", codec.ContentType()) // TODO: test me
	a.httpResponder.With(ctx, status, output)

	return nil

}
Beispiel #2
0
// Handle writes the error from the context into the HttpResponseWriter with a
// 500 http.StatusInternalServerError status code.
func (h *DefaultErrorHandler) Handle(ctx context.Context) (stop bool, err error) {

	var handlerError HandlerError = ctx.Data().Get(DataKeyForError).(HandlerError)
	hostname, _ := os.Hostname()

	w := ctx.HttpResponseWriter()

	// write the error out
	w.Header().Set("Content-Type", "text/html")
	w.WriteHeader(http.StatusInternalServerError)
	w.Write([]byte("<!DOCTYPE html><html><head>"))
	w.Write([]byte("<style>"))
	w.Write([]byte("h1 { font-size: 17px }"))
	w.Write([]byte("h1 strong {text-decoration:underline}"))
	w.Write([]byte("h2 { background-color: #ffd; padding: 20px }"))
	w.Write([]byte("footer { margin-top: 20px; border-top:1px solid black; padding:10px; font-size:0.9em }"))
	w.Write([]byte("</style>"))
	w.Write([]byte("</head><body>"))
	w.Write([]byte(fmt.Sprintf("<h1>Error in <code>%s</code></h1><h2>%s</h2>", handlerError.Handler, handlerError)))
	w.Write([]byte(fmt.Sprintf("<h3><code>%s</code> error in Handler <code>%v</code></h3> <code><pre>%s</pre></code>", reflect.TypeOf(handlerError.OriginalError), &handlerError.Handler, handlerError.Handler)))
	w.Write([]byte(fmt.Sprintf("on %s", hostname)))
	w.Write([]byte("<footer>Learn more about <a href='http://github.com/stretchrcom/goweb' target='_blank'>Goweb</a></footer>"))
	w.Write([]byte("</body></html>"))

	// responses are actually ignored
	return false, nil
}
Beispiel #3
0
// Before gets called before any other method.
func (r *ThingsController) Before(ctx context.Context) error {

	// set a Things specific header
	ctx.HttpResponseWriter().Header().Set("X-Things-Controller", "true")

	return nil

}
Beispiel #4
0
// With writes a response to the request in the specified context.
func (r *GowebHTTPResponder) With(ctx context.Context, httpStatus int, body []byte) error {

	r.WithStatus(ctx, httpStatus)

	_, writeErr := ctx.HttpResponseWriter().Write(body)
	return writeErr

}
Beispiel #5
0
func (r *ThingsController) Create(ctx context.Context) error {

	data, dataErr := ctx.RequestData()

	if dataErr != nil {
		return goweb.API.RespondWithError(ctx, http.StatusInternalServerError, dataErr.Error())
	}

	dataMap := data.(map[string]interface{})

	thing := new(Thing)
	thing.Id = dataMap["Id"].(string)
	thing.Text = dataMap["Text"].(string)

	r.Things = append(r.Things, thing)

	return goweb.Respond.WithStatus(ctx, http.StatusCreated)

}
Beispiel #6
0
//add error catching here.
func (r *UniversumController) Read(brand string, ctx context.Context) error {

	fmt.Println("rest")
	query := ctx.HttpRequest().URL.RawQuery
	//metric_name := GetQueryValue("name",query)
	since_str := GetQueryValue("since", query)
	const shortForm = "2006-Jan-02"
	since, _ := time.Parse(shortForm, since_str)

	until_str := GetQueryValue("until", query)
	until, _ := time.Parse(shortForm, until_str)
	resolution := "day"

	key := GetQueryValue("apikey", query)
	fmt.Println("the api key is " + key)
	user_id := db.Read("universum", "apikeys", key)

	if len(user_id) < 1 {
		errObject := "unverified api key"
		return goweb.API.RespondWithError(ctx, 500, errObject)
	}

	if brand == "ranking" {
		ranking := new(RankingData)
		ranking.Type = brand
		ranking.Brands, ranking.Change = GetMetrics(brand, query, since, until, resolution)
		return goweb.API.RespondWithData(ctx, ranking)
	}

	data := new(Data)
	data.Brand = brand
	data.Metrics, data.TimeStamp = GetMetrics(brand, query, since, until, resolution)

	fmt.Println("booyay")
	return goweb.API.RespondWithData(ctx, data)

}
Beispiel #7
0
// WillHandle checks whether this handler will be used to handle the specified
// request or not.
func (p *PathMatchHandler) WillHandle(c context.Context) (bool, error) {

	// check each matcher func
	matcherFuncMatches := true
	matcherFuncDecisionMade := false
	for _, matcherFunc := range p.MatcherFuncs {
		decision, matcherFuncErr := matcherFunc(c)

		if matcherFuncErr != nil {
			return false, matcherFuncErr
		}

		switch decision {
		case NoMatch:
			matcherFuncMatches = false
			matcherFuncDecisionMade = true
			break
		case Match:
			matcherFuncMatches = true
			matcherFuncDecisionMade = true
			break
		}

		if matcherFuncDecisionMade {
			break
		}

	}

	// check HTTP methods
	var httpMethodMatch bool = false

	if len(p.HttpMethods) == 0 {

		// no specific HTTP methods
		httpMethodMatch = true

	} else {

		for _, httpMethod := range p.HttpMethods {
			if httpMethod == c.MethodString() {
				httpMethodMatch = true
				break
			}
		}

	}

	// cancel early if we didn't get an HTTP Method match
	if !httpMethodMatch {
		return false, nil
	}

	// check path match

	pathMatch := p.PathPattern.GetPathMatch(c.Path())

	var allMatch bool

	if matcherFuncDecisionMade {
		allMatch = matcherFuncMatches
	} else {
		allMatch = pathMatch.Matches
	}

	if allMatch {

		// save the match parameters for later
		c.Data().Set(context.DataKeyPathParameters, pathMatch.Parameters)

	}

	return allMatch, nil
}
Beispiel #8
0
// WithPermanentRedirect responds with a redirection to the specific path or URL with the
// http.StatusMovedPermanently status.
func (r *GowebHTTPResponder) WithPermanentRedirect(ctx context.Context, pathOrURLSegments ...interface{}) error {
	ctx.HttpResponseWriter().Header().Set("Location", paths.PathFromSegments(pathOrURLSegments...))
	return r.WithStatus(ctx, http.StatusMovedPermanently)
}
Beispiel #9
0
// WithStatus writes the specified HTTP Status Code to the Context's ResponseWriter.
func (r *GowebHTTPResponder) WithStatus(ctx context.Context, httpStatus int) error {
	ctx.HttpResponseWriter().WriteHeader(httpStatus)
	return nil
}