Beispiel #1
0
// Update the database if the lastPullTime is more than 6 hours before the current time
func updateDB(db *sql.DB, ctx context.Context, lastPullTime int64) int64 {
	// If the last pull was more than 6 hours ago
	if lastPull < time.Now().Add(-1*timeout).Unix() {
		log.Infof(ctx, "Updating database")

		// Remove deleted questions from the database
		log.Infof(ctx, "Removing deleted questions from db")
		if err := backend.RemoveDeletedQuestions(db, ctx); err != nil {
			log.Warningf(ctx, "Error removing deleted questions: %v", err.Error())
			return lastPullTime
		}

		// Setting time frame to get new questions.
		toDate := time.Now()
		fromDate := time.Unix(lastPull, 0)

		// Collect new questions from SO
		questions, err := backend.GetNewQns(fromDate, toDate)
		if err != nil {
			log.Warningf(ctx, "Error getting new questions: %v", err.Error())
			return lastPullTime
		}

		// Add new questions to database
		log.Infof(ctx, "Adding new questions to db")
		if err := backend.AddQuestions(db, ctx, questions); err != nil {
			log.Warningf(ctx, "Error adding new questions: %v", err.Error())
			return lastPullTime
		}

		lastPullTime = time.Now().Unix()
		log.Infof(ctx, "New questions added")
	}
	return lastPullTime
}
Beispiel #2
0
func deleteData(res http.ResponseWriter, req *http.Request) {
	ctx := appengine.NewContext(req)
	u := user.Current(ctx)
	keyVal := req.FormValue("keyVal")
	key, err := datastore.DecodeKey(keyVal)
	if err != nil {
		http.Error(res, "Invalid data", http.StatusBadRequest)
		log.Warningf(ctx, err.Error())
		return
	}
	var l list
	err = datastore.Get(ctx, key, &l)
	if err != nil {
		http.Error(res, "Invalid data", http.StatusBadRequest)
		log.Warningf(ctx, err.Error())
		return
	}
	if l.Owner != u.Email {
		http.Error(res, "Not authorized to delete this entry", http.StatusUnauthorized)
		log.Warningf(ctx, err.Error())
		return
	}
	err = datastore.Delete(ctx, key)
	if err != nil {
		http.Error(res, "Server Error", http.StatusInternalServerError)
		log.Errorf(ctx, err.Error())
		return
	}
}
Beispiel #3
0
//Function called when the /viewTags request is made
//Retrieves all distinct tags and the number of questions saved in the db with that tag
func readTagsFromDb(ctx context.Context) []tagData {
	var tempData []tagData
	var (
		tag   sql.NullString
		count sql.NullInt64
	)

	rows, err := db.Query("SELECT tag, COUNT(tag) FROM question_tag GROUP BY tag")
	if err != nil {
		log.Warningf(ctx, "Tag query failed: %v", err.Error())
		return tempData
	}

	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(&tag, &count)
		if err != nil {
			log.Warningf(ctx, "Tag Scan failed: %v", err.Error())
			continue
		}
		currentTag := tagData{tag.String, int(count.Int64)}
		tempData = append(tempData, currentTag)
	}

	return tempData
}
// determine whether old request has ended according to logs
func (l *Locker) previousRequestEnded(c context.Context, requestID string) bool {
	q := &log.Query{
		RequestIDs: []string{requestID},
	}
	results := q.Run(c)
	record, err := results.Next()
	if err == log.Done {
		// no record found so it hasn't ended
		if l.LogVerbose {
			log.Warningf(c, "no log found for previous request %s", requestID)
		}
		return false
	}
	if err != nil {
		// Managed VMs do not have access to the logservice API
		if l.LogVerbose {
			log.Warningf(c, "err getting log for previous request %s %v", requestID, err)
		}
		return false
	}
	if l.LogVerbose {
		log.Debugf(c, "found previous request log %v", record)
	}
	return record.Finished
}
// Handle wraps a task handler with task / lock processing
func (l *Locker) Handle(handler TaskHandler, factory EntityFactory) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		c := appengine.NewContext(r)

		// ensure request is a task request
		if r.Method != "POST" || r.Header.Get("X-Appengine-TaskName") == "" {
			log.Warningf(c, "non task request")
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		// use the same queue name for any tasks scheduled by this handler
		queue := r.Header.Get("X-Appengine-QueueName")
		c = WithQueue(c, queue)

		key, seq, err := l.Parse(c, r)
		if err != nil {
			log.Warningf(c, "parse failed: %v", err)
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		entity := factory()
		err = l.Aquire(c, key, entity, seq)
		if err != nil {
			log.Warningf(c, "lock failed: %v", err)
			// if we have a lock error, it provides the http response to use
			if lerr, ok := err.(Error); ok {
				w.WriteHeader(lerr.Response)
			} else {
				w.WriteHeader(http.StatusInternalServerError)
			}
			return
		}

		// TODO: explore having handler return something to indicate
		// if the task needs to continue with the next seq or be completed
		err = handler(c, r, key, entity)
		if err != nil {
			log.Warningf(c, "handler failed: %v", err)
			// clear the lock to allow the next retry
			if err := l.clearLock(c, key, entity); err != nil {
				log.Warningf(c, "clearLock failed: %v", err)
				// if we have a lock error, it provides the http response to use
				if lerr, ok := err.(Error); ok {
					w.WriteHeader(lerr.Response)
				} else {
					w.WriteHeader(http.StatusInternalServerError)
				}
			} else {
				w.WriteHeader(http.StatusInternalServerError)
			}
			return
		}

		w.WriteHeader(http.StatusOK)
	}

	return http.HandlerFunc(fn)
}
Beispiel #6
0
func adminUpdateTask(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	tid := r.FormValue("taskKey")

	k, err := datastore.DecodeKey(tid)
	if err != nil {
		panic(err)
	}

	task := &Task{}
	if err := datastore.Get(c, k, task); err != nil {
		log.Warningf(c, "Error getting task %v: %v", k, err)
		http.Error(w, err.Error(), 404)
		return
	}

	task.Name = r.FormValue("name")
	task.Description = r.FormValue("description")
	task.Value = asInt(r.FormValue("value"))
	task.Period = asInt(r.FormValue("period"))
	task.Disabled = mightParseBool(r.FormValue("disabled"))
	task.Automatic = mightParseBool(r.FormValue("automatic"))
	task.Assignee = r.FormValue("assignee")

	if _, err := datastore.Put(c, k, task); err != nil {
		log.Warningf(c, "Error storing task %v, %+v: %v", k, task, err)
		http.Error(w, err.Error(), 500)
		return
	}
	w.WriteHeader(204)
}
Beispiel #7
0
// Handler for pulling questions from Stack Overflow manually, based on a given ID
// Request is parsed to find the supplied ID
// A check is completed to see if the question is already in the system
// If so, it retrieves that question, and returns it to be viewed, along with a message
// Makes a new backend request to retrieve new questions
// Parses the returned data into a new page, which can be inserted into the template.
func newQnHandler(w http.ResponseWriter, r *http.Request, ctx context.Context) {
	id, _ := strconv.Atoi(r.FormValue("id"))

	res, err := backend.CheckForExistingQuestion(db, id)
	if err != nil {
		log.Infof(ctx, "QUERY FAILED, %v", err)
	}

	if res == 1 {

		existingQn := backend.PullQnByID(db, ctx, id)
		if err != nil {
			log.Warningf(ctx, err.Error())
		}
		w.Write(existingQn)
	} else {

		intArray := []int{id}
		questions, err := backend.GetQuestions(ctx, intArray)
		if err != nil {
			log.Warningf(ctx, err.Error())
		} else {
			questions.Items[0].Body = backend.StripTags(questions.Items[0].Body)
			qnJson, err := json.Marshal(questions.Items[0])
			if err != nil {
				log.Warningf(ctx, err.Error())
			}
			w.Write(qnJson)
		}
	}
}
// PrimaryPublicCertificates returns primary's PublicCertificates.
func PrimaryPublicCertificates(c context.Context, primaryURL string) (*PublicCertificates, error) {
	cacheKey := fmt.Sprintf("pub_certs:%s", primaryURL)
	var pubCerts []byte
	setCache := false
	item, err := memcache.Get(c, cacheKey)
	if err != nil {
		setCache = true
		if err != memcache.ErrCacheMiss {
			log.Warningf(c, "failed to get cert from cache: %v", err)
		}
		pubCerts, err = downloadCert(urlfetch.Client(c), primaryURL)
		if err != nil {
			log.Errorf(c, "failed to download cert: %v", err)
			return nil, err
		}
	} else {
		pubCerts = item.Value
	}
	pc := &PublicCertificates{}
	if err = json.Unmarshal(pubCerts, pc); err != nil {
		log.Errorf(c, "failed to unmarshal cert: %v %v", string(pubCerts), err)
		return nil, err
	}
	if setCache {
		err = memcache.Set(c, &memcache.Item{
			Key:        cacheKey,
			Value:      pubCerts,
			Expiration: time.Hour,
		})
		if err != nil {
			log.Warningf(c, "failed to set cert to cache: %v", err)
		}
	}
	return pc, nil
}
Beispiel #9
0
func handleTweet(res http.ResponseWriter, req *http.Request) {
	ctx := appengine.NewContext(req)
	u := getCurrentUser(req)
	if u == nil {
		http.Error(res, "Incorrect login", http.StatusUnauthorized)
		log.Warningf(ctx, "Incorrect login from: %s\n", req.RemoteAddr)
		return
	}
	if req.Method != "POST" {
		http.Error(res, "Unknown method", http.StatusMethodNotAllowed)
		log.Warningf(ctx, "Incorrect method on tweet.json from %s", req.RemoteAddr)
		return
	}
	buffer := make([]byte, tweetSize)
	n, err := req.Body.Read(buffer)
	if err != nil && err != io.EOF {
		http.Error(res, "Bad Request", http.StatusBadRequest)
		log.Warningf(ctx, "Bad request: %s\n", err.Error())
		return
	}
	msg := string(buffer[:n])
	t := tweet{
		Username:   u.Username,
		Message:    msg,
		SubmitTime: time.Now(),
	}
	err = postTweet(ctx, &t, u.Email)
	if err != nil {
		http.Error(res, "Server error!", http.StatusInternalServerError)
		log.Errorf(ctx, "Put Tweet Error: %s\n", err.Error())
		return
	}
}
Beispiel #10
0
func adminAutoPay(w http.ResponseWriter, r *http.Request) {
	now := time.Now()
	c := appengine.NewContext(r)
	q := datastore.NewQuery("Task").
		Filter("Disabled =", false).
		Filter("Automatic = ", true).
		Filter("Next < ", now)

	tasks := []*Task{}
	if err := fillKeyQuery(c, q, &tasks); err != nil {
		log.Warningf(c, "Error finding automatic things: %v", err)
		w.WriteHeader(500)
		return
	}

	if len(tasks) == 0 {
		log.Infof(c, "No automatic tasks.")
		w.WriteHeader(204)
		return
	}

	storeKeys := make([]*datastore.Key, 0, 2*len(tasks))
	vals := []interface{}{}

	for i := range tasks {
		log.Infof(c, "Recording automatic task %q for %v at %s", tasks[i].Name,
			tasks[i].Assignee, moneyFmt(tasks[i].Value))

		su, err := getUserByEmail(c, tasks[i].Assignee)
		if err != nil {
			log.Warningf(c, "Failed to look up user %v: %v", tasks[i].Assignee, err)
			w.WriteHeader(500)
			return
		}

		tasks[i].updateTime()
		tasks[i].Prev = now
		storeKeys = append(storeKeys, tasks[i].Key)
		vals = append(vals, tasks[i])

		storeKeys = append(storeKeys,
			datastore.NewIncompleteKey(c, "LoggedTask", nil))
		vals = append(vals, &LoggedTask{
			Task:      tasks[i].Key,
			User:      su.Key,
			Completed: now,
			Who:       su.Name,
			Name:      tasks[i].Name,
			Amount:    tasks[i].Value,
		})
	}

	if _, err := datastore.PutMulti(c, storeKeys, vals); err != nil {
		panic(err)
	}

	w.WriteHeader(204)
}
Beispiel #11
0
// Returns the current user requesting the page
func getUser(w http.ResponseWriter, r *http.Request, ctx context.Context) stackongo.User {
	guest := stackongo.User{
		Display_name: "Guest",
	}

	// Collect userId from browser cookie
	username, err := r.Cookie("user_name")
	if err == nil && username.Value != "" && username.Value != "Guest" {
		user := readUserFromDb(ctx, username.Value)
		updateLoginTime(ctx, user.User_id)
		return user
	}

	// If user_id cookie is not set, look for code in url request to collect access token.
	// If code is not available, return guest user
	code := r.FormValue("code")
	if code == "" {
		log.Infof(ctx, "Returning guest user")
		guest.User_type = "no_code"
		return guest
	}

	queries := r.URL.Query()
	queries.Del("code")
	r.URL.RawQuery = queries.Encode()
	// Collect access token using the recieved code
	access_tokens, err := backend.ObtainAccessToken(code, r.URL.String())
	if err != nil {
		log.Warningf(ctx, "Access token not obtained: %v", err.Error())
		guest.User_type = "no_access_token"
		return guest
	}

	// Get the authenticated user with the collected access token
	user, err := backend.AuthenticatedUser(map[string]string{}, access_tokens["access_token"])
	if err != nil {
		log.Warningf(ctx, "User not authenticated: %v", err)
		guest.User_type = "not_on_SO"
		return guest
	}

	// Add user to db if not already in
	addUserToDB(ctx, user)

	//zhu li do the thing
	updateLoginTime(ctx, user.User_id)
	return user
}
Beispiel #12
0
func recaptchaCheck(ctx context.Context, response, ip string) (bool, error) {
	if appengine.IsDevAppServer() {
		return true, nil
	}

	form := url.Values{}
	form.Add("secret", os.Getenv("SECRET"))
	form.Add("response", response)
	form.Add("remoteip", ip)
	req, err := http.NewRequest("POST", recaptchaURL, strings.NewReader(form.Encode()))
	if err != nil {
		return false, err
	}

	cli := urlfetch.Client(ctx)

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	resp, err := cli.Do(req)
	if err != nil {
		return false, err
	}

	var recaptcha recaptchaResponse
	if err := json.NewDecoder(resp.Body).Decode(&recaptcha); err != nil {
		return false, err
	}

	if !recaptcha.Success {
		log.Warningf(ctx, "%+v", recaptcha)
		return false, nil
	}

	return true, nil
}
Beispiel #13
0
//Display a list of tags that are logged in the database
//User can either click on a tag to view any questions containing that tag
//Format array of tags into another array, to be easier formatted on the page into a table in the template
//An array of tagData arrays of size 4
func viewTagsHandler(w http.ResponseWriter, r *http.Request, ctx context.Context, pageNum int, user stackongo.User) {
	query := readTagsFromDb(ctx)
	var tagArray [][]tagData
	var tempTagArray []tagData
	i := 0
	for _, t := range query {
		tempTagArray = append(tempTagArray, t)
		i++
		if i == 4 {
			tagArray = append(tagArray, tempTagArray)
			i = 0
			//clear the temp array.
			tempTagArray = nil
		}
	}
	tagArray = append(tagArray, tempTagArray)
	page := template.Must(template.ParseFiles("public/viewTags.html"))
	first := (pageNum - 1) * 5
	last := pageNum * 5
	lastPage := len(tagArray) / 5
	if len(tagArray)%5 != 0 {
		lastPage++
	}
	if last > len(tagArray) {
		last = len(tagArray)
	}
	if err := page.Execute(w, queryReply{user, mostRecentUpdate, pageNum, lastPage, tagArray[first:last]}); err != nil {
		log.Warningf(ctx, "%v", err.Error())
	}

}
Beispiel #14
0
// Handler for adding a new question to the database upon submission
// It is returned as a stringified JSON object in the request body
// The string is unmarshalled into a stackongo.Question type, and added to an array
// to be added into the database using the AddQuestions function in backend/databasing.go
func addNewQuestionToDatabaseHandler(w http.ResponseWriter, r *http.Request, ctx context.Context) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Infof(ctx, "%v", err)
	}
	var f interface{}
	err = json.Unmarshal(body, &f)
	if err != nil {
		log.Infof(ctx, "%v", err)
	}
	m := f.(map[string]interface{})
	question := m["Question"]
	state := m["State"]
	if err != nil {
		log.Infof(ctx, "%v", err)
	}
	var qn stackongo.Question
	json.Unmarshal([]byte(question.(string)), &qn)
	log.Infof(ctx, "%v", qn)

	user := getUser(w, r, ctx)
	log.Infof(ctx, "%v", user.User_id)

	if err := backend.AddSingleQuestion(db, qn, state.(string), user.User_id); err != nil {
		log.Warningf(ctx, "Error adding new question to db:\t", err)
	}
	backend.UpdateTableTimes(db, ctx, "question")
}
Beispiel #15
0
// Handler for adding new question page
func addQuestionHandler(w http.ResponseWriter, r *http.Request, ctx context.Context,
	pageNum int, user stackongo.User) {
	page := template.Must(template.ParseFiles("public/addQuestion.html"))
	if err := page.Execute(w, queryReply{user, mostRecentUpdate, pageNum, 0, nil}); err != nil {
		log.Warningf(ctx, "%v", err.Error())
	}
}
Beispiel #16
0
func createProfile(res http.ResponseWriter, req *http.Request) {
	ctx := appengine.NewContext(req)
	u := user.Current(ctx)

	if req.Method == "POST" {
		username := req.FormValue("username")
		// check if name is taken
		if !confirmCreateProfile(username) {
			http.Error(res, "Invalid input!", http.StatusBadRequest)
			log.Warningf(ctx, "Invalid profile information from %s\n", req.RemoteAddr)
			return
		}

		key := datastore.NewKey(ctx, "profile", u.Email, 0, nil)
		p := profile{
			Username: username,
			Email:    u.Email,
		}
		_, err := datastore.Put(ctx, key, &p)
		if err != nil {
			http.Error(res, "server error!", http.StatusInternalServerError)
			log.Errorf(ctx, "Create profile Error: &s\n", err.Error())
			return
		}
	}
	err := tpl.ExecuteTemplate(res, "createProfile.gohtml", nil)
	if err != nil {
		http.Error(res, "Serever error!", http.StatusInternalServerError)
		log.Errorf(ctx, "Template Parse Error: %s\n", err.Error())
		return
	}
}
Beispiel #17
0
// Handler to find all questions answered/being answered by the user in URL
func userHandler(w http.ResponseWriter, r *http.Request, ctx context.Context, pageNum int, user stackongo.User) {
	userID_string := r.FormValue("id")
	userID_int, _ := strconv.Atoi(userID_string)
	log.Infof(ctx, "current user id=%s", userID_string)

	// Create a new webData struct
	tempData, updateTime, err := readFromDb(ctx, "state='unanswered' OR questions.user="******"Error reading from db: %v", err.Error())
	} else {
		mostRecentUpdate = updateTime
	}

	// Parse the html template to serve to the page
	page := getTemplate("template.html")

	var Query = []string{
		"user",
		tempData.Users[userID_int].User_info.Display_name,
	}
	log.Infof(ctx, "Query = %v", Query)
	if err := page.Execute(w, writeResponse(user, tempData, pageNum, Query)); err != nil {
		log.Warningf(ctx, "%v", err.Error())
	}
}
Beispiel #18
0
func (sink *LogSink) writeLogStorage(r *wcg.LogRecord) error {
	c := sink.ctx
	formatter := sink.formatter
	if c == nil {
		c = NewContext(r.Request)
	}
	var text string
	if r.SourceStack != nil && len(r.SourceStack) > 0 {
		text = fmt.Sprintf(
			"%s\n-- Stack Trace --\n%s",
			string(formatter.Format(r)),
			strings.Join(r.SourceStack, "\n"),
		)
	} else {
		text = string(formatter.Format(r))
	}

	switch r.Level {
	case wcg.LogLevelTrace:
		log.Debugf(c, "%s", text) // app engine does not support trace level
	case wcg.LogLevelDebug:
		log.Debugf(c, "%s", text)
	case wcg.LogLevelInfo:
		log.Infof(c, "%s", text)
	case wcg.LogLevelWarn:
		log.Warningf(c, "%s", text)
	case wcg.LogLevelError:
		log.Errorf(c, "%s", text)
	case wcg.LogLevelFatal:
		log.Criticalf(c, "%s", text)
	default:
		// nothing
	}
	return nil
}
Beispiel #19
0
func adminNewTask(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	asInt := func(s string) int {
		i, err := strconv.Atoi(s)
		if err != nil {
			panic(err)
		}
		return i
	}

	task := Task{
		Name:        r.FormValue("name"),
		Description: r.FormValue("description"),
		Assignee:    r.FormValue("assignee"),
		RType:       r.FormValue("rtype"),
		Automatic:   mightParseBool(r.FormValue("automatic")),
		Period:      asInt(r.FormValue("period")),
		Value:       asInt(r.FormValue("value")),
		Next:        time.Now().UTC(),
	}

	k, err := datastore.Put(c,
		datastore.NewIncompleteKey(c, "Task", nil), &task)
	if err != nil {
		log.Warningf(c, "Error storing task:  %v", err)
		panic(err)
	}
	log.Infof(c, "Stored new thing with key %v", k)

	http.Redirect(w, r, "/admin/tasks/", 307)
}
Beispiel #20
0
func submitAddHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	if err := r.ParseForm(); err != nil {
		serveErr(ctx, err, w)
		return
	}

	success, err := recaptchaCheck(ctx, r.FormValue("g-recaptcha-response"), r.RemoteAddr)
	if err != nil {
		serveErr(ctx, err, w)
		return
	}

	if !success {
		log.Warningf(ctx, "reCAPTCHA check failed")
		failedTmpl.ExecuteTemplate(w, "base", nil)
		return
	}

	sub := Submission{
		URL:       template.URL(strings.TrimSpace(r.FormValue("url"))),
		Submitted: time.Now(),
	}

	if _, err := datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "Submission", nil), &sub); err != nil {
		serveErr(ctx, err, w)
		return
	}

	thanksTmpl.ExecuteTemplate(w, "base", nil)
}
Beispiel #21
0
// linkHandler services requests to short URLs.
//   http://golang.org/s/key
// It consults memcache and datastore for the Link for key.
// It then sends a redirects or an error message.
func linkHandler(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	key := r.URL.Path[len(prefix)+1:]
	if !validKey.MatchString(key) {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	var link Link
	_, err := memcache.JSON.Get(c, cacheKey(key), &link)
	if err != nil {
		k := datastore.NewKey(c, kind, key, 0, nil)
		err = datastore.Get(c, k, &link)
		switch err {
		case datastore.ErrNoSuchEntity:
			http.Error(w, "not found", http.StatusNotFound)
			return
		default: // != nil
			log.Errorf(c, "%q: %v", key, err)
			http.Error(w, "internal server error", http.StatusInternalServerError)
			return
		case nil:
			item := &memcache.Item{
				Key:    cacheKey(key),
				Object: &link,
			}
			if err := memcache.JSON.Set(c, item); err != nil {
				log.Warningf(c, "%q: %v", key, err)
			}
		}
	}

	http.Redirect(w, r, link.Target, http.StatusFound)
}
Beispiel #22
0
func runFunc(c context.Context, w http.ResponseWriter, req *http.Request) {
	defer req.Body.Close()

	var inv invocation
	if err := gob.NewDecoder(req.Body).Decode(&inv); err != nil {
		log.Errorf(c, "delay: failed decoding task payload: %v", err)
		log.Warningf(c, "delay: dropping task")
		return
	}

	f := funcs[inv.Key]
	if f == nil {
		log.Errorf(c, "delay: no func with key %q found", inv.Key)
		log.Warningf(c, "delay: dropping task")
		return
	}

	ft := f.fv.Type()
	in := []reflect.Value{reflect.ValueOf(c)}
	for _, arg := range inv.Args {
		var v reflect.Value
		if arg != nil {
			v = reflect.ValueOf(arg)
		} else {
			// Task was passed a nil argument, so we must construct
			// the zero value for the argument here.
			n := len(in) // we're constructing the nth argument
			var at reflect.Type
			if !ft.IsVariadic() || n < ft.NumIn()-1 {
				at = ft.In(n)
			} else {
				at = ft.In(ft.NumIn() - 1).Elem()
			}
			v = reflect.Zero(at)
		}
		in = append(in, v)
	}
	out := f.fv.Call(in)

	if n := ft.NumOut(); n > 0 && ft.Out(n-1) == errorType {
		if errv := out[n-1]; !errv.IsNil() {
			log.Errorf(c, "delay: func failed (will retry): %v", errv.Interface())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
	}
}
Beispiel #23
0
func failAndLog(ctx context.Context, w http.ResponseWriter, code int, format string, args ...interface{}) {
	if code >= 500 {
		log.Errorf(ctx, format, args...)
	} else {
		log.Warningf(ctx, format, args...)
	}
	http.Error(w, fmt.Sprintf(format, args...), code)
}
Beispiel #24
0
Datei: get.go Projekt: robsix/rps
func loadDatastore(c context.Context, cacheItems []cacheItem,
	valsType reflect.Type) error {

	keys := make([]*datastore.Key, 0, len(cacheItems))
	vals := make([]datastore.PropertyList, 0, len(cacheItems))
	cacheItemsIndex := make([]int, 0, len(cacheItems))

	for i, cacheItem := range cacheItems {
		switch cacheItem.state {
		case internalLock, externalLock:
			keys = append(keys, cacheItem.key)
			vals = append(vals, datastore.PropertyList{})
			cacheItemsIndex = append(cacheItemsIndex, i)
		}
	}

	var me appengine.MultiError
	if err := datastoreGetMulti(c, keys, vals); err == nil {
		me = make(appengine.MultiError, len(keys))
	} else if e, ok := err.(appengine.MultiError); ok {
		me = e
	} else {
		return err
	}

	for i, index := range cacheItemsIndex {
		switch me[i] {
		case nil:
			pl := vals[i]
			val := cacheItems[index].val
			if err := setValue(val, pl); err != nil {
				return err
			}

			if cacheItems[index].state == internalLock {
				cacheItems[index].item.Flags = entityItem
				cacheItems[index].item.Expiration = 0
				if data, err := marshal(pl); err == nil {
					cacheItems[index].item.Value = data
				} else {
					cacheItems[index].state = externalLock
					log.Warningf(c, "nds:loadDatastore marshal %s", err)
				}
			}
		case datastore.ErrNoSuchEntity:
			if cacheItems[index].state == internalLock {
				cacheItems[index].item.Flags = noneItem
				cacheItems[index].item.Expiration = 0
				cacheItems[index].item.Value = []byte{}
			}
			cacheItems[index].err = datastore.ErrNoSuchEntity
		default:
			cacheItems[index].state = externalLock
			cacheItems[index].err = me[i]
		}
	}
	return nil
}
Beispiel #25
0
// auth is there to associate a user with the incoming request.
func auth(h ContextHandlerFunc) ContextHandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) {
		ctx, err = passenger.NewContextFromRequest(ctx, r)
		if err != nil {
			log.Warningf(ctx, "auth: "+err.Error())
		}
		return h(ctx, w, r)
	}
}
Beispiel #26
0
// Handler for adding new question page
func addQuestionHandler(w http.ResponseWriter, r *http.Request, ctx context.Context,
	pageNum int, user stackongo.User) {
	// Parse the html template to serve to the page
	page := getTemplate("addQuestion.html")

	if err := page.Execute(w, queryReply{user, mostRecentUpdate, pageNum, 0, nil}); err != nil {
		log.Warningf(ctx, "%v", err.Error())
	}
}
Beispiel #27
0
Datei: get.go Projekt: robsix/rps
func loadMemcache(c context.Context, cacheItems []cacheItem) {

	memcacheKeys := make([]string, len(cacheItems))
	for i, cacheItem := range cacheItems {
		memcacheKeys[i] = cacheItem.memcacheKey
	}

	items, err := memcacheGetMulti(c, memcacheKeys)
	if err != nil {
		for i := range cacheItems {
			cacheItems[i].state = externalLock
		}
		log.Warningf(c, "nds:loadMemcache GetMulti %s", err)
		return
	}

	for i, memcacheKey := range memcacheKeys {
		if item, ok := items[memcacheKey]; ok {
			switch item.Flags {
			case lockItem:
				cacheItems[i].state = externalLock
			case noneItem:
				cacheItems[i].state = done
				cacheItems[i].err = datastore.ErrNoSuchEntity
			case entityItem:
				pl := datastore.PropertyList{}
				if err := unmarshal(item.Value, &pl); err != nil {
					log.Warningf(c, "nds:loadMemcache unmarshal %s", err)
					cacheItems[i].state = externalLock
					break
				}
				if err := setValue(cacheItems[i].val, pl); err == nil {
					cacheItems[i].state = done
				} else {
					log.Warningf(c, "nds:loadMemcache setValue %s", err)
					cacheItems[i].state = externalLock
				}
			default:
				log.Warningf(c, "nds:loadMemcache unknown item.Flags %d", item.Flags)
				cacheItems[i].state = externalLock
			}
		}
	}
}
Beispiel #28
0
// Function to read all user data filtered by params from the database when a /viewUsers request is made
// Retrieves all users data
func readUsersFromDb(ctx context.Context, params string) map[int]userData {

	tempData := make(map[int]userData)

	var (
		id   sql.NullInt64
		name sql.NullString
		pic  sql.NullString
		link sql.NullString
	)

	query := "SELECT * FROM user"
	if params != "" {
		query += " WHERE " + params
	}
	rows, err := db.Query(query)
	if err != nil {
		if ctx != nil {
			log.Warningf(ctx, "User query failed: %v", err.Error())
		}
		return tempData
	}

	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(&id, &name, &pic, &link)
		if err != nil {
			if ctx != nil {
				log.Warningf(ctx, "User Scan failed: %v", err.Error())
			}
			continue
		}

		currentUser := stackongo.User{
			User_id:       int(id.Int64),
			Display_name:  name.String,
			Profile_image: pic.String,
			Link:          link.String,
		}
		tempData[int(id.Int64)] = newUser(currentUser)
	}

	return tempData
}
Beispiel #29
0
// AhStop terminates all backend instance virtual machines.
func AhStop(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	log.Debugf(c, "Terminating instances ...")
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		if err := echo.Stop(c); err != nil {
			log.Warningf(c, "Error terminating echo vm: %v", err)
		}
	}()
	go func() {
		if err := nginx.Stop(c); err != nil {
			log.Warningf(c, "Error terminating nginx: %v", err)
		}
	}()
	log.Debugf(c, "Waiting for termination to complete...")
	wg.Wait()
	log.Debugf(c, "Instance termination completed")
}
Beispiel #30
0
func notFoundHandler(c context.Context, w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusNotFound)
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	file, err := ioutil.ReadFile("static/notfound.html")
	_, err = w.Write(file)
	if err != nil {
		log.Warningf(c, "[file error] %v", err)
		fmt.Fprintf(w, "Error!")
	}
}