Wrong response data when using global
When response data is sent by setting httprsp
to a global reference then the server sometimes includes extra incorrect data.
Example from _ydbwebapi.m
:
gloreturn ; GET /test/gloreturn - Used by Unit Tests to ensure Global deleted properly
set httprsp=$name(^web("%ydbwebapi"))
...
In this case the only data for subscript "%ydbwebapi"
and its nested subscripts should be included in the result.
But the server includes also sibling subscripts to "%ydbwebapi"
.
How to reproduce
gloreturn^%ydbwebapi
uses a global reference as response data and can be used to demonstrate the problem.
-
Start the web server:
yottadb -run start^%ydbwebreq
-
Run:
$ ydb -run ^%XCMD 'kill ^web set ^web("z")="WRONG DATA" zwr ^web'
^web("z")="WRONG DATA"
- Run:
~$ printf 'GET /test/gloreturn HTTP/1.1\r\n\r\n' | nc localhost 9080
HTTP/1.1 200 OK
Date: Fri, 01 Mar 2024 08:35:00 GMT
Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: *
Content-Length: 15
coo
boo
foo
WRONG DATA
The string WRONG DATA
should not be included in the output. gloreturn
should only return data in ^web("%ydbwebapi")
, but because of the bug the data in ^web("z")
is also included.
Note: Curl does not display the incorrect data. Because of that nc
is used here.
Consequence
This problem is tricky because the HTTP request that produced the error will succeed without problem. The string WRONG DATA
will be sent from the server, but because Content-Length
is computed correctly WRONG DATA
will not be read by the client.
Instead the response to the next request will start with the string WRONG DATA
.
Most web clients will try to interpret WRONG DATA
as the start of the next response, and report it as some variant of "invalid HTTP response".
Curl does not report this at all for some reason. I don't understand why.
Incorrect code
This code loops using $query
to read the response data in the global. There is logic there to exit the loop but it doesn't seem to work correctly.
M Web Server version
3.2.1
Other
We encountered this with an old version of the web server which saved custom error responses to ^TMP("HTTPERR",$job,...)
.
The work around for us was to upgrade to a slightly newer version which saves custom error responses in HTTPRSP
directly. But the underlying problem remains, even if it is not urgent for us.