Skip to content

adds x_header configuration option for use behind proxies #299

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

Closed
wants to merge 4 commits into from

Conversation

vlaurenzano
Copy link
Contributor

This passes the xheaders configuration option to tornado. The option informs tornado to use the forwarded X-Real-Ip header if given. Useful for when the kernelgateway is behind a proxy and you need the original ip (for logging for instance).

@vlaurenzano
Copy link
Contributor Author

I set it up as to not change current behavior (through a feature flag) but it probably makes sense to set it to true by default and maybe even forget the flag.

@rolweber
Copy link
Contributor

rolweber commented Aug 8, 2018

This looks like a very specific solution. I wonder if we could introduce something more generic instead. Notebook has a tornado_settings config option. Would that work for your xheaders configuration, too?

@vlaurenzano
Copy link
Contributor Author

Looking at Notebook now on your suggestion and it looks like they already have the xheaders flag. The tornado_settings option won't work because it's used for the Application and not the httpServer.

It seems notebook actually has an xheaders config:
https://github.com/jupyter/notebook/blob/7674331e3d10881ea6727e7c6c8daff78f405756/notebook/notebookapp.py#L1375

It looks like the tornado settings are used for the app and not the server:
https://github.com/jupyter/notebook/blob/7674331e3d10881ea6727e7c6c8daff78f405756/notebook/notebookapp.py#L1353

@rolweber
Copy link
Contributor

I see. Thanks for checking :-)

I'd appreciate if someone else also has a look at this before merging.

Copy link
Contributor

@rolweber rolweber left a comment

Choose a reason for hiding this comment

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

looks good to me

Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

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

@vlaurenzano - thank you for the contribution - this will be useful. I had a few comments, mostly along the lines of modeling this after the Notebook functionality.

Since we're in the process of building the 2.1.0 release, it would be great to get this in soon. I'd like to start cutting the release Monday or Tuesday next week. (8/13-14)

@@ -174,6 +174,16 @@ def allow_origin_default(self):
def expose_headers_default(self):
return os.getenv(self.expose_headers_env, '')

x_headers_env = 'KG_X_HEADERS'
x_headers = Unicode(config=True,
Copy link
Member

Choose a reason for hiding this comment

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

Since it sounds like this is providing the identical functionality to that provided in Notebook, then I suggest we use the same option name (and variable): trust_xheaders. This fits the boolean datatype better as well, since x_headers sounds more like a noun.

I also suggest using the Bool traitlet rather than Unicode. This should eliminate the need for strtobool and import.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I used unicode and not Bool is because it is coming from an env variable and it didn't say in the documentation whether it would cast from a string or how. There is also a CBool, for casting bool, however it seems like it only works for integers. I'll look into it and update it with Bool or CBool if appropriate.

Agree about the name, I didn't know it existed in notebook prior to implementing.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good. Once the updates are in, we'll merge. Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated the x_headers name to trust_xheaders. I ended up using both CBool and strtobool. Strtbool is necessary when the config is set as an environment variable. Since CBool only uses the python bool() function to cast, any non empy string value would make a positive value, such as 'false', 'no'... etc


@default('x_headers')
def x_headers_default(self):
return os.getenv(self.x_headers_env, 'false')
Copy link
Member

Choose a reason for hiding this comment

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

It may be a good idea to handle various formats for the env value, so something like this may work more reliably...

return bool(os.getenv(self.x_headers_env, 'false').lower() == 'true')

@@ -505,6 +515,7 @@ def init_http_server(self):
"""
ssl_options = self._build_ssl_options()
self.http_server = httpserver.HTTPServer(self.web_app,
xheaders=bool(strtobool(self.x_headers)),
Copy link
Member

Choose a reason for hiding this comment

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

Per above, I think we can eliminate the casts (and import) by using the traitlets - as Notebook did.

@kevin-bates kevin-bates mentioned this pull request Aug 10, 2018
8 tasks
Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

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

Looks good Vincent - thank you!

@kevin-bates
Copy link
Member

Squashed and merged - thanks again!

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.

3 participants