501 error when writing to stream via HTTP API

version: 3.4

I am trying to write to a not-yet existing eventStream in v 3.4 via the HTTP API.

http://docs.geteventstore.com/http-api/3.4.0/writing-to-a-stream/

Using curl to test, I submitted this

curl -v -k -u admin:adminpassword -d ‘[{“eventId”: “fbf4a1a1-b4a3-4dfe-a01f-ec52c34e16e4”,“eventType”: “AcceptedEvent”,“data”:{“url”: “https://my.example.com/pr/0815”, “correlationId”: “b27465e4-a058-406c-90d2-18c29b9f647c” }, “metadata”: {
“version”: 1 }}]’
-H “Content-Type:application/json” https://myhost.com/streams/mystream

Answer is:

Authorization: Basic YWRtaW46Y2hhbmdlaXQ=

User-Agent: curl/7.43.0

Accept: /

Content-Type:application/json

Content-Length: 219

  • upload completely sent off: 219 out of 219 bytes

  • HTTP 1.0, assume close after body

< HTTP/1.0 501 Unsupported method (‘POST’)

< Server: BaseHTTP/0.3 Python/2.7.9

< Date: Fri, 26 May 2017 07:26:13 GMT

< Content-Type: text/html

<

Error response

Error response

Error code 501.

Message: Unsupported method ('POST').

Error code explanation: 501 = Server does not support this operation.

-H “Content-Type:application/vnd.eventstore.events+json” did not work either.
-H “Accept …” did not result a positive result either.

501 points to a server-side error. What is going on there?

Server: BaseHTTP/0.3 Python/2.7.9

? is this via a proxy etc?

As far as I know, there is an SSL reverse proxy, yes.

and if you try directly to eventstore? this looks like an error from
the proxy though not 100% sure.

I tried it directly in the Docker Container / EventStore. Getting correct nginx Server now. No more 501. Curl now yields the following result

curl -v -k -d ‘[{“eventId”: “fbf4a1a1-b4a3-4dfe-a01f-ec52c34e16e4”,“eventType”: “AcceptedEvent”,“data”:{“url”: “https://my.system.com/pr/0815”, “correlationId”: “b27465e4-a058-406c-90d2-18c29b9f647c” }, “metadata”: { “version”: 1 }}]’ -H “Content-Type:application/vnd.eventstore.events+json” https://localhost/streams/mystream

  • Connected to localhost (127.0.0.1) port 443 (#0)
  • successfully set certificate verify locations:
  • CAfile: none
    CApath: /etc/ssl/certs
  • SSLv3, TLS handshake, Client hello (1):
  • SSLv3, TLS handshake, Server hello (2):
  • SSLv3, TLS handshake, CERT (11):
  • SSLv3, TLS handshake, Server key exchange (12):
  • SSLv3, TLS handshake, Request CERT (13):
  • SSLv3, TLS handshake, Server finished (14):
  • SSLv3, TLS handshake, CERT (11):
  • SSLv3, TLS handshake, Client key exchange (16):
  • SSLv3, TLS change cipher, Client hello (1):
  • SSLv3, TLS handshake, Finished (20):
  • SSLv3, TLS change cipher, Client hello (1):
  • SSLv3, TLS handshake, Finished (20):
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
  • Server certificate:
  •  SSL certificate verify ok.
    

POST /streams/printing HTTP/1.1
User-Agent: curl/7.38.0
Host: localhost
Accept: /
Content-Type:application/vnd.eventstore.events+json
Content-Length: 215

  • upload completely sent off: 215 out of 215 bytes
    < HTTP/1.1 400 Bad Request
  • Server nginx/1.6.2 is not blacklisted
    < Server: nginx/1.6.2
    < Date: Fri, 26 May 2017 10:21:08 GMT
    < Content-Type: text/html
    < Content-Length: 252
    < Connection: close
    <
400 No required SSL certificate was sent

400 Bad Request

No required SSL certificate was sent
nginx/1.6.2

With other Docker applications that expose REST endpoints, I was always able to connect this way. Not here, though.

Addendum: I will try supplying the p12 cert file. However, with curl -k, that should not really be necessary.

Sven

Using HTTPS and Certificate, I get a 400 No required SSL certificate was sent.

curl -k -v -cert /certificates/client.p12 -d ‘[{“eventId”: “fbf4a1a1-b4a3-4dfe-a01f-ec52c34e16e5”,“eventType”: “AcceptedEvent”,“data”:{“url”: “https://mysystem.com/pr/0815”, “correlationId”: “b27465e4-a058-406c-90d2-18c29b9f647c” }, “metadata”: { “version”: 1 }}]’ -H “Content-Type:application/vnd.eventstore.events+json” https://localhost:32772/streams/mystream

  • malformed
  • Closing connection -1
    curl: (3) malformed
  • Hostname was NOT found in DNS cache
  • Trying 127.0.0.1…
  • Connected to localhost (127.0.0.1) port 443 (#0)
  • successfully set certificate verify locations:
  • CAfile: none
    CApath: /etc/ssl/certs
  • SSLv3, TLS handshake, Client hello (1):
  • SSLv3, TLS handshake, Server hello (2):
  • SSLv3, TLS handshake, CERT (11):
  • SSLv3, TLS handshake, Server key exchange (12):
  • SSLv3, TLS handshake, Request CERT (13):
  • SSLv3, TLS handshake, Server finished (14):
  • SSLv3, TLS handshake, CERT (11):
  • SSLv3, TLS handshake, Client key exchange (16):
  • SSLv3, TLS change cipher, Client hello (1):
  • SSLv3, TLS handshake, Finished (20):
  • SSLv3, TLS change cipher, Client hello (1):
  • SSLv3, TLS handshake, Finished (20):
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
  • Server certificate:
  •  SSL certificate verify ok.
    

POST /streams/printing HTTP/1.1
User-Agent: curl/7.38.0
Host: localhost
Accept: /
Content-Type:application/vnd.eventstore.events+json
Content-Length: 215

  • upload completely sent off: 215 out of 215 bytes
    < HTTP/1.1 400 Bad Request
  • Server nginx/1.6.2 is not blacklisted
    < Server: nginx/1.6.2
    < Date: Fri, 26 May 2017 10:52:50 GMT
    < Content-Type: text/html
    < Content-Length: 252
    < Connection: close
    <
400 No required SSL certificate was sent

400 Bad Request

No required SSL certificate was sent
nginx/1.6.2 * Closing connection 0 * SSLv3, TLS alert, Client hello (1):

Using http, all works as intended

curl -v -d ‘[{“eventId”: “fbf4a1a1-b4a3-4dfe-a01f-ec52c34e16e5”,“eventType”: “AcceptedEvent”,“data”:{“url”: “https://my.oms.com/pr/0815”, “correlationId”: “b27465e4-a058-406c-90d2-18c29b9f647c” }, “metadata”: { “version”: 1 }}]’ -H “Content-Type:application/vnd.eventstore.events+json” http://localhost:2113/streams/mystream

  • Hostname was NOT found in DNS cache
  • Trying 127.0.0.1…
  • Connected to localhost (127.0.0.1) port 2113 (#0)

POST /streams/printing HTTP/1.1
User-Agent: curl/7.38.0
Host: localhost:2113
Accept: /
Content-Type:application/vnd.eventstore.events+json
Content-Length: 215

  • upload completely sent off: 215 out of 215 bytes
    < HTTP/1.1 201 Created
    < Access-Control-Allow-Methods: POST, DELETE, GET, OPTIONS
    < Access-Control-Allow-Headers: Content-Type, X-Requested-With, X-Forwarded-Host, X-PINGOTHER, Authorization, ES-LongPoll, ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequiresMaster, ES-HardDelete, ES-ResolveLinkTo, ES-ExpectedVersion
    < Access-Control-Allow-Origin: *
    < Access-Control-Expose-Headers: Location, ES-Position
    < Location: http://localhost:2113/streams/printing/1
    < Content-Type: text/plain; charset=utf-8
  • Server Mono-HTTPAPI/1.0 is not blacklisted
    < Server: Mono-HTTPAPI/1.0
    < Date: Fri, 26 May 2017 11:00:54 GMT
    < Content-Length: 0
    < Keep-Alive: timeout=15,max=100

Hello Greg, Currently, the Docker Container has run-node.sh --ext-http-prefixes=http://*:2113/ --ext-ip=0.0.0.0 --db /persistent/db --log /persistent/logs --run-projections=all

To enable SSL for the engine, is it necessary to specify the SSL Port with --ext-sec-tcp-port ?

--ext-sec-tcp-port involves ssl over tcp. are you trying to do ssl
from nginx to eventstore or terminating at nginx?

Hello Greg

This is the current nginx config:

server {
listen 443 ssl default_server;
ssl_certificate /certificates/server.pem;
ssl_certificate_key /certificates/server.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    server_name eventstore.mydomain

    location / {
            proxy_pass          http://127.0.0.1:2113;
    proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    }

}

I gather that 443 should be exposed, yet I cannot connect using https and curl from outside the Docker network using sniproxy.
SSL should not terminate at nginx.

Currently, eventstore is initialized with command=./run-node.sh --ext-http-prefixes=http://*:2113/ --ext-ip=0.0.0.0 --db /persistent/db --log /persistent/logs --run-projections=all

Port 443 is not exposed in the Dockerfile definition.

The SNI reverse proxy is a seperate component, terminates TLS, and it forwards the unencrypted traffic to the Docker container running EventStore.

I am asking myself if, in such a scenario, the nginx forwarding from EventStore HTTP Port to port 443 is even necessary.

likely no and you def want http not https to 2113 in your config, that
could be where the issue is coming up.

Hello Greg

Does that mean there is no way to use https for communication with the HTTP-API?

Sven

no it means you would need to configure it.

port 2113 in the default settings is http

Hi Greg

Currently, there is an nginx configuration that proxy-passes all requests from listening port 443 to the internal http address http://127.0.0.1:2113 on port 2113.

However, this is where curl returns 501. I am relatively new to EventStore, how can this be made to work? Is there something missing with regards to eventstore and nginx in order to have
access via https?

server {
listen 443 ssl default_server;
ssl_certificate /certificates/server.pem;
ssl_certificate_key /certificates/server.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!

CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;

    server_name eventstore.mydomain

    location / {
            proxy_pass          [http://127.0.0.1:2113](http://127.0.0.1:2113);
    proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Port 443;
        proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    }

}

Hey Greg,

i’m very certain it’s not related to EventStore as Sven is running into an another issue with his setup with eventstore in our company. I will look at it with him.

Thanks a lot for helping.

-Alessandro