Skip to content

Add DirectResponseAction, a new route action type that returns a hard…#393

Merged
mattklein123 merged 5 commits intoenvoyproxy:masterfrom
brian-pane:direct-response/2315
Jan 6, 2018
Merged

Add DirectResponseAction, a new route action type that returns a hard…#393
mattklein123 merged 5 commits intoenvoyproxy:masterfrom
brian-pane:direct-response/2315

Conversation

@brian-pane
Copy link
Copy Markdown
Contributor

…-coded HTTP response.

envoyproxy/envoy#2315

Signed-off-by: Brian Pane bpane@pinterest.com

…-coded HTTP response.

envoyproxy/envoy#2315

Signed-off-by: Brian Pane <bpane@pinterest.com>
api/rds.proto Outdated
RedirectAction redirect = 3;

// [#not-implemented-hide:] Return an arbitrary HTTP response directly, without proxying.
DirectResponseAction response = 7;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Name the field as direct_response. Since it has no wire cost, readability wins.

api/rds.proto Outdated

// Specifies the content of the response body. If this setting is omitted,
// no body is included in the generated response.
string body = 4;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You probably want to use a real HTTP response with headers and body.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1. I would probably remove content_type and just put in a repeated list of headers to add. You should be able to use existing header list messages in this file.

api/rds.proto Outdated

// Specifies the human-readable status to be returned if
// the response is encoded as HTTP/1.x.
string reason = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Practically it's not going to be possible to actually use this. The HTTP/1.1 codec will select the reason based on the code for you and you can't set it. I would drop this.

api/rds.proto Outdated

// Specifies the content of the response body. If this setting is omitted,
// no body is included in the generated response.
string body = 4;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1. I would probably remove content_type and just put in a repeated list of headers to add. You should be able to use existing header list messages in this file.

api/rds.proto Outdated

// Specifies the content of the response body. If this setting is omitted,
// no body is included in the generated response.
string body = 4;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this should be a DataSource, so that it can either be a file on disk, or provided inline.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1 good idea.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There's a practical problem with DataSource: its inline value is of type bytes, which will require people using JSON configs to base64-encode the value.

Do you have any objection to me extending DataSource to support a string option, to save JSON users the trouble of base64-encoding?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, better if we can make it use one_of, which I think is wire compatible but @htuch and @wora will need to confirm.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mattklein123 I don't understand. DataSource is already one_of ( bytes, filepath ). What are you wanting to make one_of? I think @brian-pane was asking if he can add another field to the existing one-of so it has (bytes, filepath, string).

If I'm understanding correctly, I have no objection to that, but I don't know if there's any negative protobuf side-effects, such as other uses of DataSource having to check for another value in the one-of.

If I'm not understanding correctly, can someone clarify for me?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'm proposing to add a string to the existing one_of.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry I didn't look at DataSource, so didn't know if it already had one_of. Yes, go for it! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, this is fine. BTW, I'm moving DataSource around to its own distinct file in #398.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm happy to split out that part of the PR if it helps speed along this one.

…DataSource for body

Signed-off-by: Brian Pane <bpane@pinterest.com>
api/base.proto Outdated
string filename = 1 [(validate.rules).string.min_bytes = 1];

// Bytes inlined in the configuration.
bytes inline = 2 [(validate.rules).bytes.min_len = 1];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Name this inline_bytes. We don't have a backwards compatibility requirement for field names; in general we avoid churn, but it's fine to do this where it is a win.

Signed-off-by: Brian Pane <bpane@pinterest.com>
api/rds.proto Outdated

message DirectResponseAction {
// Specifies the HTTP response status to be returned.
google.protobuf.UInt32Value status = 1 [(validate.rules).message.required = true];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can this be uint32 instead of google.protobuf.UInt32Value?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, can we validate that it is >= 100 and < 600? (I don't know if that's even possible, but would be useful if it is)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There's a precedent for using plain uint32 and range limits here:
https://github.com/envoyproxy/data-plane-api/blob/master/api/filter/http/fault.proto#L22

@htuch is that considered a good pattern to use? (I don't know the history behind why some declarations use the simple int types and others use the google.protobuf.* types.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This came up in the newly minted STYLE.md: https://github.com/envoyproxy/data-plane-api/blob/master/STYLE.md

"Use wrapped scalar types where there is a real need for the field to have a default value that does not match the proto3 default (0/false/""). This should not be done for fields where the proto3 defaults make sense. All things being equal, pick appropriate logic, e.g. enable vs. disable for a bool field, such that the proto3 defaults work, but only where this doesn't result in API gymnastics."

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yep, +1 to @ggreenway comment above, we've been getting better at using unwrapped scalar types where it makes sense, so go for it.

…alidator

Signed-off-by: Brian Pane <bpane@pinterest.com>
ggreenway
ggreenway previously approved these changes Jan 5, 2018
htuch
htuch previously approved these changes Jan 5, 2018
api/rds.proto Outdated
uint32 status = 1 [(validate.rules).uint32 = {gte: 100, lt: 600}];

// Specifies headers to include in the HTTP response.
repeated HeaderValue response_headers = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It occurs to me that we already have response_headers_to_add on the route. Do we need this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If that's sufficient I might delete this and just put a comment in on body with a ref link to the other field and see it can be used for setting headers.

Signed-off-by: Brian Pane <bpane@pinterest.com>
@brian-pane brian-pane dismissed stale reviews from htuch and ggreenway via 8911835 January 5, 2018 23:10
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

nice, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants