Bug 125

Summary: /instances/{id} returns 500 on invalid HTTP Method
Product: Orthanc Reporter: Sébastien Jodogne <s.jodogne>
Component: Orthanc CoreAssignee: Sébastien Jodogne <s.jodogne>
Status: RESOLVED FIXED    
Severity: enhancement    
Priority: ---    
Version: unspecified   
Hardware: All   
OS: All   

Description Sébastien Jodogne 2020-06-29 15:15:03 CEST
[BitBucket user: Michael Hobbs]
[BitBucket date: 2019-01-12.20:13:39]

What steps will reproduce the problem? 

```
#!text
1. Open Chrome to Orthanc Explorer
2. F12 > Console > fetch('http://127.0.0.1:8042/instances/60cb7e45-1a6e449a-92f753db-b1717939-a410c810', {method: 'DEL'})

```

What is the expected output? 400 Bad Request

What do you see instead? 500 (Server Error)

What version of the product are you using? On what operating system? osimis/orthanc:18.12.2
Comment 1 Sébastien Jodogne 2020-06-29 15:23:37 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-13.10:58:15]

The request runs fine using command-line curl:

```
$ curl -v http://localhost:8042/instances/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5 -X DELETE
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8042 (#0)
> DELETE /instances/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5 HTTP/1.1
> Host: localhost:8042
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Content-Length: 34
< 
{
   "RemainingAncestor" : null
}
* Connection #0 to host localhost left intact

$ curl -v http://localhost:8042/instances/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5 -X DELETE
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8042 (#0)
> DELETE /instances/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5 HTTP/1.1
> Host: localhost:8042
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Content-Length: 0
< 
* Connection #0 to host localhost left intact
```

As shown in the Chrome log, your issue is related to CORS and is due to the fact that you are using the Chrome debugger:

```
fetch('http://127.0.0.1:8042/instances/60cb7e45-1a6e449a-92f753db-b1717939-a410c810', {method: 'DEL'})
Promise {<pending>, nr@context: r}
OPTIONS http://127.0.0.1:8042/instances/60cb7e45-1a6e449a-92f753db-b1717939-a410c810 400 (Bad Request)
Access to fetch at 'http://127.0.0.1:8042/instances/60cb7e45-1a6e449a-92f753db-b1717939-a410c810' from origin 'https://bitbucket.org' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

Reference: http://book.orthanc-server.com/faq/same-origin.html
Comment 2 Sébastien Jodogne 2020-06-29 15:23:38 CEST
[BitBucket user: Michael Hobbs]
[BitBucket date: 2019-01-13.15:38:04]

Sébastien, apologizes for not better explaining this. I used a made-up example with Chrome and if you don't follow it exactly you will get a CORS error and not the 500 error.

I found this error when I made a typo on a fetch setting the method to DEL and not DELETE. DEL is not a valid HTTP method but fetch in Chrome and Node's node-fetch library both allow you to use a non-standard value. Whether or not this is also an issue with the implementation of fetch, Orthanc should correctly handle it.


```
#!text
To generate this bug in Chrome and not get a CORS error do the following.
1. Close all Chrome windows to ensure the steps are followed correctly.
2. Open Chrome to a locally running Orthanc, http://localhost:8042/app/explorer.html
3. Press F12 to bring up the Chrome Dev tools.
4. If not selected, select the Console tab
5. run: fetch(`${location.origin}/instances/60cb7e45-1a6e449a-92f753db-b1717939-a410c810`, {method: 'NOTVALID'}).then(res => console.log(`Status Code: ${res.status}  Status Text: ${res.statusText}`))

```


```
#!text
Additionally, I have created a "Minimal, Complete, and Verifiable example"
repo: https://github.com/MichaelLeeHobbs/bugReports
requirements: Docker and Docker Compose
cmd: cd orthanc_125; ./start.sh

```
Comment 3 Sébastien Jodogne 2020-06-29 15:23:39 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-13.16:12:15]

Sorry, but I will only investigate this issue once you provide me with a simple curl command-line to reproduce it. I will not debug stuff related to node.js.
Comment 4 Sébastien Jodogne 2020-06-29 15:23:40 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-13.16:17:33]

Is the following one-liner using curl an illustration of your issue ("NOPE" being an invalid HTTP method)?

```
$ curl http://localhost:8042/system -X NOPE -v
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8042 (#0)
> NOPE /system HTTP/1.1
> Host: localhost:8042
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 500 Server Error
< Content-Length: 43
< Connection: close
< 
Error 500: Server Error
* Closing connection 0
```
Comment 5 Sébastien Jodogne 2020-06-29 15:23:42 CEST
[BitBucket user: Michael Hobbs]
[BitBucket date: 2019-01-13.16:47:35]

Yes and this is not a Node issue, I used Node to demonstrate the issue.
Comment 6 Sébastien Jodogne 2020-06-29 15:23:43 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-13.16:50:54]

OK, re-opening
Comment 7 Sébastien Jodogne 2020-06-29 15:23:44 CEST
[BitBucket user: Michael Hobbs]
[BitBucket date: 2019-01-13.16:51:34]

Note: curl http://www.google.com -X NOPE -v returns 405, either 400 or 405 would likely be a good response but not 500.
Comment 8 Sébastien Jodogne 2020-06-29 15:23:44 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-13.19:39:21]

The issue is not within Orthanc, but within Mongoose (its embedded HTTP server). When Orthanc is built against Civetweb, I get:

```
$ curl http://localhost:8042/system -X NOPE -v
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8042 (#0)
> NOPE /system HTTP/1.1
> Host: localhost:8042
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< Cache-Control: no-cache, no-store, must-revalidate, private, max-age=0
< Pragma: no-cache
< Expires: 0
< Content-Type: text/plain; charset=utf-8
< Date: Sun, 13 Jan 2019 19:36:48 GMT
< Connection: close
< 
Error 400: Bad Request
```

The solution is thus to add option `-DENABLE_CIVETWEB=ON` when calling CMake.
Comment 9 Sébastien Jodogne 2020-06-29 15:23:46 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-14.12:11:50]

Fix issue #125 (Mongoose: /instances/{id} returns 500 on invalid HTTP Method)

→ https://hg.orthanc-server.com/orthanc/changeset/8f2bda0719f4
Comment 10 Sébastien Jodogne 2020-06-29 15:23:47 CEST
[BitBucket user: Sébastien Jodogne]
[BitBucket date: 2019-01-14.12:13:18]

Fix issue #125 (Mongoose: /instances/{id} returns 500 on invalid HTTP Method)

→ https://hg.orthanc-server.com/orthanc/changeset/a323b75e5b08