Пример #1
1
func HandleTest(ctx *fasthttp.RequestCtx) {
	reader, err := os.Open("../testimages/loadimage/test.jpg")
	if err != nil {
		return
	}
	// Remember to free resources after you're done
	defer reader.Close()

	buffer := bytes.NewBuffer([]byte{})
	buffer.ReadFrom(reader)
	blob := buffer.Bytes()

	ctx.Write(blob)
}
Пример #2
0
func (rp *FastReverseProxy) serveWebsocket(dstHost string, reqData *RequestData, ctx *fasthttp.RequestCtx) {
	req := &ctx.Request
	uri := req.URI()
	uri.SetHost(dstHost)
	dstConn, err := rp.dialFunc(dstHost)
	if err != nil {
		log.LogError(reqData.String(), string(uri.Path()), err)
		return
	}
	if clientIP, _, err := net.SplitHostPort(ctx.RemoteAddr().String()); err == nil {
		if prior := string(req.Header.Peek("X-Forwarded-For")); len(prior) > 0 {
			clientIP = prior + ", " + clientIP
		}
		req.Header.Set("X-Forwarded-For", clientIP)
	}
	_, err = req.WriteTo(dstConn)
	if err != nil {
		log.LogError(reqData.String(), string(uri.Path()), err)
		return
	}
	ctx.Hijack(func(conn net.Conn) {
		defer dstConn.Close()
		defer conn.Close()
		errc := make(chan error, 2)
		cp := func(dst io.Writer, src io.Reader) {
			_, err := io.Copy(dst, src)
			errc <- err
		}
		go cp(dstConn, conn)
		go cp(conn, dstConn)
		<-errc
	})
}
Пример #3
0
// ExpvarHandler dumps json representation of expvars to http response.
//
// Expvars may be filtered by regexp provided via 'r' query argument.
//
// See https://golang.org/pkg/expvar/ for details.
func ExpvarHandler(ctx *fasthttp.RequestCtx) {
	expvarHandlerCalls.Add(1)

	ctx.Response.Reset()

	r, err := getExpvarRegexp(ctx)
	if err != nil {
		expvarRegexpErrors.Add(1)
		fmt.Fprintf(ctx, "Error when obtaining expvar regexp: %s", err)
		ctx.SetStatusCode(fasthttp.StatusBadRequest)
		return
	}

	fmt.Fprintf(ctx, "{\n")
	first := true
	expvar.Do(func(kv expvar.KeyValue) {
		if r.MatchString(kv.Key) {
			if !first {
				fmt.Fprintf(ctx, ",\n")
			}
			first = false
			fmt.Fprintf(ctx, "\t%q: %s", kv.Key, kv.Value)
		}
	})
	fmt.Fprintf(ctx, "\n}\n")

	ctx.SetContentType("application/json; charset=utf-8")
}
Пример #4
0
// SetPost is the API method for creating a new post.
func SetPost(ctx *fasthttp.RequestCtx, _ fasthttprouter.Params) {
	v := &struct {
		Title string
		Body  string
	}{}
	err := json.Unmarshal(ctx.PostBody(), v)
	if err != nil {
		ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
		return
	}
	p := model.NewPost(v.Title, v.Body)
	id, err := p.Set(s)
	if err != nil {
		ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
		return
	}
	ctx.Response.Header.Set("Content-Type", "application/json")
	resp, err := json.MarshalIndent(map[string]string{
		"id": string(id),
	}, "", "  ")
	if err != nil {
		ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
	}
	ctx.Write(resp)
}
Пример #5
0
// RoundTrip implements http.RoundTripper.RoundTrip.
func (binder FastBinder) RoundTrip(stdreq *http.Request) (*http.Response, error) {
	var fastreq fasthttp.Request

	convertRequest(stdreq, &fastreq)

	var ctx fasthttp.RequestCtx

	ctx.Init(&fastreq, nil, nil)

	if stdreq.ContentLength >= 0 {
		ctx.Request.Header.SetContentLength(int(stdreq.ContentLength))
	} else {
		ctx.Request.Header.Add("Transfer-Encoding", "chunked")
	}

	if stdreq.Body != nil {
		b, err := ioutil.ReadAll(stdreq.Body)
		if err == nil {
			ctx.Request.SetBody(b)
		}
	}

	binder.handler(&ctx)

	return convertResponse(stdreq, &ctx.Response), nil
}
Пример #6
0
// NewRequest returns `Request` instance.
func NewRequest(c *fasthttp.RequestCtx, l *log.Logger) *Request {
	return &Request{
		RequestCtx: c,
		url:        &URL{URI: c.URI()},
		header:     &RequestHeader{RequestHeader: &c.Request.Header},
		logger:     l,
	}
}
Пример #7
0
func TestRequest(t *testing.T) {
	ctx := new(fast.RequestCtx)
	url, _ := url.Parse("http://github.com/labstack/echo")
	ctx.Init(&fast.Request{}, fakeAddr{addr: "127.0.0.1"}, nil)
	ctx.Request.Read(bufio.NewReader(bytes.NewBufferString(test.MultipartRequest)))
	ctx.Request.SetRequestURI(url.String())
	test.RequestTest(t, NewRequest(ctx, log.New("echo")))
}
Пример #8
0
// ClientFormFastHandler 客户端表单信息(基于fasthttp)
func ClientFormFastHandler(ctx *fasthttp.RequestCtx) (clientID, clientSecret string, err error) {
	clientID = string(ctx.FormValue("client_id"))
	clientSecret = string(ctx.FormValue("client_secret"))
	if clientID == "" || clientSecret == "" {
		err = ErrAuthorizationFormInvalid
	}
	return
}
Пример #9
0
func getQueriesCount(ctx *fasthttp.RequestCtx) int {
	n := ctx.QueryArgs().GetUintOrZero("queries")
	if n < 1 {
		n = 1
	} else if n > 500 {
		n = 500
	}
	return n
}
Пример #10
0
// GetPostJSON is the API method for getting a post's JSON.
func GetPostJSON(ctx *fasthttp.RequestCtx, ps fasthttprouter.Params) {
	id := ps.ByName("id")
	postJSON, err := model.GetJSON([]byte(id), s)
	if err != nil {
		ctx.Error(err.Error(), fasthttp.StatusNotFound)
		return
	}
	ctx.Response.Header.Set("Content-Type", "application/json")
	ctx.Write(postJSON)
}
Пример #11
0
// CheckHost Implement a CheckHost method on our new type
func (hs HostSwitch) CheckHost(ctx *fasthttp.RequestCtx) {
	// Check if a http.Handler is registered for the given host.
	// If yes, use it to handle the request.
	if handler := hs[string(ctx.Host())]; handler != nil {
		handler(ctx)
	} else {
		// Handle host names for wich no handler is registered
		ctx.Error("Forbidden", 403) // Or Redirect?
	}
}
Пример #12
0
// Main request handler
func requestHandler(ctx *fasthttp.RequestCtx) {
	path := ctx.Path()
	switch {
	case bytes.HasPrefix(path, imgPrefix):
		imgHandler(ctx)
	case bytes.HasPrefix(path, cssPrefix):
		cssHandler(ctx)
	default:
		filesHandler(ctx)
	}
}
Пример #13
0
func getExpvarRegexp(ctx *fasthttp.RequestCtx) (*regexp.Regexp, error) {
	r := string(ctx.QueryArgs().Peek("r"))
	if len(r) == 0 {
		r = "."
	}
	rr, err := regexp.Compile(r)
	if err != nil {
		return nil, fmt.Errorf("cannot parse r=%q: %s", r, err)
	}
	return rr, nil
}
Пример #14
0
func TestExpvarHandlerRegexp(t *testing.T) {
	var ctx fasthttp.RequestCtx
	ctx.QueryArgs().Set("r", "cmd")
	ExpvarHandler(&ctx)
	body := string(ctx.Response.Body())
	if !strings.Contains(body, `"cmdline"`) {
		t.Fatalf("missing 'cmdline' expvar")
	}
	if strings.Contains(body, `"memstats"`) {
		t.Fatalf("unexpected memstats expvar found")
	}
}
Пример #15
0
// ServerHTTP writes a redirect to an HTTP response
func (r *ProxyHandler) ServeHTTP(ctx *fasthttp.RequestCtx) {
	proxyClient := &fasthttp.HostClient{
		Addr: r.url,
		// set other options here if required - most notably timeouts.
	}

	req := &ctx.Request
	resp := &ctx.Response
	if err := proxyClient.Do(req, resp); err != nil {
		ctx.Logger().Printf("error when proxying the request: %s", err)
		ctx.SetStatusCode(fasthttp.StatusServiceUnavailable)
	}
}
func responseStreamHandler(ctx *fasthttp.RequestCtx) {
	// Send the response in chunks and wait for a second between each chunk.
	ctx.SetBodyStreamWriter(func(w *bufio.Writer) {
		for i := 0; i < 10; i++ {
			fmt.Fprintf(w, "this is a message number %d", i)

			// Do not forget flushing streamed data to the client.
			if err := w.Flush(); err != nil {
				return
			}
			time.Sleep(time.Second)
		}
	})
}
Пример #17
0
func mainHandler(ctx *fasthttp.RequestCtx) {
	// Performance hack for prefork mode - periodically close keepalive
	// connections for evenly distributing connections among available
	// processes.
	if *prefork {
		maxDuration := maxConnDuration + time.Millisecond*time.Duration(atomic.LoadUint64(&connDurationJitter))
		if time.Since(ctx.ConnTime()) > maxDuration {
			atomic.StoreUint64(&connDurationJitter, uint64(rand.Intn(100)))
			ctx.SetConnectionClose()
		}
	}

	path := ctx.Path()
	switch string(path) {
	case "/plaintext":
		plaintextHandler(ctx)
	case "/json":
		jsonHandler(ctx)
	case "/db":
		dbHandler(ctx)
	case "/queries":
		queriesHandler(ctx)
	case "/fortune":
		fortuneHandler(ctx)
	case "/update":
		updateHandler(ctx)
	default:
		ctx.Error("unexpected path", fasthttp.StatusBadRequest)
	}
}
Пример #18
0
func TestServerWrapHandler(t *testing.T) {
	e := echo.New()
	ctx := new(fasthttp.RequestCtx)
	req := NewRequest(ctx, nil)
	res := NewResponse(ctx, nil)
	c := e.NewContext(req, res)
	h := WrapHandler(func(ctx *fasthttp.RequestCtx) {
		ctx.Write([]byte("test"))
	})
	if assert.NoError(t, h(c)) {
		assert.Equal(t, http.StatusOK, ctx.Response.StatusCode())
		assert.Equal(t, "test", string(ctx.Response.Body()))
	}
}
Пример #19
0
//fasthttp
func fastHttpRawHandler(ctx *fasthttp.RequestCtx) {
	if string(ctx.Method()) == "GET" {
		switch string(ctx.Path()) {
		case "/hello":
			if sleepTime > 0 {
				time.Sleep(sleepTimeDuration)
			}
			ctx.Write(message)
		default:
			ctx.Error("Unsupported path", fasthttp.StatusNotFound)
		}
		return
	}
	ctx.Error("Unsupported method", fasthttp.StatusMethodNotAllowed)
}
Пример #20
0
func (g *Goka) Serve(rCtx *fasthttp.RequestCtx) {

	c := g.pool.Get().(*Context)
	h, g := g.router.Find(string(rCtx.Method()), string(rCtx.Path()), c)
	c.reset(rCtx, g)

	for i := len(g.middleware) - 1; i >= 0; i-- {
		h = g.middleware[i](h)
	}

	if err := h(c); err != nil {
		g.httpErrorHandler(err, c)
	}

	g.pool.Put(c)
}
func fastHTTPHandler(ctx *fasthttp.RequestCtx) {
	if string(ctx.Method()) == "GET" {
		switch string(ctx.Path()) {
		case "/rest/hello":
			ctx.Write([]byte("Hello world"))
		default:
			ctx.Error("Unsupported path", fasthttp.StatusNotFound)
		}
		return
	}
}
Пример #22
0
func mainHandler(ctx *fasthttp.RequestCtx) {
	path := ctx.Path()
	switch string(path) {
	case "/plaintext":
		plaintextHandler(ctx)
	case "/json":
		jsonHandler(ctx)
	case "/db":
		dbHandler(ctx)
	case "/queries":
		queriesHandler(ctx)
	case "/fortune":
		fortuneHandler(ctx)
	case "/update":
		updateHandler(ctx)
	default:
		ctx.Error("unexpected path", fasthttp.StatusBadRequest)
	}
}
Пример #23
0
func fortuneHandler(ctx *fasthttp.RequestCtx) {
	rows, err := db.Query("fortuneSelectStmt")
	if err != nil {
		log.Fatalf("Error selecting db data: %v", err)
	}

	fortunes := make([]templates.Fortune, 0, 16)
	for rows.Next() {
		var f templates.Fortune
		if err := rows.Scan(&f.ID, &f.Message); err != nil {
			log.Fatalf("Error scanning fortune row: %s", err)
		}
		fortunes = append(fortunes, f)
	}
	rows.Close()
	fortunes = append(fortunes, templates.Fortune{Message: "Additional fortune added at request time."})

	sort.Sort(common.FortunesByMessage(fortunes))

	ctx.SetContentType("text/html; charset=utf-8")
	templates.WriteFortunePage(ctx, fortunes)
}
Пример #24
0
func (l *logAction) Act(ruleName string, ctx *fasthttp.RequestCtx) error {
	_, err := fmt.Fprintf(
		l.destination,
		"[%v] %v %s %s %s%s \"%s\" \"%s\"\n",
		ruleName,
		time.Now().Format("2006-01-02 15:04:05.000"),
		ctx.Request.Header.Peek("X-Forwarded-For"),
		ctx.Method(),
		ctx.Host(),
		ctx.RequestURI(),
		ctx.PostBody(),
		ctx.Request.Header.UserAgent(),
	)
	return err
}
Пример #25
0
// HandleAuthorizeRequest 处理授权请求
func (fs *FastServer) HandleAuthorizeRequest(ctx *fasthttp.RequestCtx, authReq *AuthorizeRequest) (err error) {
	if authReq.UserID == "" {
		err = ErrUserInvalid
		return
	}
	tgr := &oauth2.TokenGenerateRequest{
		ClientID:    authReq.ClientID,
		UserID:      authReq.UserID,
		RedirectURI: authReq.RedirectURI,
		Scope:       authReq.Scope,
	}
	ti, terr := fs.manager.GenerateAuthToken(oauth2.Code, tgr)
	if terr != nil {
		err = terr
		return
	}
	redirectURI, err := fs.GetRedirectURI(authReq, ti)
	if err != nil {
		return
	}
	ctx.Redirect(redirectURI, 302)
	return
}
Пример #26
0
// GetAuthorizeRequest 获取授权请求参数
func (fs *FastServer) GetAuthorizeRequest(ctx *fasthttp.RequestCtx) (authReq *AuthorizeRequest, err error) {
	if !ctx.IsGet() {
		err = ErrRequestMethodInvalid
		return
	}
	redirectURI, err := url.QueryUnescape(string(ctx.FormValue("redirect_uri")))
	if err != nil {
		return
	}
	authReq = &AuthorizeRequest{
		Type:        oauth2.ResponseType(string(ctx.FormValue("response_type"))),
		RedirectURI: redirectURI,
		State:       string(ctx.FormValue("state")),
		Scope:       string(ctx.FormValue("scope")),
		ClientID:    string(ctx.FormValue("client_id")),
	}
	if authReq.Type == "" || !fs.checkResponseType(authReq.Type) {
		err = ErrResponseTypeInvalid
	} else if authReq.ClientID == "" {
		err = ErrClientInvalid
	}
	return
}
Пример #27
0
func (s *Server) ServeHTTP(c *fasthttp.RequestCtx) {
	// Request
	rq := s.pool.request.Get().(*Request)
	reqHdr := s.pool.requestHeader.Get().(*RequestHeader)
	reqURL := s.pool.url.Get().(*URL)
	reqHdr.reset(&c.Request.Header)
	reqURL.reset(c.URI())
	rq.reset(c, reqHdr, reqURL)

	// Response
	rs := s.pool.response.Get().(*Response)
	resHdr := s.pool.responseHeader.Get().(*ResponseHeader)
	resHdr.reset(&c.Response.Header)
	rs.reset(c, resHdr)

	s.handler.ServeHTTP(rq, rs)

	s.pool.request.Put(rq)
	s.pool.requestHeader.Put(reqHdr)
	s.pool.url.Put(reqURL)
	s.pool.response.Put(rs)
	s.pool.responseHeader.Put(resHdr)
}
Пример #28
0
// Test 4: Fortunes
func fortuneHandler(ctx *fasthttp.RequestCtx) {
	rows, err := fortuneSelectStmt.Query()
	if err != nil {
		log.Fatalf("Error selecting db data: %v", err)
	}

	fortunes := make([]Fortune, 0, 16)
	for rows.Next() {
		var f Fortune
		if err := rows.Scan(&f.Id, &f.Message); err != nil {
			log.Fatalf("Error scanning fortune row: %s", err)
		}
		fortunes = append(fortunes, f)
	}
	rows.Close()
	fortunes = append(fortunes, Fortune{Message: "Additional fortune added at request time."})

	sort.Sort(FortunesByMessage(fortunes))

	ctx.SetContentType("text/html")
	if err := tmpl.Execute(ctx, fortunes); err != nil {
		log.Fatalf("Error executing fortune: %s", err)
	}
}
Пример #29
0
// GetAllPosts is a method for getting every post
func GetAllPosts(ctx *fasthttp.RequestCtx, _ fasthttprouter.Params) {
	posts, err := model.GetAll(s)
	if err != nil {
		ctx.Error(err.Error(), fasthttp.StatusNotFound)
		return
	}

	resp, err := json.MarshalIndent(posts, "", "  ")
	if err != nil {
		ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
		return
	}
	ctx.Response.Header.Set("Content-Type", "application/json")
	ctx.Write(resp)
}
Пример #30
0
func zingAlbumHandler(ctx *fasthttp.RequestCtx, params fasthttprouter.Params) {
	zingURL := string(ctx.QueryArgs().Peek("url"))
	log.Info("Zing-mp3 album request",
		"zing_url", zingURL,
	)

	album, err := zing.ParseAlbumData(zingURL)
	if err != nil {
		ctx.SetStatusCode(fasthttp.StatusBadRequest)
		fmt.Fprint(ctx, err)
		return
	}

	job, err := newAlbumJob(album, ctx.Response.BodyWriter())
	if err != nil {
		ctx.SetStatusCode(fasthttp.StatusInternalServerError)
		fmt.Fprint(ctx, err)
		return
	}

	ctx.SetStatusCode(fasthttp.StatusOK)
	job.Run()
}