예제 #1
13
//download image from town
func (t *Townparser) downloadImage(url string, name string) error {
	defer func() {
		if err := recover(); err != nil {
			log.Info("%s recovered from panic", TAG)
			return
		}
	}()
	if url == "0" {
		return nil
	}
	exist, err := exists("templates/static/images/" + name + ".jpg")
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
	}

	if !exist {
		resp, err := t.Tc.Get(url)
		if err != nil {
			log.Error("%s image download failed, name: %v, url: %v", TAG, name, url)
			log.Error("%s %s", TAG, err.Error())
			return err
		}
		defer resp.Body.Close()
		if strings.Contains(url, "jpg") || strings.Contains(url, "jpeg") {
			img, _ := jpeg.Decode(resp.Body)
			m := resize.Resize(300, 0, img, resize.Lanczos2Lut)
			out, err := os.Create("templates/static/images/" + name + ".jpg")
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
				return nil
			}

			// write new image to file
			jpeg.Encode(out, m, nil)
			out.Close()
		} else if strings.Contains(url, "png") {
			img, err := png.Decode(resp.Body)
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
			}
			m := resize.Resize(300, 0, img, resize.Lanczos2Lut)
			out, err := os.Create("templates/static/images/" + name + ".png")
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
				return nil
			}

			// write new image to file
			jpeg.Encode(out, m, nil)
			out.Close()
		}
	}
	time.Sleep(200 * time.Millisecond)
	return nil
}
예제 #2
0
//http get to the given ressource
func (t *Townclient) Get(sUrl string) (*http.Response, error) {
	if strings.Contains(sUrl, "jpg") || strings.Contains(sUrl, "png") || strings.Contains(sUrl, "gif") || strings.Contains(sUrl, "jpeg") {
	} else {
		log.Info("%s[GET] url: %v", TAG, sUrl)
	}

	client := &http.Client{}
	req, err := http.NewRequest("GET", sUrl, nil)
	if err != nil {
		log.Error("%s couldn't create Request to: %v", TAG, sUrl)
		return nil, err
	}

	t.addHeader(req)

	if t.cookies != nil {
		for _, cookie := range t.cookies {
			req.AddCookie(cookie)
		}
	}

	time1 := time.Now()
	t.dumpRequest(req, "town_get_req_"+strconv.Itoa(time1.Nanosecond()))

	//connect to sUrl
	resp, err := client.Do(req)
	if err != nil {
		log.Error("%s couldn't connect to: %v", TAG, sUrl)
		return nil, err
	}

	t.dumpResponse(resp, "town_get_resp_"+strconv.Itoa(time1.Nanosecond()))

	return resp, nil
}
예제 #3
0
파일: config.go 프로젝트: sguzwf/vertex
func ReadConfigs() error {

	if err := autoflag.Load(gofigure.DefaultLoader, &Config); err != nil {
		logging.Error("Error loading configs: %v", err)
		return err
	}
	logging.Info("Read configs: %#v", &Config)

	for k, m := range Config.APIConfigs {

		if conf, found := Config.apiconfs[k]; found && conf != nil {

			b, err := yaml.Marshal(m)
			if err == nil {

				if err := yaml.Unmarshal(b, conf); err != nil {
					logging.Error("Error reading config for API %s: %s", k, err)
				} else {
					logging.Debug("Unmarshaled API config for %s: %#v", k, conf)
				}

			} else {

				logging.Error("Error marshalling config for API %s: %s", k, err)

			}
		} else {
			logging.Warning("API Section %s in config file not registered with server", k)
		}

	}

	return nil

}
예제 #4
0
func (t *Townmanager) Start() {
	t.page = 1
	t.end = false

	tc := &Townclient{}
	tc.User = t.User
	tc.Password = t.Password

	err := t.init(tc)
	log.Info("%s init finished, starting to parse...", TAG)
	if err != nil {
		log.Error("%s init failed", TAG)
		log.Error("%s %s", TAG, err.Error())
		return
	}

	tp := &Townparser{Url: t.url, Tc: tc}

	count, err := tp.ParsePageCount()
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return
	}
	t.maxpage = count
	log.Info("%s crawling approximately %v pages", TAG, t.maxpage)
	t.saveReleases(tp.Rel)

	i := 1
	for {
		if i == 1 {
			err = tp.ParseReleases(false)
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
				break
			}
		} else {
			tp = nil
			tp = &Townparser{Url: t.url + "&pp=25&page=" + strconv.Itoa(i), Tc: tc}
			err = tp.ParseReleases(true)
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
				break
			}
		}
		log.Info("%s crawled page %v/%v", TAG, i, t.maxpage)
		t.saveReleases(tp.Rel)
		time.Sleep(5 * time.Second)
		i++
		if i == t.maxpage+1 {
			break
		}
		if t.end {
			log.Info("%s found old end point", TAG)
			break
		}
	}
	log.Info("%s parser closing", TAG)

}
예제 #5
0
파일: runner.go 프로젝트: Bootz/nzbcrawler
func (r *Runner) Start() {
	go func() {
		timeout := time.Second * 1
		for {
			select {
			case <-time.After(timeout):
				if !r.checkTown() {
					timeout = time.Minute * 5
					log.Info("town: trying login again in %v minute", timeout)
				} else {
					tm := town.Townmanager{User: r.Server.Config2.TownName, Password: r.Server.Config2.TownPassword, DB: r.Server.RelDB}
					go tm.Start()
					dur, err := time.ParseDuration(r.Server.Config2.Timeout)
					if err != nil {
						log.Error(err.Error())
					}
					c := time.Tick(dur)
					for _ = range c {
						log.Info("tick start town")
						go tm.Start()
					}
				}
			}
			break
		}
		return
	}()
	go func() {
		timeout := time.Second * 2
		for {
			select {
			case <-time.After(timeout):
				if !r.checkTown() {
					timeout = time.Minute * 5
					log.Info("ghost: trying to login again in %v minute", timeout)
				} else {
					gm := ghost.Ghostmanager{User: r.Server.Config2.GhostName, Password: r.Server.Config2.GhostPassword, DB: r.Server.RelDB}
					go gm.Start()
					dur, err := time.ParseDuration(r.Server.Config2.Timeout)
					if err != nil {
						log.Error(err.Error())
					}
					c := time.Tick(dur)
					for _ = range c {
						log.Info("tick start ghost")
						go gm.Start()
					}
				}
			}
			break
		}
		return
	}()
}
예제 #6
0
func (g *Ghostmanager) Start() {

	g.end = false

	gc := &Ghostclient{}
	gc.User = g.User
	gc.Password = g.Password

	err := g.init(gc)
	log.Info("%s init finished, starting to parse...", TAG)
	if err != nil {
		log.Error("%s init failed", TAG)
		log.Error("%s %s", TAG, err.Error())
		return
	}

	tp := &Ghostparser{Url: g.url, Gc: gc}

	i := 1
	for {
		if i == 1 {
			err = tp.ParseReleases()
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
				break
			}
			g.maxpage = tp.Count
			log.Info("%s crawling approximately %v pages", TAG, g.maxpage)
		} else {
			tp = nil
			tp = &Ghostparser{Url: g.url + "&page=" + strconv.Itoa(i), Gc: gc}
			err = tp.ParseReleases()
			if err != nil {
				log.Error("%s %s", TAG, err.Error())
				break
			}
		}
		g.saveReleases(tp.Rel)
		log.Info("%s crawled page %v/%v", TAG, i, g.maxpage)
		time.Sleep(5 * time.Second)
		i++
		if i == g.maxpage+1 {
			break
		}
		if g.end {
			log.Info("%s found old end point", TAG)
			break
		}
	}
	log.Info("%s closing", TAG)
}
예제 #7
0
파일: server.go 프로젝트: Bootz/nzbcrawler
func GetLogs(server *Server, parms martini.Params) string {
	offset, _ := strconv.Atoi(parms["offset"])

	var all []mydb.Log
	_, err := server.LogDB.Select(&all, "select * from log ORDER BY id DESC LIMIT 50 OFFSET ?", offset)
	if err != nil {
		log.Error(err.Error())
	}
	by, err := json.Marshal(all)
	if err != nil {
		log.Error(err.Error())
	}

	return string(by)

}
예제 #8
0
파일: vertex.go 프로젝트: sguzwf/vertex
// Parse the user input into a request handler struct, with input validation
func parseInput(r *http.Request, input interface{}, validator *RequestValidator) error {

	schemaDecoder.IgnoreUnknownKeys(true)

	if err := r.ParseForm(); err != nil {
		return InvalidRequestError("Error parsing request data: %s", err)
	}

	// We do not map and validate input to non-struct handlers
	if reflect.TypeOf(input).Kind() != reflect.Func {

		if err := schemaDecoder.Decode(input, r.Form); err != nil {
			return InvalidRequestError("Error decoding schema: %s", err)
		}

		// Validate the input based on the API spec
		if err := validator.Validate(input, r); err != nil {
			logging.Error("Error validating http.Request!: %s", err)
			return NewError(err)

		}

	}

	return nil

}
예제 #9
0
파일: validate.go 프로젝트: sguzwf/vertex
func (rv *RequestValidator) Validate(request interface{}, r *http.Request) error {

	val := reflect.ValueOf(request)
	if val.Kind() == reflect.Ptr {
		val = val.Elem()
	}

	//go over all the validators
	for _, v := range rv.fieldValidators {

		// find the field in the struct. we assume it's there since we build the validators on start time
		field := val.FieldByName(v.GetKey())

		// if the arg is optional and not set, we set the default
		if v.IsOptional() && (!field.IsValid() || r.FormValue(v.GetParamName()) == "") {
			def, ok := v.GetDefault()
			if ok {
				logging.Info("Default value for %s: %v", v.GetKey(), def)
				field.Set(reflect.ValueOf(def).Convert(field.Type()))
			}
		}

		// now we validate!
		e := v.Validate(field, r)

		if e != nil {
			logging.Error("Could not validate field %s: %s", v.GetParamName(), e)
			return e
		}

	}

	return nil
}
예제 #10
0
func (t *Townclient) getSValue() (sValue string) {
	log.Info("%s getting sValue for town login", TAG)
	sValue = ""
	var doc *goquery.Document
	var e error
	log.Info("%s[GET] url: %v", TAG, ROOT)
	if doc, e = goquery.NewDocument(ROOT); e != nil {
		log.Error("%s %s", TAG, e.Error())
		return
	}

	doc.Find("input").Each(func(i int, s *goquery.Selection) {
		attr, exists := s.Attr("name")
		if exists == true {
			if attr == "s" {
				bla, exists := s.Attr("value")
				if exists == true {
					sValue = bla
				}
			}
		}

	})
	log.Info("%s sValue: %v", TAG, sValue)
	return sValue
}
예제 #11
0
파일: server.go 프로젝트: Bootz/nzbcrawler
func SetRating(server *Server, parms martini.Params) string {
	checksum := parms["checksum"]
	score, _ := strconv.Atoi(parms["score"])

	rating, err := server.RelDB.SelectInt("select rating from release where checksum=?", checksum)
	if err != nil {
		log.Error(err.Error())
	}
	oldrating := rating
	rating += int64(score)
	log.Info("changing score for %s from %v to %v", checksum, oldrating, rating)
	_, err = server.RelDB.Exec("update release set rating=? where checksum=?", rating, checksum)
	if err != nil {
		log.Error(err.Error())
	}

	return fmt.Sprintf("%v %v", checksum, score)
}
예제 #12
0
파일: server.go 프로젝트: Bootz/nzbcrawler
func LinkFollow(w http.ResponseWriter, r *http.Request, server *Server, parms martini.Params) {
	checksum := parms["checksum"]

	hits, err := server.RelDB.SelectInt("select hits from release where checksum=?", checksum)
	if err != nil {
		log.Error(err.Error())
	}

	oldhits := hits
	hits += 1
	log.Info("increasing hits for %s from %v to %v", checksum, oldhits, hits)
	_, err = server.RelDB.Exec("update release set hits=? where checksum=?", hits, checksum)
	if err != nil {
		log.Error(err.Error())
	}

	url, err := server.RelDB.SelectStr("select url from release where checksum=?", checksum)
	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
예제 #13
0
파일: oauth.go 프로젝트: sguzwf/vertex
func (j *JWTAuthenticator) EncodeToken(data interface{}) (string, error) {
	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims["data"] = data

	sstr, err := token.SignedString(j.key)
	if err != nil {
		logging.Error("Error signing token: %s", err)

	}
	return sstr, err
}
예제 #14
0
func (g *Ghostparser) getBoardId(str string) int {
	regex, err := regexp.Compile("boardid=.+&")
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return -1
	}

	str = regex.FindString(str)
	str = strings.Replace(str, "&", "", -1)
	astr := strings.Split(str, "=")
	if len(astr) < 2 {
		return -1
	}
	i, err := strconv.Atoi(astr[1])
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return -1
	}
	return i
}
예제 #15
0
파일: api.go 프로젝트: sguzwf/vertex
// configure registers the API's routes on a router. If the passed router is nil, we create a new one and return it.
// The nil mode is used when an API is run in stand-alone mode.
func (a *API) configure(router *httprouter.Router) *httprouter.Router {

	if router == nil {
		router = httprouter.New()
	}

	for i, route := range a.Routes {

		if err := route.parseInfo(route.Path); err != nil {
			logging.Error("Error parsing info for %s: %s", route.Path, err)
		}
		a.Routes[i] = route
		h := a.handler(route)

		pth := a.FullPath(route.Path)

		if route.Methods&GET == GET {
			logging.Info("Registering GET handler %v to path %s", h, pth)
			router.Handle("GET", pth, h)
		}
		if route.Methods&POST == POST {
			logging.Info("Registering POST handler %v to path %s", h, pth)
			router.Handle("POST", pth, h)

		}

	}

	chain := buildChain(a.SwaggerMiddleware...)
	if chain == nil {
		chain = buildChain(a.swaggerHandler())
	} else {
		chain.append(a.swaggerHandler())
	}

	// Server the API documentation swagger
	router.GET(a.FullPath("/swagger"), a.middlewareHandler(chain, nil, nil))

	chain = buildChain(a.TestMiddleware...)
	if chain == nil {
		chain = buildChain(a.testHandler())
	} else {
		chain.append(a.testHandler())
	}

	router.GET(path.Join("/test", a.root(), ":category"), a.middlewareHandler(chain, nil, nil))

	// Redirect /$api/$version/console => /console?url=/$api/$version/swagger
	uiPath := fmt.Sprintf("/console?url=%s", url.QueryEscape(a.FullPath("/swagger")))
	router.Handler("GET", a.FullPath("/console"), http.RedirectHandler(uiPath, 301))

	return router

}
예제 #16
0
파일: api.go 프로젝트: sguzwf/vertex
func (a *API) middlewareHandler(chain *step, security SecurityScheme, renderer Renderer) func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	// allow overriding the API's default renderer with a per-route one
	if renderer == nil {
		renderer = a.Renderer
	}

	return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

		req := NewRequest(r)

		if !a.AllowInsecure && !req.Secure {
			// local requests bypass security
			if req.RemoteIP != "127.0.0.1" {
				http.Error(w, insecureAccessMessage, http.StatusForbidden)
				return
			}
		}

		r.ParseForm()
		// Copy values from the router params to the request params
		for _, v := range p {
			r.Form.Set(v.Key, v.Value)
		}

		var ret interface{}
		var err error

		if security != nil {
			if err = security.Validate(req); err != nil {
				logging.Warning("Error validating security scheme: %s", err)

				if e, ok := err.(*internalError); ok {
					e.Code = ErrUnauthorized
					err = e
				}
			}
		}
		if err == nil {
			ret, err = chain.handle(w, req)
		}

		if err != Hijacked {

			if err = renderer.Render(ret, err, w, req); err != nil {
				logging.Error("Error rendering response: %s", err)
			}
		} else {
			logging.Debug("Not rendering hijacked request %s", r.RequestURI)
		}

	}

}
예제 #17
0
func (g *Ghostmanager) saveReleases(releases []Release) {
	for _, rel := range releases {
		err := g.DB.Insert(&town.Release{Name: rel.Name, Checksum: rel.Checksum, Rating: rel.Rating, Hits: rel.Hits, Time: rel.Time, Url: rel.Url, Tag: rel.Tag})
		if err != nil {
			switch err.(type) {
			case *sqlite3.Error:
				if err.(*sqlite3.Error).Code() == 2067 {
					g.end = true
					break
				} else {
					log.Error("%s %s", TAG, err.Error())
				}
			default:
				log.Error("%s %s", TAG, err.Error())
			}
		} else {
			log.Info("%s saved %v", TAG, rel.Name)
		}
	}

}
예제 #18
0
func (t *Townmanager) saveReleases(releases []Release) {
	for _, rel := range releases {
		err := t.DB.Insert(&rel)
		if err != nil {
			switch err.(type) {
			case *sqlite3.Error:
				if err.(*sqlite3.Error).Code() == 2067 {
					t.end = true
					break
				} else {
					log.Error("%s %s", TAG, err.Error())
				}
			default:
				log.Error("%s %s", TAG, err.Error())
			}
		} else {
			log.Info("%s saved %v", TAG, rel.Name)
		}
	}

}
예제 #19
0
//http get to the given ressource
func (g *Ghostclient) Get(sUrl string) (*http.Response, error) {
	if strings.Contains(sUrl, "jpg") || strings.Contains(sUrl, "png") || strings.Contains(sUrl, "gif") {
	} else {
		log.Info("%s[GET] url: %v", TAG, sUrl)
	}
	client := &http.Client{}
	req, err := http.NewRequest("GET", sUrl, nil)
	if err != nil {
		log.Error("%s couldn't create Request to: %v", TAG, sUrl)
		return nil, err
	}

	req.Header.Add("Accept", "text/html, application/xhtml+xml, */*")
	req.Header.Add("Referer", "http://ghost-of-usenet.org/index.php")
	req.Header.Add("Accept-Language", "de-DE")
	req.Header.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)")
	req.Header.Add("Accept-Encoding", "gzip, deflate")
	req.Header.Add("Host", "ghost-of-usenet.org")
	req.Header.Add("Connection", "Keep-Alive")

	if g.cookies != nil {
		for _, cookie := range g.cookies {
			req.AddCookie(cookie)
		}
	}

	time1 := time.Now()
	g.dumpRequest(req, "ghost_get_req_"+strconv.Itoa(time1.Nanosecond()))

	//connect to sUrl
	resp, err := client.Do(req)
	if err != nil {
		log.Error("%s couldn't connect to: %v", TAG, sUrl)
		return nil, err
	}

	g.dumpResponse(resp, "ghost_get_resp_"+strconv.Itoa(time1.Nanosecond()))

	return resp, nil
}
예제 #20
0
파일: render.go 프로젝트: sguzwf/vertex
//serialize an error string inside an object
func writeError(w http.ResponseWriter, message string) {

	//WriteError is called from recovery, so it must be panic proof
	defer func() {
		e := recover()
		if e != nil {
			logging.Error("Could not write error response! %s", e)
		}
	}()

	http.Error(w, message, http.StatusInternalServerError)

}
예제 #21
0
func (t *Townmanager) init(tc *Townclient) error {
	//login to get cookies
	err := tc.Login()
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return err
	}

	time.Sleep(1000 * time.Millisecond)

	url, err := tc.GetDailyUrl()
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return err
	}

	t.url = url

	time.Sleep(200 * time.Millisecond)

	return nil
}
예제 #22
0
func (g *Ghostmanager) init(gc *Ghostclient) error {

	//login to get cookies
	err := gc.Login()
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return err
	}

	time.Sleep(1000 * time.Millisecond)

	url, err := gc.GetDailyUrl()
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return err
	}

	g.url = url

	time.Sleep(200 * time.Millisecond)

	return nil
}
예제 #23
0
//parse the http resp from Townclient
func (g *Ghostparser) ParseReleases() error {
	log.Info("%s parsing %v", TAG, g.Url)

	resp, err := g.Gc.Get(g.Url)
	if err != nil {
		log.Error("%s %s", TAG, err.Error())
		return err
	}
	defer resp.Body.Close()

	respbody, err := html.Parse(resp.Body)
	doc := goquery.NewDocumentFromNode(respbody)

	var rel Release
	doc.Find("table").Each(func(a int, sa *goquery.Selection) {
		if a == 10 { //get the right table
			sa.Find("tr").Each(func(b int, sb *goquery.Selection) {
				sb.Find("td").Each(func(c int, sc *goquery.Selection) {
					if c == 2 {
						rel = Release{}
						g.getUrlAndTagAndName(&rel, sc)

						if rel.Name != "" {
							rel.Time = time.Now().Unix()
							rel.Checksum = g.encodeName(rel.Url)
							rel.checkQual()
							if rel.Name != "" {
								rel.Hits = 0
								rel.Rating = 0
								g.downloadImage(rel.Url, rel.Checksum)
								g.addRelease(rel)
							}
						}
					}
				})
			})
		}
		if g.Count == 0 { //get page count
			if a == 51 {
				sa.Find("a").Each(func(d int, sd *goquery.Selection) {
					if d == 3 {
						g.Count, err = strconv.Atoi(sd.Text())
					}
				})
			}
		}
	})

	return nil
}
예제 #24
0
파일: parse.go 프로젝트: sguzwf/vertex
// parseDefault takes the default string of a paramInfo and parses it according to the param's type
func parseDefault(val string, t reflect.Kind) (interface{}, bool) {

	if val == "" {
		return nil, false
	}

	switch t {
	case reflect.Int, reflect.Int32, reflect.Int16, reflect.Int64:
		if i, err := parseInt(val); err == nil {
			return i, true
		} else {
			logging.Error("Error parsing int default '%s': %s", val, err)
		}
	case reflect.Float32, reflect.Float64:
		if f, err := parseFloat(val); err == nil {
			return f, true
		} else {
			logging.Error("Error parsing float default '%s': %s", val, err)
		}
	case reflect.String:
		return val, true
	case reflect.Bool:
		if b, err := parseBool(val); err == nil {
			return b, true
		} else {
			logging.Error("Error parsing bool default '%s': %s", val, err)
		}
	case reflect.Slice:
		if l, err := parseList(val); err == nil {
			return l, true
		} else {
			logging.Error("Error parsing string list '%s': %s", val, err)
		}
	}

	return nil, false
}
예제 #25
0
파일: server.go 프로젝트: Bootz/nzbcrawler
func GetReleaseWithTagAndName(server *Server, parms martini.Params) string {
	offset := parms["offset"]
	tags := parms["tags"]
	name := parms["name"]
	command := ""
	if tags == "none" && name != "none" {
		command = "select * from release where name LIKE '%" + name + "%' ORDER BY time DESC LIMIT 200 OFFSET " + offset
	} else if name == "none" && tags != "none" {
		cb := &CMDBuilder{}
		command = cb.Tokenize(tags)
		command += " ORDER BY time DESC LIMIT 200 OFFSET " + offset
	} else if name != "none" && tags != "none" {
		cb := &CMDBuilder{}
		command = cb.Tokenize(tags)
		command += "AND name LIKE '%" + name + "%' ORDER BY time DESC LIMIT 200 OFFSET " + offset
	}

	var b []town.Release

	if command != "" {
		_, err := server.RelDB.Select(&b, command)
		if err != nil {
			log.Error(err.Error())
		}
	} else {
		_, err := server.RelDB.Select(&b, "select * from release ORDER BY time DESC LIMIT 200 OFFSET ?", offset)
		if err != nil {
			log.Error(err.Error())
		}
	}
	by, err := json.Marshal(b)
	if err != nil {
		log.Error(err.Error())
	}

	return string(by)
}
예제 #26
0
파일: api.go 프로젝트: sguzwf/vertex
// return an httprouter compliant handler function for a route
func (a *API) handler(route Route) func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	// extract the handler type to create a reflect based factory for it
	T := reflect.TypeOf(route.Handler)
	if T.Kind() == reflect.Ptr {
		T = T.Elem()
	}

	validator := NewRequestValidator(route.requestInfo)

	security := route.Security
	if security == nil {
		security = a.DefaultSecurityScheme
	}

	// Build the middleware chain for the API middleware and the rout middleware.
	// The route middleware comes after the API middleware
	chain := buildChain(append(a.Middleware, route.Middleware...)...)

	// add the handler itself as the final middleware
	handlerMW := MiddlewareFunc(func(w http.ResponseWriter, r *Request, next HandlerFunc) (interface{}, error) {

		var reqHandler RequestHandler
		if T.Kind() == reflect.Struct {
			// create a new request handler instance
			reqHandler = reflect.New(T).Interface().(RequestHandler)
		} else {
			reqHandler = route.Handler
		}

		//read params
		if err := parseInput(r.Request, reqHandler, validator); err != nil {
			logging.Error("Error reading input: %s", err)
			return nil, NewError(err)
		}

		return reqHandler.Handle(w, r)
	})

	if chain == nil {
		chain = &step{
			mw: handlerMW,
		}
	} else {
		chain.append(handlerMW)
	}

	return a.middlewareHandler(chain, security, route.Renderer)
}
예제 #27
0
파일: validate.go 프로젝트: sguzwf/vertex
// Create new request validator for a request handler interface.
// This function walks the struct tags of the handler's fields and extracts validation metadata.
//
// You should give it the reflect type of your request handler struct
func NewRequestValidator(ri schema.RequestInfo) *RequestValidator {

	//if the user passes a pointer we walk the actual struct

	ret := &RequestValidator{
		fieldValidators: make([]validator, 0),
	}

	//iterate over the fields and create a validator for each
	for _, pi := range ri.Params {

		var vali validator
		switch pi.Kind {
		//		case reflect.Struct:

		//			//for structs - we add validators recursively
		//			validator := NewRequestValidator(field.Type)
		//			if validator != nil && len(validator.fieldValidators) > 0 {
		//				ret.fieldValidators = append(ret.fieldValidators, validator.fieldValidators...)
		//			}
		//			continue

		case reflect.String:
			vali = newStringValidator(pi)

		case reflect.Int, reflect.Int32, reflect.Int64:
			vali = newIntValidator(pi)

		case reflect.Float32, reflect.Float64:
			vali = newFloatValidator(pi)
		case reflect.Bool:
			vali = newBoolValidator(pi)
		default:
			logging.Error("I don't know how to validate %s", pi.Kind)
			continue
		}

		if vali != nil {
			logging.Debug("Adding validator %v to request validator %v", vali, ri)
			ret.fieldValidators = append(ret.fieldValidators, vali)
		}

	}

	return ret
}
예제 #28
0
파일: error.go 프로젝트: sguzwf/vertex
// ErrorString converts an error code to a user "friendly" string
func httpError(err error) (re int, rm string) {

	if err == nil {
		return http.StatusOK, http.StatusText(http.StatusOK)
	}

	incidentId := uuid.New()
	if err != Hijacked {
		logging.Error("[%s] Error processing request: %s", incidentId, err)
	}

	statusFunc := func(i int) (int, string) {
		return i, fmt.Sprintf("[%s] %s", incidentId, http.StatusText(i))
	}

	if e, ok := err.(*internalError); !ok {
		return statusFunc(http.StatusInternalServerError)
	} else {

		switch e.Code {
		case Ok:
			return http.StatusOK, "OK"
		case ErrHijacked:
			return http.StatusOK, "Request Hijacked By Handler"
		case ErrInvalidRequest:
			return statusFunc(http.StatusBadRequest)
		case ErrInvalidParam, ErrMissingParam:
			return http.StatusBadRequest, e.Message
		case ErrUnauthorized:
			return statusFunc(http.StatusUnauthorized)
		case ErrInsecureAccessDenied:
			return statusFunc(http.StatusForbidden)
		case ErrResourceUnavailable:
			return statusFunc(http.StatusServiceUnavailable)
		case ErrBackOff:
			return statusFunc(http.StatusServiceUnavailable)
		case ErrGeneralFailure:
			fallthrough
		default:
			return statusFunc(http.StatusInternalServerError)

		}
	}

}
예제 #29
0
파일: testing.go 프로젝트: sguzwf/vertex
// invokeTest runs a tester and prints the output
func (t *testRunner) invokeTest(path string, tc Tester) *testResult {

	if t.shouldRun(tc) {

		var result testResult
		if tc == nil || t.shouldRun(tc) {
			result = t.runTest(tc, path)
			logging.Info("Test result for %s: %#v", path, result)
			if err := t.formatter.format(result); err != nil {
				logging.Error("Error running formatter: %s", err)
			}
			return &result
		}

	}

	return nil
}
예제 #30
0
파일: ip_limit.go 프로젝트: sguzwf/vertex
// Deny denies traffic from the given CIDRs (e.g. 127.0.0.0/8 for local addresses)
func (f *IPRangeFilter) Deny(cidrs ...string) *IPRangeFilter {
	f.denied = make([]*net.IPNet, 0, len(cidrs))

	for _, addr := range cidrs {
		if ip := net.ParseIP(addr); ip != nil {
			addr = addr + "/32"

		}
		_, ipnet, err := net.ParseCIDR(addr)
		if err != nil {
			logging.Error("Error parsing CIDR: %s", err)
			continue
		}
		f.denied = append(f.denied, ipnet)

	}
	return f
}