Add route/id resource. Closes #10
This commit is contained in:
@@ -12,8 +12,6 @@ to compose the response.
|
|||||||
We access the resource tree easily with the ``kapow set`` and ``kapow get``
|
We access the resource tree easily with the ``kapow set`` and ``kapow get``
|
||||||
subcommands.
|
subcommands.
|
||||||
|
|
||||||
.. // DOING #10: /route/id
|
|
||||||
|
|
||||||
.. // DOING #113: /request/ssl/client/i/dn
|
.. // DOING #113: /request/ssl/client/i/dn
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
@@ -45,6 +43,9 @@ Overview
|
|||||||
│ │ └──── content The contents of the file uploaded in the form field <name>
|
│ │ └──── content The contents of the file uploaded in the form field <name>
|
||||||
│ └──── body HTTP request body
|
│ └──── body HTTP request body
|
||||||
│
|
│
|
||||||
|
│─ route
|
||||||
|
│ └──── id Id of the route that matched this request.
|
||||||
|
│
|
||||||
└─ response
|
└─ response
|
||||||
├──── status HTTP status code
|
├──── status HTTP status code
|
||||||
├──── headers
|
├──── headers
|
||||||
@@ -382,6 +383,28 @@ then, when handling the request:
|
|||||||
foobar
|
foobar
|
||||||
|
|
||||||
|
|
||||||
|
``/route/id`` Resource
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ID of the original route that matched this request..
|
||||||
|
|
||||||
|
Sample Usage
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If the user runs:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ curl http://kapow.example:8080/
|
||||||
|
|
||||||
|
then, when handling the request:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ kapow get /route/id
|
||||||
|
ecd5d63f-f28b-11ea-ac55-ec21e5089c1f
|
||||||
|
|
||||||
|
|
||||||
``/response/status`` Resource
|
``/response/status`` Resource
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,12 @@ func getRequestFileContent(w http.ResponseWriter, r *http.Request, h *model.Hand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRequestId(w http.ResponseWriter, r *http.Request, h *model.Handler) {
|
||||||
|
w.Header().Add("Content-Type", "application/octet-stream")
|
||||||
|
_, _ = w.Write([]byte(h.Route.ID))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Allow any HTTP status code. Now we are limited by WriteHeader
|
// FIXME: Allow any HTTP status code. Now we are limited by WriteHeader
|
||||||
// capabilities
|
// capabilities
|
||||||
func setResponseStatus(w http.ResponseWriter, r *http.Request, h *model.Handler) {
|
func setResponseStatus(w http.ResponseWriter, r *http.Request, h *model.Handler) {
|
||||||
|
|||||||
@@ -266,8 +266,8 @@ func TestGetRequestVersionSetsOctectStreamContentType(t *testing.T) {
|
|||||||
getRequestVersion(w, r, &h)
|
getRequestVersion(w, r, &h)
|
||||||
|
|
||||||
res := w.Result()
|
res := w.Result()
|
||||||
if ct := res.Header.Get("Content-Type"); ct != "application/octet-stream" {
|
if v := res.Header.Get("Content-Type"); v != "application/octet-stream" {
|
||||||
t.Errorf("Content Type mismatch. Expected: %v, got: %v", "application/octet-stream", ct)
|
t.Errorf("Content Type mismatch. Expected: %q, got: %q", "application/octet-stream", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,8 +378,8 @@ func TestGetRequestRemoteSetsOctectStreamContentType(t *testing.T) {
|
|||||||
getRequestRemote(w, r, &h)
|
getRequestRemote(w, r, &h)
|
||||||
|
|
||||||
res := w.Result()
|
res := w.Result()
|
||||||
if ct := res.Header.Get("Content-Type"); ct != "application/octet-stream" {
|
if v := res.Header.Get("Content-Type"); v != "application/octet-stream" {
|
||||||
t.Errorf("Content Type mismatch. Expected: %v, got: %v", "application/octet-stream", ct)
|
t.Errorf("Content Type mismatch. Expected: %q, got: %q", "application/octet-stream", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +586,7 @@ func TestGetRequestHeadersSetsOctectStreamContentType(t *testing.T) {
|
|||||||
|
|
||||||
res := w.Result()
|
res := w.Result()
|
||||||
if v := res.Header.Get("Content-Type"); v != "application/octet-stream" {
|
if v := res.Header.Get("Content-Type"); v != "application/octet-stream" {
|
||||||
t.Errorf("Content Type mismatch. Expected: application/octet-stream. Got: %q", v)
|
t.Errorf("Content Type mismatch. Expected: %q. Got: %q", "application/octet-stream", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,7 +1109,54 @@ func TestGetRequestFileContent500sWhenHandlerRequestErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOING #10: /route/id
|
func TestGetRouteId200sOnHappyPath(t *testing.T) {
|
||||||
|
h := model.Handler{
|
||||||
|
Request: httptest.NewRequest("POST", "/", nil),
|
||||||
|
Writer: httptest.NewRecorder(),
|
||||||
|
}
|
||||||
|
r := httptest.NewRequest("GET", "/not-important-here", nil)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
getRequestId(w, r, &h)
|
||||||
|
|
||||||
|
res := w.Result()
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
t.Error("Status code mismatch")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRouteIdSetsOctectStreamContentType(t *testing.T) {
|
||||||
|
h := model.Handler{
|
||||||
|
Request: httptest.NewRequest("POST", "/", nil),
|
||||||
|
Writer: httptest.NewRecorder(),
|
||||||
|
}
|
||||||
|
r := httptest.NewRequest("GET", "/not-important-here", nil)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
getRequestId(w, r, &h)
|
||||||
|
|
||||||
|
res := w.Result()
|
||||||
|
if v := res.Header.Get("Content-Type"); v != "application/octet-stream" {
|
||||||
|
t.Errorf("Content Type mismatch. Expected: %q, got: %q", "application/octet-stream", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRouteIdReturnsTheCorrectMethod(t *testing.T) {
|
||||||
|
h := model.Handler{
|
||||||
|
Request: httptest.NewRequest("FOO", "/", nil),
|
||||||
|
Writer: httptest.NewRecorder(),
|
||||||
|
Route: model.Route{ID: "Expected_ID"},
|
||||||
|
}
|
||||||
|
r := httptest.NewRequest("GET", "/not-important-here", nil)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
getRequestId(w, r, &h)
|
||||||
|
|
||||||
|
res := w.Result()
|
||||||
|
if body, _ := ioutil.ReadAll(res.Body); string(body) != "Expected_ID" {
|
||||||
|
t.Errorf("Body mismatch. Expected: %q, got: %q", "Expected_ID", string(body))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetResponseStatus200sOnHappyPath(t *testing.T) {
|
func TestSetResponseStatus200sOnHappyPath(t *testing.T) {
|
||||||
h := model.Handler{
|
h := model.Handler{
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ func Run(bindAddr string, wg *sync.WaitGroup) {
|
|||||||
{"/handlers/{handlerID}/request/files/{name}/content", "GET", getRequestFileContent},
|
{"/handlers/{handlerID}/request/files/{name}/content", "GET", getRequestFileContent},
|
||||||
{"/handlers/{handlerID}/request/body", "GET", getRequestBody},
|
{"/handlers/{handlerID}/request/body", "GET", getRequestBody},
|
||||||
|
|
||||||
|
// route
|
||||||
|
//{"/handlers/{handlerID}/route/id", "GET", getRouteId},
|
||||||
|
|
||||||
// response
|
// response
|
||||||
{"/handlers/{handlerID}/response/status", "PUT", lockResponseWriter(setResponseStatus)},
|
{"/handlers/{handlerID}/response/status", "PUT", lockResponseWriter(setResponseStatus)},
|
||||||
{"/handlers/{handlerID}/response/headers/{name}", "PUT", lockResponseWriter(setResponseHeaders)},
|
{"/handlers/{handlerID}/response/headers/{name}", "PUT", lockResponseWriter(setResponseHeaders)},
|
||||||
|
|||||||
Reference in New Issue
Block a user