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

wsgi: Middleware for delaying and rejecting requests #7

Closed
underyx opened this issue May 30, 2019 · 1 comment · Fixed by #12
Closed

wsgi: Middleware for delaying and rejecting requests #7

underyx opened this issue May 30, 2019 · 1 comment · Fixed by #12
Assignees
Milestone

Comments

@underyx
Copy link
Contributor

underyx commented May 30, 2019

Behavior

Based on system clock, do the following:

Before July 24th 13:00 UTC

Nothing.

After July 24th 13:00 UTC

Upon request, start counting request time.

Upon successful response, if the request didn't have a KW-RFC-22 compliant User-Agent header, sleep for as long as the request took, to double the response time.

After August 1st 13:00 UTC

Upon request, if the request didn't have a KW-RFC-22 compliant User-Agent header, return an HTTP 400 error explaining the User-Agent requirements.

Implementation

I recommend using https://docs.pylonsproject.org/projects/webob/en/stable/api/dec.html#webob.dec.wsgify.middleware here.

We should make the following configurable:

  • the cutoff datetimes, so we can test on a smaller batch of services

We should document the following clearly:

  • if sleep is blocking in the users' app, this could introduce overloading for their service
@underyx underyx changed the title wsgi: MIddleware for delaying and rejecting requests wsgi: Middleware for delaying and rejecting requests May 30, 2019
@underyx underyx added this to the 0.2.0 milestone May 30, 2019
@paveldedik paveldedik self-assigned this Jun 5, 2019
@paveldedik
Copy link
Contributor

paveldedik commented Jun 5, 2019

OK, so my idea for this is something like this:

USER_AGENT_RE = re.compile(
    r"^(?P<name>\S.+?)\/(?P<version>\S.+?) \(Kiwi\.com (?P<environment>\S.+?)\)(?: ?(?P<system_info>.*))$"
)

@wsgify.middleware
def restrict_user_agent(req, app):
    if not USER_AGENT_RE.match(req.user_agent):
        return webob.exc.HTTPForbidden("Bad User-Agent: see Kiwi.com RFC #22")
    return app


@wsgify.middleware
def slowdown_requests(req, app):
    if USER_AGENT_RE.match(req.user_agent):
        return app

    now = time.time()
    resp = req.get_response(app)
    seconds = time.time() - now
    time.sleep(seconds)
    return resp

In case of flask, we can add the middlewares like this:

app = Flask(__name__)

app.wsgi_app = slowdown_requests(app.wsgi_app)

app.run()

Now the question is, if it's better to have one middleware which slowdowns/refuses requests based on the time, or have several of them which are picked when the app is started (this can be a problem as the middleware won't be applied until the app workers are restarted).

I think creating one middleware is the better option.

paveldedik added a commit that referenced this issue Jun 24, 2019
- Fix #7

Co-Authored-By: Bence Nagy <bence@underyx.me>
paveldedik added a commit that referenced this issue Jun 26, 2019
- Fix #7

Co-Authored-By: Bence Nagy <bence@underyx.me>
underyx added a commit that referenced this issue Jun 26, 2019
- Fix #7

Co-Authored-By: Bence Nagy <bence@underyx.me>
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 a pull request may close this issue.

2 participants