Example #1
0
// Default handler
func handler(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	// Load db on first request.
	var err error
	err = nil
	startOnce.Do(func() {
		err = start(c)
	})
	if err != nil {
		startOnce = sync.Once{}
		c.Criticalf("unable to load db:" + err.Error())
	}
	if UpdateAt == nil {
		loadWait.Wait()
	}
	if UpdateAt.Before(time.Now()) && !updating {
		updating = true
		update(c)
		updating = false
	}
	var mac string
	var hw *oui.HardwareAddr

	// Prepare the response and queue sending the result.
	res := &Response{}

	defer func() {
		var j []byte
		var err error
		j, err = res.MarshalJSON()
		if err != nil {
			c.Errorf(err.Error())
		}
		w.Write(j)
	}()

	// Set headers
	w.Header().Set("Cache-Control", "public, max-age=86400") // 86400 = 24*60*60
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Expires", UpdateAt.Format(http.TimeFormat))
	w.Header().Set("Last-Modified", db.Generated().Format(http.TimeFormat))

	mac = r.URL.Query().Get("mac")
	if mac == "" {
		mac = strings.Trim(r.URL.Path, "/")
	}
	hw, err = oui.ParseMac(mac)
	if err != nil {
		res.Error = err.Error() + ". Usage 'http://" + appengine.DefaultVersionHostname(c) + "/AB-CD-EF' (dashes can be colons or omitted)."
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	entry, err := db.LookUp(*hw)
	if err != nil {
		if err == oui.ErrNotFound {
			res.Error = "not found in db"
			w.WriteHeader(http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusInternalServerError)
		res.Error = err.Error()
		return
	}
	res.Data = entry

}
Example #2
0
func main() {
	flag.Parse()
	runtime.GOMAXPROCS(*threads)

	var cron *cronexpr.Expression
	if *update != "" {
		cron = cronexpr.MustParse(*update)
	}

	var db oui.DynamicDB
	url := ""
	fileName := ""
	var err error

	if strings.HasPrefix(*ouiFile, "http") {
		url = *ouiFile
		if url == "http" {
			url = "http://standards-oui.ieee.org/oui.txt"
		}
		log.Println("Downloading new Db from: " + url)
		db, err = oui.OpenHttp(url)
		if err != nil {
			log.Fatalf("Error downloading:%s", err.Error())
		}
	} else {
		fileName = *ouiFile
		log.Println("Opening database from: " + fileName)
		db, err = oui.OpenFile(fileName)
		if err != nil {
			log.Fatalf("Error updating file:%s", err.Error())
		}
	}
	log.Printf("Database generated at %s\n", db.Generated().Local().String())

	// Start updater if needed.
	if cron != nil {
		go func() {
			for {
				// Sleep until next update
				next := cron.Next(time.Now())
				log.Println("Next update: " + next.String())
				time.Sleep(next.Sub(time.Now()))
				if url != "" {
					log.Println("Updating db from: " + url)
					err := oui.UpdateHttp(db, url)
					if err != nil {
						log.Printf("Error downloading update:%s", err.Error())
					} else {
						log.Println("Updated Successfully")
					}
				} else {
					log.Println("Updating db with file: " + fileName)
					err := oui.UpdateFile(db, fileName)
					if err != nil {
						log.Printf("Error loading update:%s", err.Error())
					} else {
						log.Println("Updated Successfully")
					}
				}
			}
		}()
	}

	// We dereference this to avoid a pretty big penalty under heavy load.
	prettyL := *pretty

	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		var mac string
		var hw *oui.HardwareAddr

		// Prepare the response and queue sending the result.
		res := &Response{}

		defer func() {
			var j []byte
			var err error
			if prettyL {
				j, err = json.MarshalIndent(res, "", "  ")
			} else {
				j, err = res.MarshalJSON()
			}
			if err != nil {
				log.Fatal(err)
			}
			w.Write(j)
		}()

		// Set headers
		if *originPolicy != "" {
			w.Header().Set("Access-Control-Allow-Origin", *originPolicy)
		}
		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("Last-Modified", db.Generated().Format(http.TimeFormat))

		// Find Mac
		mac = req.URL.Query().Get("mac")
		if mac == "" {
			mac = strings.Trim(req.URL.Path, "/")
		}
		hw, err := oui.ParseMac(mac)
		if err != nil {
			res.Error = err.Error()
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		entry, err := db.LookUp(*hw)
		if err != nil {
			if err == oui.ErrNotFound {
				res.Error = "not found in db"
				w.WriteHeader(http.StatusNotFound)
				return
			}
			w.WriteHeader(http.StatusInternalServerError)
			res.Error = err.Error()
			return
		}
		res.Data = entry
	})

	log.Println("Listening on " + *listen)
	log.Fatal(http.ListenAndServe(*listen, nil))
}