Example #1
0
func root(ctx *web.Context) string {
	msg := form
	if said, ok := ctx.GetSecureCookie("said"); ok {
		msg = "You said " + said + "<p>" + msg
	}
	return msg
}
Example #2
0
func handleGetEnviron(ctx *web.Context) (map[string]string, error) {
	if err := errorIfNotMaster(ctx); err != nil {
		return nil, err
	}
	ctx.ContentType("json")
	s := ctx.User.(*server)
	return s.session.Environ(), nil
}
Example #3
0
func redirect(ctx *web.Context, loc *url.URL) {
	if _, ok := ctx.Params["noredirect"]; ok {
		return
	}
	loc = ctx.Request.URL.ResolveReference(loc)
	ctx.Header().Set("Location", loc.String())
	ctx.WriteHeader(303)
	fmt.Fprintf(ctx, "redirecting to %s", loc)
}
Example #4
0
// List of files nice for tab completion
func handleGetFiles(ctx *web.Context) error {
	if err := errorIfNotMaster(ctx); err != nil {
		return err
	}
	ctx.ContentType("json")
	paths, err := filepath.Glob(ctx.Params["pattern"])
	if err != nil {
		return err
	}
	if paths == nil {
		paths = []string{}
	}
	return json.NewEncoder(ctx).Encode(paths)
}
Example #5
0
func handleGetCmdJson(ctx *web.Context, idstr string) error {
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	md, err := metacmd{c}.Metadata()
	if err != nil {
		return err
	}
	ctx.ContentType("json")
	// Don't hammer me, but don't cache for too long. This resource is not
	// intended for polling, anyway. This may seem race sensitive, but that's
	// because it is. Only matters in big, multi user setups with lots of
	// concurrent changes, which is totally not lush's current intended use
	// case. So a few race conditions here and there are no biggy (for now).
	ctx.Response.Header().Set("cache-control", "max-age=3")
	return json.NewEncoder(ctx).Encode(md)
}
Example #6
0
func handleGetCmdInfo(ctx *web.Context, idstr string) error {
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	ctx.Header().Set("content-type", "application/json")
	enc := json.NewEncoder(ctx)
	var info = struct {
		Started, Exited *time.Time
		Error           string `json:",omitempty"`
	}{
		Started: c.Status().Started(),
		Exited:  c.Status().Exited(),
	}
	if cerr := c.Status().Err(); cerr != nil {
		info.Error = cerr.Error()
	}
	return enc.Encode(info)
}
Example #7
0
func handleGetCmdidsJson(ctx *web.Context) error {
	s := ctx.User.(*server)
	ids := s.session.GetCommandIds()
	ctx.ContentType("json")
	return json.NewEncoder(ctx).Encode(ids)
}
Example #8
0
// Websocket control connection. All connected clients are considered equal.
func handleWsCtrl(ctx *web.Context) error {
	wsconn, err := websocket.Upgrade(ctx.Response, ctx.Request, nil, 1024, 1024)
	if _, ok := err.(websocket.HandshakeError); ok {
		// Get the secret token to include in a websocket request
		ctx.ContentType("txt")
		fmt.Fprint(ctx.Response, getWebsocketKey())
		return nil
	} else if err != nil {
		return err
	}
	s := ctx.User.(*server)
	ws := newWsClient(wsconn)
	defer ws.Close()
	// This is just for the incoming key, after which blocking on read is fine
	err = ws.SetReadDeadline(time.Now().Add(5 * time.Second))
	if err != nil {
		return fmt.Errorf("Couldn't set read deadline for websocket: %v", err)
	}
	// First order of business: see if the client sends me the correct key
	// this could be done lots of ways different, perhaps more elegant ways:
	// HTTP headers, query parameters, secret path, ... BUT! This method is very
	// straight-forward and easy to understand.
	msg, err := ws.ReadTextMessage()
	if err != nil {
		return err
	}
	if string(msg) != getWebsocketKey() {
		// This is a best effort service to help whoever tried to connect to
		// this in debugging, hence no error checking.
		fmt.Fprint(ws, "Invalid lush key")
		return errors.New("Illegal websocket key")
	}
	// Alright I trust this client now, read ops are expected to block
	err = ws.SetReadDeadline(time.Time{})
	if err != nil {
		return fmt.Errorf("Couldn't remove read deadline for websocket: %v", err)
	}
	// tell the client about its Id
	_, err = fmt.Fprint(ws, "clientid;", ws.Id)
	if err != nil {
		return fmt.Errorf("Websocket write error: %v", err)
	}
	// Subscribe this ws client to all future control events. Will be removed
	// automatically when the first Write fails (FlexibleMultiWriter).
	// Therefore, no need to worry about removing: client disconnects -> next
	// Write fails -> removed.
	s.ctrlclients.AddWriter(ws)
	// notify all other clients that a new client has connected
	wseventAllclients(s, "") // pretend somebody generated this event
	// TODO: keep clients updated about disconnects, too
	ws.isMaster = claimMaster(ctx)
	for {
		msg, err := ws.ReadTextMessage()
		if err != nil {
			s.ctrlclients.RemoveWriter(ws)
			return err
		}
		err = parseAndHandleWsEvent(s, ws, msg)
		if err != nil {
			return fmt.Errorf("error handling WS event: %v", err)
		}
	}
	return errors.New("unreachable")
}
Example #9
0
File: params.go Project: hraban/web
func process(ctx *web.Context) string {
	ctx.ContentType("txt")
	return fmt.Sprintf("%#v", ctx.Params)
}
Example #10
0
func say(ctx *web.Context) {
	ctx.SetSecureCookie("said", ctx.Params["said"], 3600)
	ctx.Redirect(303, "/")
	return
}
Example #11
0
// This function will be called prior to each web request
func AuthHandler(ctx *web.Context) error {
	ctx.User = "******"
	fmt.Println(ctx.Request.Header)
	return nil
}
Example #12
0
func i(ctx *web.Context) {
	ctx.Write([]byte("<a href=j>non-nil error"))
}