示例#1
0
func handleSearch(w http.ResponseWriter, req *http.Request) {
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	timeout, err := time.ParseDuration(req.FormValue("timeout"))

	if err == nil {
		ctx, cancel = context.WithTimeout(context.Background(), timeout)
	} else {
		ctx, cancel = context.WithCancel(context.Background())
	}

	defer cancel()

	query := req.FormValue("q")

	if query == "" {
		http.Error(w, "no query", http.StatusBadRequest)
		return
	}

	userIP, err := userip.FromRequest(req)

	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	ctx = userip.NewContext(ctx, userIP)

	start := time.Now()
	results, err := google.Search(ctx, query)
	elapsed := time.Since(start)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if err := resultsTemplate.Execute(w, struct {
		Results          google.Results
		Timeout, Elapsed time.Duration
	}{
		Results: results,
		Timeout: timeout,
		Elapsed: elapsed,
	}); err != nil {
		log.Print(err)
		return
	}
}
示例#2
0
// handleSearch handles URLs like /search?q=golang&timeout=1s by forwarding the
// query to google.Search. If the query param includes timeout, the search is
// canceled after that duration elapses.
func handleSearch(w http.ResponseWriter, req *http.Request) {
	// ctx is the Context for this handler. Calling cancel closes the
	// ctx.Done channel, which is the cancellation signal for requests
	// started by this handler.
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)
	timeout, err := time.ParseDuration(req.FormValue("timeout"))
	if err == nil {
		// The request has a timeout, so create a context that is
		// canceled automatically when the timeout expires.
		ctx, cancel = context.WithTimeout(context.Background(), timeout)
	} else {
		ctx, cancel = context.WithCancel(context.Background())
	}
	defer cancel() // Cancel ctx as soon as handleSearch returns.

	// Check the search query.
	query := req.FormValue("q")
	if query == "" {
		http.Error(w, "no query", http.StatusBadRequest)
		return
	}

	// Store the user IP in ctx for use by code in other packages.
	userIP, err := userip.FromRequest(req)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	ctx = userip.NewContext(ctx, userIP)

	// Run the Google search and print the results.
	start := time.Now()
	results, err := google.Search(ctx, query)
	elapsed := time.Since(start)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if err := resultsTemplate.Execute(w, struct {
		Results          google.Results
		Timeout, Elapsed time.Duration
	}{
		Results: results,
		Timeout: timeout,
		Elapsed: elapsed,
	}); err != nil {
		log.Print(err)
		return
	}
}
示例#3
0
// Handle HTTP Request
func handleEvent(w http.ResponseWriter, req *http.Request) {
	log.Println("Handle event")
	userIP, err := userip.FromRequest(req)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// check if IP is requesting too frequently
	if ipBlocker(userIP.String()) {
		http.Error(w, "too many request from "+userIP.String(), http.StatusBadRequest)
		return
	} else {
		ipStore[userIP.String()] = time.Now()
	}

	requrl, _ := url.QueryUnescape(req.FormValue("uri"))
	parsedURI, _ := url.Parse(requrl)

	event := EventStruct{
		Id:        req.FormValue("id"),
		Event:     req.FormValue("event"),
		IP:        userIP.String(),
		URI:       requrl,
		Host:      parsedURI.Host,
		Path:      parsedURI.Path,
		Query:     parsedURI.RawQuery,
		UserAgent: req.UserAgent(),
		Timestamp: time.Now(),
		Action:    req.FormValue("action"),
	}
	if event.Id == "" || event.Event == "" {
		http.Error(w, "no query", http.StatusBadRequest)
		return
	}

	// write back to the user, thus the HTTP(s) request
	// doesn't block anything at client-side
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Write(nil)

	// save Event to all our cool backends / services
	saveEvent(event)
}