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

Provide some way to patch SERVER_SOFTWARE universally #3607

Closed
nicktimko opened this issue Feb 13, 2019 · 7 comments
Closed

Provide some way to patch SERVER_SOFTWARE universally #3607

nicktimko opened this issue Feb 13, 2019 · 7 comments

Comments

@nicktimko
Copy link
Contributor

Long story short

I'd like some way to globally alter the User-Agent and Server headers for an application without needing to patch many instances of clients and applications. In order to do so, the cleanest route I've divined is to add the User-Agent headers onto ClientSession instances at instantation and a middleware to all Applications to patch all responses with an updated Server header.

Actual behaviour

The below monkeypatch doesn't work because during the import processing, it will trigger importing of aiohttp which ends up importing client_reqrep, and web_response before I can change the attribute of aiohttp.http.

import aiohttp.http.SERVER_SOFTWARE
aiohttp.http.SERVER_SOFTWARE = "my-app"

Actually, now that I think about it, I could do the below, but it feels even worse than reaching into the one place.

from aiohttp import client_reqrep, web_response

client_reqrep.SERVER_SOFTWARE = "my-app"
web_response.SERVER_SOFTWARE = "my-app"

The security conscious that don't have proxies that would strip off the header could also blank it out, e.g. #270

Rough solution routes

Have the two uses of SERVER_SOFTWARE instead pull it out of the http subpackage on use, rather than on import. This will allow easier patching of aiohttp.http.SERVER_SOFTWARE in one place. This is simple enough I could submit a PR if it has a hope.

Add a default user-agent/server attribute to the ClientSession/Application classes that could be monkey patched? I could look at this and maybe PR it...

Something else?

@aio-libs-bot
Copy link

GitMate.io thinks the contributor most likely able to help you is @asvetlov.

Possibly related issues are #836 (Provide a way to associate context with requests), #279 (Provide a way to retrieve 5xx error codes), #752 (There is no way to 'del_route'), #2106 (Warnings should provide a stacklevel), and #3459 (Recommended way to run background tasks).

@asvetlov
Copy link
Member

asvetlov commented Feb 14, 2019

I suggest adding app.on_repsonse_prepare signal.
In the signal you can setup Server HTTP header for a response.
aiohttp adds default Server only if the value is not specified explicitly.

Does it solve your needs?

@nicktimko
Copy link
Contributor Author

I'm unsure if that will effect all subapps, but I'm fairly sure it won't label any ClientSession's.

@ultrafunkamsterdam
Copy link

Hacky solution but it seems to work

import aiohttp
aiohttp.http.SERVER_SOFTWARE = 'someserver'
from aiohttp import web
app = web.Application()
web.run_app(app)

image

@kwatsen
Copy link

kwatsen commented Jan 29, 2020

I'd like a way to suppress the "Server" response header altogether.

RFC 7231, Section 7.4.2 says:

An origin server MAY generate a Server field in its responses.

So it's allowed for "Server" header field to be absent.

aiohttp/web_response.py line 391-393

        headers.setdefault(hdrs.CONTENT_TYPE, 'application/octet-stream')
        headers.setdefault(hdrs.DATE, rfc822_formatted_time())
        headers.setdefault(hdrs.SERVER, SERVER_SOFTWARE)

Which shows that there is no way to exclude it if desired.

As it is, I'm using "hack" suggested by ultrafunkamsterdam to set it to a less revealing value.

UPDATE:

I wrote too soon, I was unable to get the "hack" to work, but I was able to get the on_response_prepare signal to work.

@asvetlov
Copy link
Member

app.on_repsonse_prepare is the official solution.
You are free to use any hack that works for you but the library may change its internals and thus break your hack at any time.

Closing the issue.

@nicktimko
Copy link
Contributor Author

@asvetlov the hypothetical setting also serves for HTTP clients though; I would be able to globally configure User-Agent headers in reusable libs with their own clients. The app.on_response_prepare is HTTP server only.

Let me know if it's just a very distant priority/won't have time to implement it (I could PR it at some point...) vs. opposed in principle to the idea (PR doomed to be rejected).

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

No branches or pull requests

5 participants