StackStorm / st2

StackStorm (aka "IFTTT for Ops") is event-driven automation for auto-remediation, incident responses, troubleshooting, deployments, and more for DevOps and SREs. Includes rules engine, workflow, 160 integration packs with 6000+ actions (see https://exchange.stackstorm.org) and ChatOps. Installer at https://docs.stackstorm.com/install/index.html
https://stackstorm.com/
Apache License 2.0
6.07k stars 749 forks source link

Support HEAD requests for Webhook endpoints #2929

Open skjbulcher opened 8 years ago

skjbulcher commented 8 years ago

Webhook endpoints do not appear to support HEAD requests. Different services use HEAD to validate a webhook URL prior permitting it to be registered, e.g. Trello. Supporting HEAD requests seams to be a generally accepted component of a properly developed webhooks system.

As an example, I set up a webhook at /api/v1/webhooks/trello and performed two requests against it:

HEAD Request

Status: 404 Headers:

Access-Control-Allow-Headers →Content-Type,Authorization,X-Auth-Token,St2-Api-Key,X-Request-ID
Access-Control-Allow-Methods →GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin →http://127.0.0.1:3000
Access-Control-Expose-Headers →Content-Type,X-Limit,X-Total-Count,X-Request-ID
Connection →keep-alive
Content-Length →57
Content-Type →application/json
Date →Tue, 27 Sep 2016 23:03:11 GMT
Server →nginx/1.10.1

GET Request:

Status: 200 Body:

{
  "uid": "trigger:core:b3d0af1a-5535-4fad-8345-b91a8fd3ffbf:8f44bbbb76667c8e5ab60e05b708d2e2",
  "parameters": {
    "url": "trello"
  },
  "name": "b3d0af1a-5535-4fad-8345-b91a8fd3ffbf",
  "type": "core.st2.webhook",
  "id": "57eac1a8250e5a030d81cbb0",
  "pack": "core"
}

Headers:

Access-Control-Allow-Headers →Content-Type,Authorization,X-Auth-Token,St2-Api-Key,X-Request-ID
Access-Control-Allow-Methods →GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin →http://127.0.0.1:3000
Access-Control-Expose-Headers →Content-Type,X-Limit,X-Total-Count,X-Request-ID
Connection →keep-alive
Content-Length →252
Content-Type →application/json; charset=UTF-8
Date →Tue, 27 Sep 2016 23:26:46 GMT
Front-End-Https →on
Server →nginx/1.10.1
X-Content-Type-Options →nosniff
X-Request-ID →39ced76e-47ad-473b-9c39-0588a19d549c
skjbulcher commented 8 years ago

I've come up with a hack that seems to allow the requests to be recognized. The theory is simple: proxy HEAD requests as GET requests when they attempt to hit a webhook URL. The hack is comprised of a new named location in the nginx config, as well as an edit to the location /api/ section. The relevant sections appear below:

  # StackStorm does not support HEAD requests for webhooks. This is a hack
  # that proxies HEAD requests as GET requests for webhook URLs. Related
  # edits appear in the `location /api/` section and are commented with
  # "HEAD METHOD WEBHOOK EDIT"
  location @headrequestnotfoundError {
    add_header X-Method-Requested $request_method always;

    rewrite ^/api/(.*)  /$1 break;

    proxy_pass            http://127.0.0.1:9101;
    proxy_method          GET;
    proxy_read_timeout    90;
    proxy_connect_timeout 90;
    proxy_redirect        off;

    proxy_set_header      Host $host;
    proxy_set_header      X-Real-IP $remote_addr;
    proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_set_header Connection '';
    chunked_transfer_encoding off;
    proxy_buffering off;
    proxy_cache off;
    proxy_set_header Host $host;
  }

  location /api/ {
    error_page 502 = @apiError;

    # HEAD METHOD WEBHOOK EDIT
    proxy_intercept_errors on;
    if ($request_uri ~* ^/api/v1/webhooks/) {
      set $test  "webhook url";
    }
    if ($request_method = HEAD) {
      set $test  "$test + HEAD request";
    }
    if ($test = "webhook url + HEAD request") {
      error_page 404 = @headrequestnotfoundError;
    }

    rewrite ^/api/(.*)  /$1 break;

    proxy_pass            http://127.0.0.1:9101/;
    proxy_read_timeout    90;
    proxy_connect_timeout 90;
    proxy_redirect        off;

    proxy_set_header      Host $host;
    proxy_set_header      X-Real-IP $remote_addr;
    proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_set_header Connection '';
    chunked_transfer_encoding off;
    proxy_buffering off;
    proxy_cache off;
    proxy_set_header Host $host;
  }

Obviously this does not address the actual issue, but it is a workaround for those who are unable to set up webhooks because of this StackStorm issue.

Kami commented 8 years ago

Yeah, I'm fine with supporting HEAD as well. It could simply be an alias (aka behave the same) for GET, right?

Edit: With that I mean making the st2 code change for an "alias".

skjbulcher commented 8 years ago

The change is working for my use case, but I don't think HEAD is supposed to return the content body. There may be other differences between HEAD and GET that I am not aware of.

enykeev commented 7 years ago

We also have a similar problem in #2561. By this logic, GET should be treated same as POST while HEAD should act more like OPTIONS as in return 2xx code, but not create a trigger instance.