Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: 500 Invalid WRP content type: */* for an invalid accept header #74

Merged

Conversation

denopink
Copy link
Contributor

@denopink denopink commented Apr 26, 2022

Overview

related to xmidt-org/talaria#227 where a 500 Invalid WRP content type: */* is produced when an invalid accept header is provided. Instead of a 500, 400 is now returned.

tl;rd

This patches the bug where replacing the header Accept: application/json with anything except application/json like Accept: /, returns a 500 Invalid WRP content type: /.

Explanation

It starts off with an error from DetermineFormat not being handled at

format, err := DetermineFormat(defaultFormat, wrpRequest.Original.Header, "Accept")
if err != nil {
return nil, err
}

Then NewEntityResponseWriters DetermineFormat error gets handled as a 500 at

wrp-go/wrphttp/handler.go

Lines 134 to 138 in 4b27541

wrpResponse, err := wh.newResponseWriter(httpResponse, wrpRequest)
if err != nil {
wh.errorEncoder(wrpRequest.Context(), err, httpResponse)
return
}

Type of Change(s)
  • Bug fix (non-breaking change which fixes an issue)
  • All new and existing tests passed.
Module Unit Testing: [PASSING]
PR Affecting Unit Testing: handler_test.go [PASSING]
Running tool: /usr/local/bin/go test -timeout 30s -run ^(TestHandlerFunc|TestWithErrorEncoder|TestWithNewResponseWriter|TestWithDecoder|TestWithBefore|TestNewHTTPHandler|TestWRPHandler)$ github.com/xmidt-org/wrp-go/v3/wrphttp

=== RUN   TestHandlerFunc
--- PASS: TestHandlerFunc (0.00s)
=== RUN   TestWithErrorEncoder
=== RUN   TestWithErrorEncoder/Default
=== RUN   TestWithErrorEncoder/Custom
--- PASS: TestWithErrorEncoder (0.00s)
    --- PASS: TestWithErrorEncoder/Default (0.00s)
    --- PASS: TestWithErrorEncoder/Custom (0.00s)
=== RUN   TestWithNewResponseWriter
=== RUN   TestWithNewResponseWriter/Default
=== RUN   TestWithNewResponseWriter/Custom
--- PASS: TestWithNewResponseWriter (0.00s)
    --- PASS: TestWithNewResponseWriter/Default (0.00s)
    --- PASS: TestWithNewResponseWriter/Custom (0.00s)
=== RUN   TestWithDecoder
=== RUN   TestWithDecoder/Default
=== RUN   TestWithDecoder/Custom
--- PASS: TestWithDecoder (0.00s)
    --- PASS: TestWithDecoder/Default (0.00s)
    --- PASS: TestWithDecoder/Custom (0.00s)
=== RUN   TestWithBefore
=== RUN   TestWithBefore/0
=== RUN   TestWithBefore/1
=== RUN   TestWithBefore/2
=== RUN   TestWithBefore/3
--- PASS: TestWithBefore (0.00s)
    --- PASS: TestWithBefore/0 (0.00s)
    --- PASS: TestWithBefore/1 (0.00s)
    --- PASS: TestWithBefore/2 (0.00s)
    --- PASS: TestWithBefore/3 (0.00s)
=== RUN   TestNewHTTPHandler
--- PASS: TestNewHTTPHandler (0.00s)
=== RUN   TestWRPHandler
=== RUN   TestWRPHandler/ServeHTTP
=== RUN   TestWRPHandler/ServeHTTP/DecodeError
=== RUN   TestWRPHandler/ServeHTTP/ResponseWriterError
=== RUN   TestWRPHandler/ServeHTTP/Success
    /Users/odc/Documents/GitHub/xmidt-org/wrp-go/wrphttp/handler_test.go:352: PASS:     ServeWRP(mock.argumentMatcher,mock.argumentMatcher)
--- PASS: TestWRPHandler (0.00s)
    --- PASS: TestWRPHandler/ServeHTTP (0.00s)
        --- PASS: TestWRPHandler/ServeHTTP/DecodeError (0.00s)
        --- PASS: TestWRPHandler/ServeHTTP/ResponseWriterError (0.00s)
        --- PASS: TestWRPHandler/ServeHTTP/Success (0.00s)
PASS
ok      github.com/xmidt-org/wrp-go/v3/wrphttp  0.134s


> Test run finished at 5/2/2022, 3:47:48 PM <

Local Test

Ran talaria locally

curl -v --location --request POST 'localhost:6200/api/v3/device/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic dXNlcjpwYXNz' \
--data-raw '{
"msg_type":3,
"content_type":"application/json",
"source":"dns:me",
"dest":"mac:112233445566",
"transaction_uuid":"1234567890",
"payload":"eyJjb21tYW5kIjoiR0VUIiwibmFtZXMiOlsiU29tZXRoaW5nIl19",
"partner_ids":["comcast"]
}'

# Output:

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:6200...
* Connected to localhost (127.0.0.1) port 6200 (#0)
> POST /api/v3/device/send HTTP/1.1
> Host: localhost:6200
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Type: application/json
> Authorization: Basic dXNlcjpwYXNz
> Content-Length: 223
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Content-Length: 29
< Content-Type: text/plain; charset=utf-8
< X-Talaria-Build: 0.1.4
< X-Talaria-Flavor: mint
< X-Talaria-Region: east
< X-Talaria-Server: talaria
< X-Talaria-Start-Time: 26 Apr 22 15:51 UTC
< Date: Tue, 26 Apr 2022 16:03:41 GMT
<
* Connection #0 to host localhost left intact
Invalid WRP content type: */*%
#

@denopink denopink added the bug Something isn't working label Apr 26, 2022
@denopink denopink requested a review from kristinapathak April 26, 2022 18:50
@denopink denopink self-assigned this Apr 26, 2022
denopink added a commit to denopink/wrp-go that referenced this pull request Apr 26, 2022
denopink added a commit to denopink/wrp-go that referenced this pull request Apr 26, 2022
Patch bug xmidt-org/talaria#227 , `500 Invalid WRP content type: */*`

Looked into xmidt-org/talaria#227 and it looks like we're not handling a bad format error from `DetermineFormat` at
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/requestResponse.go#L140-L143
```go
func NewEntityResponseWriter(defaultFormat wrp.Format) ResponseWriterFunc {
	return func(httpResponse http.ResponseWriter, wrpRequest *Request) (ResponseWriter, error) {
		format, err := DetermineFormat(defaultFormat, wrpRequest.Original.Header, "Accept")
		if err != nil {
			return nil, err
		}
		...
	}
}
```
Then `NewEntityResponseWriter`s `DetermineFormat error` gets handled as a `500` at (where `newResponseWriter` -> `NewEntityResponseWriter`)
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/handler.go#L134-L138
```go
func (wh *wrpHandler) ServeHTTP(httpResponse http.ResponseWriter, httpRequest *http.Request) {
	...
	wrpResponse, err := wh.newResponseWriter(httpResponse, wrpRequest)
	if err != nil {
		wh.errorEncoder(wrpRequest.Context(), err, httpResponse)
		return
	}
	...
}
```

Tested locally with a quick patch and it looks goods:
```console
curl -v --location --request POST 'localhost:6200/api/v3/device/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic dXNlcjpwYXNz' \
--data-raw '{
"msg_type":3,
"content_type":"application/json",
"source":"dns:me",
"dest":"mac:112233445566",
"transaction_uuid":"1234567890",
"payload":"eyJjb21tYW5kIjoiR0VUIiwibmFtZXMiOlsiU29tZXRoaW5nIl19",
"partner_ids":["comcast"]
}'

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:6200...
* Connected to localhost (127.0.0.1) port 6200 (#0)
> POST /api/v3/device/send HTTP/1.1
> Host: localhost:6200
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Type: application/json
> Authorization: Basic dXNlcjpwYXNz
> Content-Length: 223
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Content-Length: 29
< Content-Type: text/plain; charset=utf-8
< X-Talaria-Build: 0.1.4
< X-Talaria-Flavor: mint
< X-Talaria-Region: east
< X-Talaria-Server: talaria
< X-Talaria-Start-Time: 26 Apr 22 15:51 UTC
< Date: Tue, 26 Apr 2022 16:03:41 GMT
<
* Connection #0 to host localhost left intact
Invalid WRP content type: */*%
```

Move validation of the `Accept` header to `DecodeEntity` func
@denopink denopink force-pushed the denopink/Bug-500InvalidWRPContentType branch from f876422 to 0fb935f Compare April 26, 2022 22:28
Copy link
Contributor

@kristinapathak kristinapathak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Can you add a test case in decoders_test.go for this scenario?

@denopink
Copy link
Contributor Author

This looks great! Can you add a test case in decoders_test.go for this scenario?

Will do and rebase with #73

denopink added a commit to denopink/wrp-go that referenced this pull request May 2, 2022
Patch bug xmidt-org/talaria#227 , `500 Invalid WRP content type: */*`

Looked into xmidt-org/talaria#227 and it looks like we're not handling a bad format error from `DetermineFormat` at
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/requestResponse.go#L140-L143
```go
func NewEntityResponseWriter(defaultFormat wrp.Format) ResponseWriterFunc {
	return func(httpResponse http.ResponseWriter, wrpRequest *Request) (ResponseWriter, error) {
		format, err := DetermineFormat(defaultFormat, wrpRequest.Original.Header, "Accept")
		if err != nil {
			return nil, err
		}
		...
	}
}
```
Then `NewEntityResponseWriter`s `DetermineFormat error` gets handled as a `500` at (where `newResponseWriter` -> `NewEntityResponseWriter`)
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/handler.go#L134-L138
```go
func (wh *wrpHandler) ServeHTTP(httpResponse http.ResponseWriter, httpRequest *http.Request) {
	...
	wrpResponse, err := wh.newResponseWriter(httpResponse, wrpRequest)
	if err != nil {
		wh.errorEncoder(wrpRequest.Context(), err, httpResponse)
		return
	}
	...
}
```

Tested locally with a quick patch and it looks goods:
```console
curl -v --location --request POST 'localhost:6200/api/v3/device/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic dXNlcjpwYXNz' \
--data-raw '{
"msg_type":3,
"content_type":"application/json",
"source":"dns:me",
"dest":"mac:112233445566",
"transaction_uuid":"1234567890",
"payload":"eyJjb21tYW5kIjoiR0VUIiwibmFtZXMiOlsiU29tZXRoaW5nIl19",
"partner_ids":["comcast"]
}'

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:6200...
* Connected to localhost (127.0.0.1) port 6200 (#0)
> POST /api/v3/device/send HTTP/1.1
> Host: localhost:6200
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Type: application/json
> Authorization: Basic dXNlcjpwYXNz
> Content-Length: 223
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Content-Length: 29
< Content-Type: text/plain; charset=utf-8
< X-Talaria-Build: 0.1.4
< X-Talaria-Flavor: mint
< X-Talaria-Region: east
< X-Talaria-Server: talaria
< X-Talaria-Start-Time: 26 Apr 22 15:51 UTC
< Date: Tue, 26 Apr 2022 16:03:41 GMT
<
* Connection #0 to host localhost left intact
Invalid WRP content type: */*%
```

Move validation of the `Accept` header to `DecodeEntity` func
@codecov
Copy link

codecov bot commented May 2, 2022

Codecov Report

Merging #74 (9b0fca0) into main (7f41972) will increase coverage by 0.04%.
The diff coverage is 100.00%.

❗ Current head 9b0fca0 differs from pull request most recent head f5a6e28. Consider uploading reports for the commit f5a6e28 to get more accurate results

@@            Coverage Diff             @@
##             main      #74      +/-   ##
==========================================
+ Coverage   49.03%   49.08%   +0.04%     
==========================================
  Files          18       18              
  Lines        3214     3217       +3     
==========================================
+ Hits         1576     1579       +3     
  Misses       1468     1468              
  Partials      170      170              
Impacted Files Coverage Δ
format.go 70.90% <100.00%> (ø)
wrphttp/decoders.go 75.00% <100.00%> (+2.27%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7f41972...f5a6e28. Read the comment docs.

denopink added 5 commits May 2, 2022 15:36
Patch bug xmidt-org/talaria#227 , `500 Invalid WRP content type: */*`

Looked into xmidt-org/talaria#227 and it looks like we're not handling a bad format error from `DetermineFormat` at
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/requestResponse.go#L140-L143
```go
func NewEntityResponseWriter(defaultFormat wrp.Format) ResponseWriterFunc {
	return func(httpResponse http.ResponseWriter, wrpRequest *Request) (ResponseWriter, error) {
		format, err := DetermineFormat(defaultFormat, wrpRequest.Original.Header, "Accept")
		if err != nil {
			return nil, err
		}
		...
	}
}
```
Then `NewEntityResponseWriter`s `DetermineFormat error` gets handled as a `500` at (where `newResponseWriter` -> `NewEntityResponseWriter`)
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/handler.go#L134-L138
```go
func (wh *wrpHandler) ServeHTTP(httpResponse http.ResponseWriter, httpRequest *http.Request) {
	...
	wrpResponse, err := wh.newResponseWriter(httpResponse, wrpRequest)
	if err != nil {
		wh.errorEncoder(wrpRequest.Context(), err, httpResponse)
		return
	}
	...
}
```

Tested locally with a quick patch and it looks goods:
```console
curl -v --location --request POST 'localhost:6200/api/v3/device/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic dXNlcjpwYXNz' \
--data-raw '{
"msg_type":3,
"content_type":"application/json",
"source":"dns:me",
"dest":"mac:112233445566",
"transaction_uuid":"1234567890",
"payload":"eyJjb21tYW5kIjoiR0VUIiwibmFtZXMiOlsiU29tZXRoaW5nIl19",
"partner_ids":["comcast"]
}'

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:6200...
* Connected to localhost (127.0.0.1) port 6200 (#0)
> POST /api/v3/device/send HTTP/1.1
> Host: localhost:6200
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Type: application/json
> Authorization: Basic dXNlcjpwYXNz
> Content-Length: 223
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Content-Length: 29
< Content-Type: text/plain; charset=utf-8
< X-Talaria-Build: 0.1.4
< X-Talaria-Flavor: mint
< X-Talaria-Region: east
< X-Talaria-Server: talaria
< X-Talaria-Start-Time: 26 Apr 22 15:51 UTC
< Date: Tue, 26 Apr 2022 16:03:41 GMT
<
* Connection #0 to host localhost left intact
Invalid WRP content type: */*%
```

Move validation of the `Accept` header to `DecodeEntity` func
Patch bug xmidt-org/talaria#227 , `500 Invalid WRP content type: */*`

Looked into xmidt-org/talaria#227 and it looks like we're not handling a bad format error from `DetermineFormat` at
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/requestResponse.go#L140-L143
```go
func NewEntityResponseWriter(defaultFormat wrp.Format) ResponseWriterFunc {
	return func(httpResponse http.ResponseWriter, wrpRequest *Request) (ResponseWriter, error) {
		format, err := DetermineFormat(defaultFormat, wrpRequest.Original.Header, "Accept")
		if err != nil {
			return nil, err
		}
		...
	}
}
```
Then `NewEntityResponseWriter`s `DetermineFormat error` gets handled as a `500` at (where `newResponseWriter` -> `NewEntityResponseWriter`)
https://github.com/xmidt-org/wrp-go/blob/4b275411c7aa52e1a537cc130f3b0f37e526c978/wrphttp/handler.go#L134-L138
```go
func (wh *wrpHandler) ServeHTTP(httpResponse http.ResponseWriter, httpRequest *http.Request) {
	...
	wrpResponse, err := wh.newResponseWriter(httpResponse, wrpRequest)
	if err != nil {
		wh.errorEncoder(wrpRequest.Context(), err, httpResponse)
		return
	}
	...
}
```

Tested locally with a quick patch and it looks goods:
```console
curl -v --location --request POST 'localhost:6200/api/v3/device/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic dXNlcjpwYXNz' \
--data-raw '{
"msg_type":3,
"content_type":"application/json",
"source":"dns:me",
"dest":"mac:112233445566",
"transaction_uuid":"1234567890",
"payload":"eyJjb21tYW5kIjoiR0VUIiwibmFtZXMiOlsiU29tZXRoaW5nIl19",
"partner_ids":["comcast"]
}'

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:6200...
* Connected to localhost (127.0.0.1) port 6200 (#0)
> POST /api/v3/device/send HTTP/1.1
> Host: localhost:6200
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Type: application/json
> Authorization: Basic dXNlcjpwYXNz
> Content-Length: 223
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Content-Length: 29
< Content-Type: text/plain; charset=utf-8
< X-Talaria-Build: 0.1.4
< X-Talaria-Flavor: mint
< X-Talaria-Region: east
< X-Talaria-Server: talaria
< X-Talaria-Start-Time: 26 Apr 22 15:51 UTC
< Date: Tue, 26 Apr 2022 16:03:41 GMT
<
* Connection #0 to host localhost left intact
Invalid WRP content type: */*%
```

Move validation of the `Accept` header to `DecodeEntity` func
@denopink denopink force-pushed the denopink/Bug-500InvalidWRPContentType branch from 472e177 to b598138 Compare May 2, 2022 19:39
@denopink denopink requested a review from kristinapathak May 2, 2022 19:49
Copy link
Contributor

@kristinapathak kristinapathak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

wrphttp/decoders_test.go Outdated Show resolved Hide resolved
wrphttp/decoders_test.go Outdated Show resolved Hide resolved
denopink and others added 3 commits May 3, 2022 16:34
Co-authored-by: Kristina Pathak <kmspring57@gmail.com>
Co-authored-by: Kristina Pathak <kmspring57@gmail.com>
@denopink denopink merged commit 162846c into xmidt-org:main May 3, 2022
@denopink denopink deleted the denopink/Bug-500InvalidWRPContentType branch May 3, 2022 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants