Title:
[ANeff] Bug for: RestSetResponse() ignored if returntype non-void (CF-3546046 regression)
| View in TrackerStatus/Resolution/Reason: Closed/Fixed/Fixed
Reporter/Name(from Bugbase): Aaron Neff / Aaron Neff ()
Created: 02/01/2017
Components: REST Services
Versions: 2016
Failure Type: Incorrectly functioning
Found In Build/Fixed In Build: 2016.0.01.298513 / 2018.0.0.303768
Priority/Frequency: Normal / Some users will encounter
Locale/System: / Win All
Vote Count: 1
History: The fix for CF-3546046 allows RestSetResponse() to be used even when the containing functions returntype is non-void. Good.
Issue: The fix for CF-3546046 introduced a regression wherein RestSetResponse() is ignored if the containing function's returntype non-void. Bad.
Repro:
1) Run index.cfm
2) Run mypage.cfm
Application.cfc
--------------------------------------------
component {
THIS.name = "ticket_3546046NotFixedProperly";
THIS.secureJSONPrefix="";
THIS.mappings["/mymapping"] = expandPath("./");
THIS.restSettings.skipCFCWithError = true;
public void function onApplicationStart() {
restInitApplication("/mymapping", "MyRestApp");
}
public boolean function onRequestStart() {
if(structKeyExists(URL, "reinit")) {
applicationStop();
location(url='http://' & CGI.HTTP_HOST & getDirectoryFromPath(CGI.SCRIPT_NAME));
}
return true;
}
}
--------------------------------------------
index.cfm (empty file)
MyCFC.cfc
--------------------------------------------
component rest="true" restpath="cfcrestpath" {
remote void function returnVoid(string foobar restargsource="path") httpmethod="GET" restpath="void/{foobar}" produces="application/json" {
var response = {status=404, content=serializeJSON({message="Not Found"}), headers={myHeader=ARGUMENTS.foobar}};
if(ARGUMENTS.foobar is "foo") {
response.status = 200;
response.content = serializeJSON({message="Found"});
}
restSetResponse(response);
}
remote struct function returnNonVoid(string foobar restargsource="path") httpmethod="GET" restpath="nonvoid/{foobar}" produces="application/json" {
var response = {status=404, content=serializeJSON({message="Not Found"}), headers={myHeader=ARGUMENTS.foobar}};
if(ARGUMENTS.foobar is "foo") {
response.status = 200;
response.content = serializeJSON({message="Found"});
}
restSetResponse(response);
return response;
}
}
--------------------------------------------
mypage.cfm
--------------------------------------------
<cfscript>
//test 1
cfhttp(url='http://' & CGI.HTTP_HOST & '/rest/myrestapp/cfcrestpath/void/foo');//Filecontent is {"MESSAGE":"Found"} (good)
writeDump(CFHTTP);
//test 2
cfhttp(url='http://' & CGI.HTTP_HOST & '/rest/myrestapp/cfcrestpath/void/bar');//Filecontent is {"MESSAGE":"Not Found"} (good)
writeDump(CFHTTP);
//test 3
cfhttp(url='http://' & CGI.HTTP_HOST & '/rest/myrestapp/cfcrestpath/nonvoid/foo');//Filecontent is {"STATUS":200,"HEADERS":{"MYHEADER":"foo"},"CONTENT":"{\"MESSAGE\":\"Found\"}"} (bad - should return same as test 1)
writeDump(CFHTTP);
//test 4
cfhttp(url='http://' & CGI.HTTP_HOST & '/rest/myrestapp/cfcrestpath/nonvoid/bar');//Filecontent is {"STATUS":404,"HEADERS":{"MYHEADER":"bar"},"CONTENT":"{\"MESSAGE\":\"Not Found\"}"} (bad - should return same as test 2)
writeDump(CFHTTP);
myCFC = new MyCFC();
//test 5
writeDump(serializeJSON(myCFC.returnNonVoid(foobar="foo")));//returns {"STATUS":200,"HEADERS":{"MYHEADER":"foo"},"CONTENT":"{\"MESSAGE\":\"Found\"}"} (good)
//test 6
writeDump(serializeJSON(myCFC.returnNonVoid(foobar="bar")));//returns {"STATUS":404,"HEADERS":{"MYHEADER":"bar"},"CONTENT":"{\"MESSAGE\":\"Not Found\"}"} (good)
</cfscript>
--------------------------------------------
Actual result: If a non-void REST method is invoked directly, RestSetResponse() is ignored and the function returns its result variable (good). If a non-void REST method is invoked via HTTP, RestSetResponse() is ignored and the function returns its result variable (bad).
Expected result: If a non-void REST method is invoked directly, RestSetResponse() is ignored and the function returns its result variable. If a non-void REST method is invoked via HTTP, ColdFusion ignores the function's return value and uses the response set using the RestSetResponse() function.
For more details regarding actual and expected results, see comments in mypage.cfm.
Attachments:
Comments: