Beispiel #1
0
/* test cases */
func Test_WebPipeEndToEndRequestsShouldSucceed(t *testing.T) {
	/* server side logic */
	itemsMap := make(map[string]string)
	createItemApi := func(request *webpipe.Request, response *webpipe.Response, _ webpipe.Context) error {
		id := uuid.NewV4().String()
		if data, err := request.Payload.Bytes(); err != nil {
			return err
		} else {
			itemsMap[id] = string(data)
		}

		response.Payload = webpipe.CreateBytesPayload([]byte(id))
		return nil
	}

	getItemApi := func(request *webpipe.Request, response *webpipe.Response, _ webpipe.Context) error {
		id := request.Params.Get("item_id")
		if item, ok := itemsMap[id]; ok {
			response.Payload = webpipe.CreateBytesPayload([]byte(item))
		}
		return nil
	}

	/* prepare server pipe */
	serverHandlers := []webpipe.DelegatingHandler{
		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			startTime := time.Now()                                  /* get start timestamp */
			context.Next(request, response)                          /* invoke the remaining part in the stack */
			duration := time.Now().Sub(startTime)                    /* calculate elapsed duration */
			response.Header.Set("X-API-DURATION", duration.String()) /* fill the duration header */
		},

		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			authHeader, found := request.Header["Authorization"] /* check auth header */
			if !found || len(authHeader) == 0 {
				response.StatusCode = http.StatusForbidden /* forbid calling without auth header */
			} else {
				if authHeader[0] != "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" {
					response.StatusCode = http.StatusUnauthorized /* do authorization */
				} else {
					context.Next(request, response) /* invoke the remaining part in the stack */
				}
			}
		},
	}

	server := webpipe.CreateServer(serverHandlers)
	server.Register("POST", "/items", nil, createItemApi)
	server.Register("GET", "/items/:item_id", nil, getItemApi)
	go server.Listen(8082)

	/* prepare client pipe */
	invokePerfLog := []string{}
	clientHandlers := []webpipe.DelegatingHandler{
		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			request.Header.Set("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==") /* set auth header */
			context.Next(request, response)                                           /* invoke the remaining part in the stack */
		},

		func(request *webpipe.Request, response *webpipe.Response, context webpipe.Context) {
			context.Next(request, response) /* invoke the rpc first */
			duration := response.Header.Get("X-API-DURATION")
			invokePerfLog = append(invokePerfLog, duration)
		},
	}

	/* client side invocations */
	client := webpipe.CreateClient("http://localhost:8082", clientHandlers)
	req := client.NewRequest("POST")
	req.Payload = webpipe.CreateBytesPayload([]byte("bytes payload for item"))
	resp, err := client.Invoke("/items", req)

	/* assertion 1 */
	Nil(t, err)
	Equal(t, http.StatusCreated, resp.StatusCode)
	Equal(t, 1, len(invokePerfLog))
	Equal(t, 1, len(itemsMap))
	id, err := resp.Payload.Bytes()
	Nil(t, err)
	False(t, len(id) == 0)

	req = client.NewRequest("GET")
	req.Params.Set("item_id", string(id))
	resp, err = client.Invoke("/items/:item_id", req)

	/* assertion 2 */
	Nil(t, err)
	Equal(t, http.StatusOK, resp.StatusCode)
	Equal(t, 2, len(invokePerfLog))
	body, err := resp.Payload.Bytes()
	Nil(t, err)
	Equal(t, "bytes payload for item", string(body))
}
Beispiel #2
0
func Test_HandleHttpBasicRequestsShouldSucceed(t *testing.T) {
	/* prepare web server */
	server := webpipe.CreateServer(nil)

	server.Register("POST", "/echo", nil,
		func(request *webpipe.Request, response *webpipe.Response, _ webpipe.Context) error {
			response.Payload = request.Payload
			return nil
		})

	server.Register("GET", "/hello/:name", nil,
		func(request *webpipe.Request, response *webpipe.Response, _ webpipe.Context) error {
			if request.Payload != nil {
				return errors.New("invalid payload input")
			}

			response.Payload = webpipe.CreateBytesPayload([]byte("hello, " + request.Params.Get("name")))
			return nil
		})

	server.Register("GET", "/items/:id", nil,
		func(request *webpipe.Request, response *webpipe.Response, ctx webpipe.Context) error {
			if request.Payload != nil {
				return errors.New("invalid payload input")
			}

			/* should not call anything furthur */
			ctx.Next(request, response)
			return nil
		})

	go server.Listen(8080)

	/* invoke echo api */
	res, err := http.Post("http://localhost:8080/echo", "text/plain", bytes.NewBuffer([]byte("Hello Server")))
	Nil(t, err)
	Equal(t, http.StatusCreated, res.StatusCode)

	pl := webpipe.CreateWebStreamPayload(res.Body, int(res.ContentLength))
	b, err := pl.Bytes()
	Nil(t, err)
	True(t, bytes.Equal([]byte("Hello Server"), b))

	/* invoke hello api */
	res, err = http.Get("http://localhost:8080/hello/gopher")
	Nil(t, err)
	Equal(t, http.StatusOK, res.StatusCode)

	pl = webpipe.CreateWebStreamPayload(res.Body, int(res.ContentLength))
	b, err = pl.Bytes()
	Nil(t, err)
	True(t, bytes.Equal([]byte("hello, gopher"), b))

	/* invoke not found api */
	res, err = http.Get("http://localhost:8080/items/1")
	Nil(t, err)
	Equal(t, http.StatusNotFound, res.StatusCode)

	pl = webpipe.CreateWebStreamPayload(res.Body, int(res.ContentLength))
	Equal(t, 0, int(res.ContentLength))
}