func ExampleLBClient() { // Requests will be spread among these servers. servers := []string{ "google.com:80", "foobar.com:8080", "127.0.0.1:123", } // Prepare clients for each server var lbc fasthttp.LBClient for _, addr := range servers { c := &fasthttp.HostClient{ Addr: addr, } lbc.Clients = append(lbc.Clients, c) } // Send requests to load-balanced servers var req fasthttp.Request var resp fasthttp.Response for i := 0; i < 10; i++ { url := fmt.Sprintf("http://abcedfg/foo/bar/%d", i) req.SetRequestURI(url) if err := lbc.Do(&req, &resp); err != nil { log.Fatalf("Error when sending request: %s", err) } if resp.StatusCode() != fasthttp.StatusOK { log.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode(), fasthttp.StatusOK) } useResponseBody(resp.Body()) } }
func acquireAddr(req *fasthttp.Request) (string, bool) { addr := string(req.URI().Host()) if len(addr) == 0 { log.Fatalf("address cannot be empty") } isTLS := string(req.URI().Scheme()) == "https" tmp := strings.SplitN(addr, ":", 2) if len(tmp) != 2 { port := ":80" if isTLS { port = ":443" } return tmp[0] + port, isTLS } port := tmp[1] portInt, err := strconv.Atoi(port) if err != nil { log.Fatalf("cannot parse port %q of addr %q: %s", port, addr, err) } if portInt < 0 { log.Fatalf("upstreamHosts port %d cannot be negative: %q", portInt, addr) } return addr, isTLS }
func fetchFromUpstream(h *fasthttp.RequestHeader, key []byte) *ybc.Item { upstreamUrl := fmt.Sprintf("%s://%s%s", *upstreamProtocol, *upstreamHost, h.RequestURI()) var req fasthttp.Request req.SetRequestURI(upstreamUrl) var resp fasthttp.Response err := upstreamClient.Do(&req, &resp) if err != nil { logRequestError(h, "Cannot make request for [%s]: [%s]", key, err) return nil } if resp.StatusCode() != fasthttp.StatusOK { logRequestError(h, "Unexpected status code=%d for the response [%s]", resp.StatusCode(), key) return nil } contentType := string(resp.Header.ContentType()) if contentType == "" { contentType = "application/octet-stream" } body := resp.Body() contentLength := len(body) itemSize := contentLength + len(contentType) + 1 txn, err := cache.NewSetTxn(key, itemSize, ybc.MaxTtl) if err != nil { logRequestError(h, "Cannot start set txn for response [%s], itemSize=%d: [%s]", key, itemSize, err) return nil } if err = storeContentType(h, txn, contentType); err != nil { txn.Rollback() return nil } n, err := txn.Write(body) if err != nil { logRequestError(h, "Cannot read response [%s] body with size=%d to cache: [%s]", key, contentLength, err) txn.Rollback() return nil } if n != contentLength { logRequestError(h, "Unexpected number of bytes copied=%d from response [%s] to cache. Expected %d", n, key, contentLength) txn.Rollback() return nil } item, err := txn.CommitItem() if err != nil { logRequestError(h, "Cannot commit set txn for response [%s], size=%d: [%s]", key, contentLength, err) return nil } atomic.AddInt64(&stats.BytesReadFromUpstream, int64(n)) return item }
func runRequests(b *testing.B, pb *testing.PB, c *fasthttp.HostClient) { var req fasthttp.Request req.SetRequestURI("http://foo.bar/baz") var resp fasthttp.Response for pb.Next() { if err := c.Do(&req, &resp); err != nil { b.Fatalf("unexpected error: %s", err) } if resp.StatusCode() != fasthttp.StatusOK { b.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode(), fasthttp.StatusOK) } } }
func convertRequest(stdreq *http.Request, fastreq *fasthttp.Request) { fastreq.SetRequestURI(stdreq.URL.String()) fastreq.Header.SetMethod(stdreq.Method) for k, a := range stdreq.Header { for n, v := range a { if n == 0 { fastreq.Header.Set(k, v) } else { fastreq.Header.Add(k, v) } } } }
func BenchmarkGas(b *testing.B) { b.ReportAllocs() // new gas g := New("testfiles/config_test.yaml") // set route g.Router.Get("/", indexPage) req := fasthttp.Request{} req.SetRequestURI("/") req.Header.SetMethod("GET") for i := 0; i < b.N; i++ { ctx := fasthttp.RequestCtx{ Request: req, } g.Router.Handler(&ctx) } }
func TestNewFastHTTPHandler(t *testing.T) { expectedMethod := "POST" expectedProto := "HTTP/1.1" expectedProtoMajor := 1 expectedProtoMinor := 1 expectedRequestURI := "/foo/bar?baz=123" expectedBody := "body 123 foo bar baz" expectedContentLength := len(expectedBody) expectedTransferEncoding := "encoding" expectedHost := "foobar.com" expectedRemoteAddr := "1.2.3.4:6789" expectedHeader := map[string]string{ "Foo-Bar": "baz", "Abc": "defg", "XXX-Remote-Addr": "123.43.4543.345", } expectedURL, err := url.ParseRequestURI(expectedRequestURI) if err != nil { t.Fatalf("unexpected error: %s", err) } callsCount := 0 nethttpH := func(w http.ResponseWriter, r *http.Request) { callsCount++ if r.Method != expectedMethod { t.Fatalf("unexpected method %q. Expecting %q", r.Method, expectedMethod) } if r.Proto != expectedProto { t.Fatalf("unexpected proto %q. Expecting %q", r.Proto, expectedProto) } if r.ProtoMajor != expectedProtoMajor { t.Fatalf("unexpected protoMajor %d. Expecting %d", r.ProtoMajor, expectedProtoMajor) } if r.ProtoMinor != expectedProtoMinor { t.Fatalf("unexpected protoMinor %d. Expecting %d", r.ProtoMinor, expectedProtoMinor) } if r.RequestURI != expectedRequestURI { t.Fatalf("unexpected requestURI %q. Expecting %q", r.RequestURI, expectedRequestURI) } if r.ContentLength != int64(expectedContentLength) { t.Fatalf("unexpected contentLength %d. Expecting %d", r.ContentLength, expectedContentLength) } if len(r.TransferEncoding) != 1 || r.TransferEncoding[0] != expectedTransferEncoding { t.Fatalf("unexpected transferEncoding %d. Expecting %d", r.TransferEncoding, expectedTransferEncoding) } if r.Host != expectedHost { t.Fatalf("unexpected host %q. Expecting %q", r.Host, expectedHost) } if r.RemoteAddr != expectedRemoteAddr { t.Fatalf("unexpected remoteAddr %q. Expecting %q", r.RemoteAddr, expectedRemoteAddr) } body, err := ioutil.ReadAll(r.Body) r.Body.Close() if err != nil { t.Fatalf("unexpected error when reading request body: %s", err) } if string(body) != expectedBody { t.Fatalf("unexpected body %q. Expecting %q", body, expectedBody) } if !reflect.DeepEqual(r.URL, expectedURL) { t.Fatalf("unexpected URL: %#v. Expecting %#v", r.URL, expectedURL) } for k, expectedV := range expectedHeader { v := r.Header.Get(k) if v != expectedV { t.Fatalf("unexpected header value %q for key %q. Expecting %q", v, k, expectedV) } } w.Header().Set("Header1", "value1") w.Header().Set("Header2", "value2") w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "request body is %q", body) } fasthttpH := NewFastHTTPHandler(http.HandlerFunc(nethttpH)) var ctx fasthttp.RequestCtx var req fasthttp.Request req.Header.SetMethod(expectedMethod) req.SetRequestURI(expectedRequestURI) req.Header.SetHost(expectedHost) req.Header.Add("Transfer-Encoding", expectedTransferEncoding) req.BodyWriter().Write([]byte(expectedBody)) for k, v := range expectedHeader { req.Header.Set(k, v) } remoteAddr, err := net.ResolveTCPAddr("tcp", expectedRemoteAddr) if err != nil { t.Fatalf("unexpected error: %s", err) } ctx.Init(&req, remoteAddr, nil) fasthttpH(&ctx) if callsCount != 1 { t.Fatalf("unexpected callsCount: %d. Expecting 1", callsCount) } resp := &ctx.Response if resp.StatusCode() != fasthttp.StatusBadRequest { t.Fatalf("unexpected statusCode: %d. Expecting %d", resp.StatusCode(), fasthttp.StatusBadRequest) } if string(resp.Header.Peek("Header1")) != "value1" { t.Fatalf("unexpected header value: %q. Expecting %q", resp.Header.Peek("Header1"), "value1") } if string(resp.Header.Peek("Header2")) != "value2" { t.Fatalf("unexpected header value: %q. Expecting %q", resp.Header.Peek("Header2"), "value2") } expectedResponseBody := fmt.Sprintf("request body is %q", expectedBody) if string(resp.Body()) != expectedResponseBody { t.Fatalf("unexpected response body %q. Expecting %q", resp.Body(), expectedResponseBody) } }