debug
This commit is contained in:
+453
-8
@@ -67,15 +67,17 @@
|
||||
variables.framework.disableDashboard = false;
|
||||
variables.framework.unhandledPaths = "/flex2gateway";
|
||||
variables.framework.allowCrossDomain = true; // соответствующие заголовки, включая Access-Control-Allow-Origin выставляются только при наличии заголовка origin в реквесте
|
||||
//variables.framework.allowCrossDomain = ""; // перепишем явно, возвращая Origin
|
||||
|
||||
variables.framework.globalHeaders = structNew();
|
||||
variables.framework.globalHeaders["Access-Control-Expose-Headers"] = "Location";
|
||||
variables.framework.globalHeaders["Access-Control-Allow-Credentials"] = "true";
|
||||
//variables.framework.globalHeaders["Access-Control-Allow-Origin"] = "*"; //*** не знаю, нужно ли - но просили этот заголовок
|
||||
//variables.framework.globalHeaders["X-MY-HEADER"] = "my header value for example";
|
||||
|
||||
//variables.framework.docs={};
|
||||
variables.framework.docs.APIName="MMS API";
|
||||
variables.framework.docs.APIVersion="3.26";
|
||||
variables.framework.docs.APIName="Deck API";
|
||||
variables.framework.docs.APIVersion="0.01";
|
||||
|
||||
request.UNDEFINED_USR_ID=-1;
|
||||
request.ANONYMOUS_USR_ID=2;
|
||||
@@ -92,12 +94,12 @@
|
||||
<cfreturn super.onApplicationStart() />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="onRequest">
|
||||
<!--- <cffunction name="onRequest">
|
||||
<cfargument name="template" type="string" required="true"/>
|
||||
<cfset request.startTickCount=getTickCount()/>
|
||||
<!---<cfheader name="Access-Control-Allow-Origin" value="*"/>--->
|
||||
<cfreturn super.onRequest(template) />
|
||||
</cffunction>
|
||||
</cffunction> --->
|
||||
|
||||
<cfscript>
|
||||
|
||||
@@ -127,8 +129,14 @@
|
||||
////////////////////////////////////////////////
|
||||
// самым грубым образом получаем данные от IDP, не обрабатывая исключения
|
||||
|
||||
if (UCase(arguments.verb) EQ 'OPTIONS') return true;
|
||||
|
||||
//if (variables.framework.allowCrossDomain EQ "") {
|
||||
//corsHeaders(); // *** нужно, чтобы variables.framework.allowCrossDomain="" иначе задвоятся заголовки
|
||||
//}
|
||||
|
||||
//if (UCase(arguments.verb) EQ 'OPTIONS') return newRepresentation().noData().withStatus("204","No Data").withHeaders({"Content-Type":"application/json;charset=utf-8"});
|
||||
if (UCase(arguments.verb) EQ 'OPTIONS') return true;
|
||||
return true;
|
||||
var auth="";
|
||||
if (structKeyExists(headers,"Authorization")) {
|
||||
auth=headers.Authorization;
|
||||
@@ -141,8 +149,7 @@
|
||||
httpService.addParam(type = "HEADER", name = "Authorization", value = "#auth#"); //passthrough
|
||||
var resp = httpService.send();
|
||||
var result = resp.getPrefix().filecontent;
|
||||
//writeDump(result); abort;
|
||||
|
||||
//writeDump(result); abort;
|
||||
var idpUserData=deserializeJson(result);
|
||||
arguments.requestArguments.companyUid=idpUserData.companyId;
|
||||
arguments.requestArguments.usrUid=idpUserData.contactId;//userId; //GUID!
|
||||
@@ -151,7 +158,7 @@
|
||||
if (structIsEmpty(usrCustomerInfo)) return representationOf("Cannot find default specification for current user #result#").withStatus(422);
|
||||
arguments.requestArguments.usrId=usrCustomerInfo.usrId; //Integer!
|
||||
arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //Integer
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -267,6 +274,7 @@
|
||||
|
||||
|
||||
<cffunction name="getUsrCustomerInfo">
|
||||
|
||||
<cfargument name="usrUid"/>
|
||||
<!--- глупейшее определение спецификации по умолчанию (надо переделать, чтобы создавалась, или вообще просто записывать факты без спеки). Но помним, что при постановке на тестирование цены еше не фиксированы --->
|
||||
<!--- заметим, что у нас контрагент может быть определен параллельно, от IDP --->
|
||||
@@ -290,4 +298,441 @@
|
||||
</cfif>
|
||||
</cffunction>
|
||||
|
||||
|
||||
<cffunction name="corsHeaders">
|
||||
<!--- фрагмент взят из taffy/core/api.cfc и немного переписан --->
|
||||
<cfset var _taffyRequest=request._taffyRequest/>
|
||||
<cfset local={}/>
|
||||
|
||||
<cfset local.allowVerbs = uCase(structKeyList(_taffyRequest.matchDetails.methods)) />
|
||||
<cfif true
|
||||
AND listFindNoCase('PUT,PATCH,DELETE,OPTIONS',_taffyRequest.verb)
|
||||
AND NOT listFind(local.allowVerbs,'OPTIONS')>
|
||||
<cfset local.allowVerbs = listAppend(local.allowVerbs,'OPTIONS') />
|
||||
</cfif>
|
||||
<cfif structKeyExists(_taffyRequest.headers, "origin") >
|
||||
|
||||
<cfheader name="Access-Control-Allow-Origin" value="#_taffyRequest.headers.origin#" />
|
||||
|
||||
<cfheader name="Access-Control-Allow-Methods" value="#local.allowVerbs#" />
|
||||
<!--- Why do we parrot back these headers? See: https://github.com/atuttle/Taffy/issues/144 --->
|
||||
<cfif not structKeyExists(_taffyRequest.headers, "Access-Control-Request-Headers")>
|
||||
<cfheader name="Access-Control-Allow-Headers" value="Origin, Authorization, X-CSRF-Token, X-Requested-With, Content-Type, X-HTTP-Method-Override, Accept, Referrer, User-Agent" />
|
||||
<cfelse>
|
||||
<!--- parrot back all of the request headers to allow the request to continue (can we improve on this?) --->
|
||||
<cfset local.allowedHeaders = {} />
|
||||
<cfloop list="Origin,Authorization,X-CSRF-Token,X-Requested-With,Content-Type,X-HTTP-Method-Override,Accept,Referrer,User-Agent" index="local.h">
|
||||
<cfset local.allowedHeaders[local.h] = 1 />
|
||||
</cfloop>
|
||||
<cfset local.requestedHeaders = _taffyRequest.headers['Access-Control-Request-Headers'] />
|
||||
<cfloop list="#local.requestedHeaders#" index="local.i">
|
||||
<cfset local.allowedHeaders[ local.i ] = 1 />
|
||||
</cfloop>
|
||||
<cfheader name="Access-Control-Allow-Headers" value="#structKeyList(local.allowedHeaders)#" />
|
||||
</cfif>
|
||||
</cfif>
|
||||
</cffunction>
|
||||
|
||||
<!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
|
||||
<!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
|
||||
|
||||
<!--- Overriding TAFFY short-circuit logic (taffy/core/api.cfc) --->
|
||||
<cffunction name="onRequest" output="true" returntype="boolean">
|
||||
<cfargument name="targetPage" type="string" required="true" />
|
||||
|
||||
<cfset request.startTickCount=getTickCount()/><!--- *** --->
|
||||
|
||||
<cfset var _taffyRequest = {} />
|
||||
<cfset var local = {} />
|
||||
<cfset var m = '' />
|
||||
<cfset request._taffyRequest = _taffyRequest />
|
||||
<cfset local.debug = false />
|
||||
|
||||
<cfset _taffyRequest.metrics = {} />
|
||||
<cfset m = _taffyRequest.metrics />
|
||||
<cfset m.init = getTickCount() />
|
||||
|
||||
<!--- enable/disable debug output per settings --->
|
||||
<cfif not structKeyExists(url, application._taffy.settings.debugKey)>
|
||||
<cfsetting showdebugoutput="false" />
|
||||
</cfif>
|
||||
|
||||
<!--- display api dashboard if requested --->
|
||||
<cfif
|
||||
NOT structKeyExists(url,application._taffy.settings.endpointURLParam)
|
||||
AND NOT structKeyExists(form,application._taffy.settings.endpointURLParam)
|
||||
AND len(cgi.path_info) lte 1
|
||||
AND listFindNoCase(cgi.script_name, "index.cfm", "/") EQ listLen(cgi.script_name, "/")>
|
||||
<cfif NOT application._taffy.settings.disableDashboard>
|
||||
<cfif StructKeyExists( URL, "docs" )>
|
||||
<cfinclude template="#application._taffy.settings.docsPath#" />
|
||||
<cfelse>
|
||||
<cfinclude template="../dashboard/dashboard.cfm" />
|
||||
</cfif>
|
||||
<cfabort />
|
||||
<cfelse>
|
||||
<cfif len(application._taffy.settings.disabledDashboardRedirect)>
|
||||
<cflocation url="#application._taffy.settings.disabledDashboardRedirect#" addtoken="false" />
|
||||
<cfabort />
|
||||
<cfelseif application._taffy.settings.showDocsWhenDashboardDisabled>
|
||||
<cfinclude template="#application._taffy.settings.docsPath#" />
|
||||
<cfabort />
|
||||
<cfelse>
|
||||
<cfset throwError(403, "Forbidden") />
|
||||
</cfif>
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<!--- get request details --->
|
||||
<cfset m.beforeParse = getTickCount() />
|
||||
<cfset local.parsed = parseRequest() />
|
||||
<cfset m.afterParse = getTickCount() />
|
||||
<cfset structAppend(_taffyRequest, local.parsed) />
|
||||
<cfset m.parseTime = m.afterParse - m.beforeParse />
|
||||
|
||||
<!--- CORS headers (so that CORS can pass even if the resource throws an exception) --->
|
||||
<cfset local.allowVerbs = uCase(structKeyList(_taffyRequest.matchDetails.methods)) />
|
||||
<cfif (application._taffy.settings.allowCrossDomain eq true or len(application._taffy.settings.allowCrossDomain) gt 0)
|
||||
AND listFindNoCase('PUT,PATCH,DELETE,OPTIONS',_taffyRequest.verb)
|
||||
AND NOT listFind(local.allowVerbs,'OPTIONS')>
|
||||
<cfset local.allowVerbs = listAppend(local.allowVerbs,'OPTIONS') />
|
||||
</cfif>
|
||||
<cfif structKeyExists(_taffyRequest.headers, "origin") AND (application._taffy.settings.allowCrossDomain eq true or len(application._taffy.settings.allowCrossDomain) gt 0)>
|
||||
<cfif application._taffy.settings.allowCrossDomain eq true>
|
||||
<!--- <cfheader name="Access-Control-Allow-Origin" value="*" /> ---><!--- *** dirty hack 2024-10-23 17:59:43--->
|
||||
<cfheader name="Access-Control-Allow-Origin" value="#_taffyRequest.headers.origin#" />
|
||||
<cfelse>
|
||||
<!---
|
||||
The Access-Control-Allow-Origin header can only have 1 value so we check to see if the Origin header is
|
||||
in the list of origins specified in the config setting and parrot back the Origin header if so.
|
||||
We also need to add the Access-Control-Allow-Credentials header and set it to true for those type requests
|
||||
--->
|
||||
<cfset local.domains = listToArray( application._taffy.settings.allowCrossDomain, ', ;' )>
|
||||
<cfif structKeyExists(_taffyRequest.headers, "origin")>
|
||||
<cfloop from="1" to="#arrayLen( local.domains )#" index="local.i">
|
||||
<cfif lcase( rereplace( _taffyRequest.headers.origin, "(http|https):\/\/", "", "all" ) ) EQ lcase( rereplace( local.domains[ local.i ], "(http|https):\/\/", "", "all" ) ) >
|
||||
<cfheader name="Access-Control-Allow-Origin" value="#_taffyRequest.headers.origin#" />
|
||||
<cfheader name="Access-Control-Allow-Credentials" value="true" />
|
||||
<cfbreak>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
</cfif>
|
||||
</cfif>
|
||||
<cfheader name="Access-Control-Allow-Methods" value="#local.allowVerbs#" />
|
||||
<!--- Why do we parrot back these headers? See: https://github.com/atuttle/Taffy/issues/144 --->
|
||||
<cfif not structKeyExists(_taffyRequest.headers, "Access-Control-Request-Headers")>
|
||||
<cfheader name="Access-Control-Allow-Headers" value="Origin, Authorization, X-CSRF-Token, X-Requested-With, Content-Type, X-HTTP-Method-Override, Accept, Referrer, User-Agent" />
|
||||
<cfelse>
|
||||
<!--- parrot back all of the request headers to allow the request to continue (can we improve on this?) --->
|
||||
<cfset local.allowedHeaders = {} />
|
||||
<cfloop list="Origin,Authorization,X-CSRF-Token,X-Requested-With,Content-Type,X-HTTP-Method-Override,Accept,Referrer,User-Agent" index="local.h">
|
||||
<cfset local.allowedHeaders[local.h] = 1 />
|
||||
</cfloop>
|
||||
<cfset local.requestedHeaders = _taffyRequest.headers['Access-Control-Request-Headers'] />
|
||||
<cfloop list="#local.requestedHeaders#" index="local.i">
|
||||
<cfset local.allowedHeaders[ local.i ] = 1 />
|
||||
</cfloop>
|
||||
<cfheader name="Access-Control-Allow-Headers" value="#structKeyList(local.allowedHeaders)#" />
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<!--- global headers --->
|
||||
<cfset addHeaders(getGlobalHeaders()) />
|
||||
|
||||
<!---
|
||||
Now we know everything we need to know to service the request. let's service it!
|
||||
--->
|
||||
|
||||
<!--- ...after we let the api developer know all of the request details first... --->
|
||||
<cfset m.beforeOnTaffyRequest = getTickCount() />
|
||||
<cfset _taffyRequest.continue = onTaffyRequest(
|
||||
_taffyRequest.verb
|
||||
,_taffyRequest.matchDetails.beanName
|
||||
,_taffyRequest.requestArguments
|
||||
,_taffyRequest.returnMimeExt
|
||||
,_taffyRequest.headers
|
||||
,_taffyRequest.methodMetadata
|
||||
,local.parsed.matchDetails.srcUri
|
||||
) />
|
||||
<cfset m.afterOnTaffyRequest = getTickCount() />
|
||||
<cfset m.otrTime = m.afterOnTaffyRequest - m.beforeOnTaffyRequest />
|
||||
|
||||
<cfif not structKeyExists(_taffyRequest, "continue")>
|
||||
<!--- developer forgot to return true --->
|
||||
<cfthrow
|
||||
message="Error in your onTaffyRequest method"
|
||||
detail="Your onTaffyRequest method returned no value. Expected: Return TRUE or call noData()/representationOf()."
|
||||
errorcode="400"
|
||||
/>
|
||||
</cfif>
|
||||
|
||||
<cfif isObject(_taffyRequest.continue)>
|
||||
<!--- inspection complete but request has been aborted by developer; return custom response --->
|
||||
<cfset _taffyRequest.result = duplicate(_taffyRequest.continue) />
|
||||
<cfset structDelete(_taffyRequest, "continue")/>
|
||||
<cfset m.resourceTime = 0 />
|
||||
<cfelse>
|
||||
<!--- inspection complete and request allowed by developer --->
|
||||
|
||||
<!--- handle requests for simulated responses --->
|
||||
<cfif structKeyExists(_taffyRequest.requestArguments, application._taffy.settings.simulateKey) and _taffyRequest.requestArguments[application._taffy.settings.simulateKey] eq application._taffy.settings.simulatePassword>
|
||||
<!--- is there a simulated response? --->
|
||||
<cfset sampler = 'sample#_taffyRequest.method#Response' />
|
||||
<cfif structKeyExists(_taffyRequest.matchDetails.metadata, sampler)>
|
||||
<!--- get simulated response --->
|
||||
<cfinvoke
|
||||
component="#application._taffy.factory.getBean(_taffyRequest.matchDetails.beanName)#"
|
||||
method="#sampler#"
|
||||
returnvariable="_taffyRequest.result"
|
||||
/>
|
||||
<cfset _taffyRequest.result = rep(_taffyRequest.result) />
|
||||
<cfelse>
|
||||
<!--- no method for simulated response, so return 400 --->
|
||||
<cfset _taffyRequest.result = noData().withStatus(400, "No Sample Response Available") />
|
||||
</cfif>
|
||||
<cfelse>
|
||||
<!--- send request to service --->
|
||||
<cfif structKeyExists(_taffyRequest.matchDetails.methods, _taffyRequest.verb)>
|
||||
<!--- check the cache before we call the resource --->
|
||||
<cfset m.cacheCheckTime = getTickCount() />
|
||||
<cfset local.cacheKey = getCacheKey(
|
||||
_taffyRequest.matchDetails.beanName
|
||||
,_taffyRequest.requestArguments
|
||||
,local.parsed.matchDetails.srcUri
|
||||
) />
|
||||
<cfif ucase(_taffyRequest.verb) eq "GET" and validCacheExists(local.cacheKey)>
|
||||
<cfset m.cacheCheckTime = getTickCount() - m.cacheCheckTime />
|
||||
<cfset m.cacheGetTime = getTickCount() />
|
||||
<cfset _taffyRequest.result = getCachedResponse(local.cacheKey) />
|
||||
<cfset m.cacheGetTime = m.cacheGetTime - getTickCount() />
|
||||
<cfelse>
|
||||
<cfif ucase(_taffyRequest.verb) eq "GET">
|
||||
<cfset m.cacheCheckTime = getTickCount() - m.cacheCheckTime />
|
||||
<cfelse>
|
||||
<cfset structDelete(m, "cacheCheckTime") />
|
||||
</cfif>
|
||||
<!--- returns a representation-object --->
|
||||
<cfset m.beforeResource = getTickCount() />
|
||||
<cfinvoke
|
||||
component="#application._taffy.factory.getBean(_taffyRequest.matchDetails.beanName)#"
|
||||
method="#_taffyRequest.method#"
|
||||
argumentcollection="#_taffyRequest.requestArguments#"
|
||||
returnvariable="_taffyRequest.result"
|
||||
/>
|
||||
<cfset m.afterResource = getTickCount() />
|
||||
<cfset m.resourceTime = m.afterResource - m.beforeResource />
|
||||
<cfif !isDefined("_taffyRequest.result")>
|
||||
<cfthrow
|
||||
message="Resource did not return a value"
|
||||
detail="The resource is expected to return a call to rep()/representationOf() or noData(). It appears there was no return at all."
|
||||
errorcode="taffy.resources.ResourceReturnsNothing"
|
||||
/>
|
||||
</cfif>
|
||||
<!--- If the type returned is not an instance of baseSerializer, wrap it with a call to rep().
|
||||
This way we can directly return the object instead of a serializer from resource actions. --->
|
||||
<cfif !isInstanceOf(_taffyRequest.result, "taffy.core.baseSerializer")>
|
||||
<cfset _taffyRequest.result = rep(_taffyRequest.result) />
|
||||
</cfif>
|
||||
<cfif ucase(_taffyRequest.verb) eq "GET" and structKeyExists(local, "cacheKey")>
|
||||
<cfset m.cacheSaveStart = getTickCount() />
|
||||
<cfset setCachedResponse(local.cacheKey, _taffyRequest.result) />
|
||||
<cfset m.cacheSaveTime = getTickCount() - m.cacheSaveStart />
|
||||
</cfif>
|
||||
</cfif>
|
||||
<cfelseif NOT listFind(local.allowVerbs,_taffyRequest.verb)>
|
||||
<!--- if the verb is not implemented, refuse the request --->
|
||||
<cfheader name="ALLOW" value="#local.allowVerbs#" />
|
||||
<cfset throwError(405, "Method Not Allowed") />
|
||||
<cfelse>
|
||||
<!--- create dummy response for cross domain OPTIONS request --->
|
||||
<cfset _taffyRequest.resultHeaders = structNew() />
|
||||
<cfset _taffyRequest.statusArgs = structNew() />
|
||||
<cfset _taffyRequest.statusArgs.statusCode = 200 />
|
||||
<cfset _taffyRequest.statusArgs.statusText = 'OK' />
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
</cfif>
|
||||
<!--- make sure the requested mime type is available --->
|
||||
<cfif not mimeSupported(_taffyRequest.returnMimeExt)>
|
||||
<cfset throwError(400, "Requested format not available (#_taffyRequest.returnMimeExt#)") />
|
||||
</cfif>
|
||||
|
||||
<cfif structKeyExists(_taffyRequest,'result')>
|
||||
<!--- get status code --->
|
||||
<cfset _taffyRequest.statusArgs = structNew() />
|
||||
<cfset _taffyRequest.statusArgs.statusCode = _taffyRequest.result.getStatus() />
|
||||
<cfset _taffyRequest.statusArgs.statusText = _taffyRequest.result.getStatusText() />
|
||||
<!--- get custom headers --->
|
||||
<cfinvoke
|
||||
component="#_taffyRequest.result#"
|
||||
method="getHeaders"
|
||||
returnvariable="_taffyRequest.resultHeaders"
|
||||
/>
|
||||
</cfif>
|
||||
|
||||
<cfsetting enablecfoutputonly="true" />
|
||||
<cfcontent reset="true" type="#getReturnMimeAsHeader(_taffyRequest.returnMimeExt)#; charset=utf-8" />
|
||||
<cfheader statuscode="#_taffyRequest.statusArgs.statusCode#" statustext="#_taffyRequest.statusArgs.statusText#" />
|
||||
|
||||
<!--- headers --->
|
||||
<cfset addHeaders(_taffyRequest.resultHeaders) />
|
||||
|
||||
<!--- add ALLOW header for current resource, which describes available verbs --->
|
||||
<cfheader name="ALLOW" value="#local.allowVerbs#" />
|
||||
|
||||
<!--- metrics headers that should always apply --->
|
||||
<cfheader name="X-TIME-IN-PARSE" value="#m.parseTime#" />
|
||||
<cfheader name="X-TIME-IN-ONTAFFYREQUEST" value="#m.otrTime#" />
|
||||
<cfif structKeyExists(m, "resourceTime")>
|
||||
<cfheader name="X-TIME-IN-RESOURCE" value="#m.resourceTime#" />
|
||||
</cfif>
|
||||
<cfif structKeyExists(m, "cacheCheckTime")>
|
||||
<cfheader name="X-TIME-IN-CACHE-CHECK" value="#m.cacheCheckTime#" />
|
||||
</cfif>
|
||||
<cfif structKeyExists(m, "cacheGetTime")>
|
||||
<cfheader name="X-TIME-IN-CACHE-GET" value="#m.cacheGetTime#" />
|
||||
</cfif>
|
||||
<cfif structKeyExists(m, "cacheSaveTime")>
|
||||
<cfheader name="X-TIME-IN-CACHE-SAVE" value="#m.cacheSaveTime#" />
|
||||
</cfif>
|
||||
|
||||
<cfif application._taffy.settings.exposeHeaders>
|
||||
<cfset local.exposeHeaderList = structKeyList(_taffyRequest.resultHeaders) />
|
||||
<cfset local.exposeHeaderValue = "" />
|
||||
<cfif application._taffy.settings.useEtags and _taffyRequest.verb eq "GET" and _taffyRequest.result.getType() eq "textual">
|
||||
<cfset local.exposeHeaderList = listAppend(local.exposeHeaderList, "Etag") />
|
||||
</cfif>
|
||||
<cfloop list="#local.exposeHeaderList#" index="local.exposeHeader">
|
||||
<!--- filter out default simple response headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers --->
|
||||
<cfif not listFindNoCase("Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma", local.exposeHeader)>
|
||||
<cfset local.exposeHeaderValue = listAppend(local.exposeHeaderValue, local.exposeHeader) />
|
||||
</cfif>
|
||||
</cfloop>
|
||||
<cfif listLen(local.exposeHeaderValue) gt 0>
|
||||
<cfheader name="Access-Control-Expose-Headers" value="#local.exposeHeaderValue#" />
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<!--- result data --->
|
||||
<cfif structKeyExists(_taffyRequest,'result')>
|
||||
<cfset _taffyRequest.resultType = _taffyRequest.result.getType() />
|
||||
<cfset local.resultSerialized = '' />
|
||||
|
||||
<cfif _taffyRequest.resultType eq "textual">
|
||||
<!--- serialize the representation's data into the requested mime type --->
|
||||
<cfset _taffyRequest.metrics.beforeSerialize = getTickCount() />
|
||||
<cfinvoke
|
||||
component="#_taffyRequest.result#"
|
||||
method="getAs#_taffyRequest.returnMimeExt#"
|
||||
returnvariable="_taffyRequest.resultSerialized"
|
||||
/>
|
||||
<cfset _taffyRequest.metrics.afterSerialize = getTickCount() />
|
||||
<cfset m.serializeTime = m.afterSerialize - m.beforeSerialize />
|
||||
<cfheader name="X-TIME-IN-SERIALIZE" value="#m.serializeTime#" />
|
||||
|
||||
<!--- apply jsonp wrapper if requested --->
|
||||
<cfif structKeyExists(_taffyRequest, "jsonpCallback")>
|
||||
<cfset _taffyRequest.resultSerialized = _taffyRequest.jsonpCallback & "(" & _taffyRequest.resultSerialized & ");" />
|
||||
</cfif>
|
||||
|
||||
<!--- don't return data if etags are enabled and the data hasn't changed --->
|
||||
<cfif application._taffy.settings.useEtags and _taffyRequest.verb eq "GET">
|
||||
<!--- etag values are quoted per: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag --->
|
||||
<cfif structKeyExists(server, "lucee")>
|
||||
<!--- hashCode() will not work for lucee, see issue #354 --->
|
||||
<cfset _taffyRequest.serverEtag = '"' & hash(_taffyRequest.resultSerialized) & '"' />
|
||||
<cfelse>
|
||||
<cfset _taffyRequest.serverEtag = '"' & _taffyRequest.result.getData().hashCode() & '"' />
|
||||
</cfif>
|
||||
<cfif structKeyExists(_taffyRequest.headers, "If-None-Match")>
|
||||
<cfset _taffyRequest.clientEtag = _taffyRequest.headers['If-None-Match'] />
|
||||
|
||||
<cfif len(_taffyRequest.clientEtag) gt 0 and _taffyRequest.clientEtag eq _taffyRequest.serverEtag>
|
||||
<cfheader statuscode="304" statustext="Not Modified" />
|
||||
<cfcontent reset="true" type="#application._taffy.settings.mimeExtensions[_taffyRequest.returnMimeExt]#; charset=utf-8" />
|
||||
<cfreturn true />
|
||||
<cfelse>
|
||||
<cfheader name="Etag" value="#_taffyRequest.serverEtag#" />
|
||||
</cfif>
|
||||
<cfelse>
|
||||
<cfheader name="Etag" value="#_taffyRequest.serverEtag#" />
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<cfset m.done = getTickCount() />
|
||||
<cfset m.taffyTime = m.done - m.init - m.parseTime - m.otrTime - m.serializeTime />
|
||||
<cfif structKeyExists(m, "resourceTime")>
|
||||
<cfset m.taffyTime -= m.resourceTime />
|
||||
</cfif>
|
||||
<cfheader name="X-TIME-IN-TAFFY" value="#m.taffyTime#" />
|
||||
|
||||
<cfcontent reset="true" type="#application._taffy.settings.mimeExtensions[_taffyRequest.returnMimeExt]#; charset=utf-8" />
|
||||
<cfif _taffyRequest.resultSerialized neq ('"' & '"')>
|
||||
<cfset local.resultSerialized = _taffyRequest.resultSerialized />
|
||||
</cfif>
|
||||
<!--- debug output --->
|
||||
<cfif structKeyExists(url, application._taffy.settings.debugKey)>
|
||||
<cfset local.debug = true />
|
||||
</cfif>
|
||||
|
||||
<cfelseif _taffyRequest.resultType eq "filename">
|
||||
<cfset m.done = getTickCount() />
|
||||
<cfset m.taffyTime = m.done - m.init - m.parseTime - m.otrTime - m.resourceTime />
|
||||
<cfheader name="X-TIME-IN-TAFFY" value="#m.taffyTime#" />
|
||||
<cfcontent reset="true" file="#_taffyRequest.result.getFileName()#" type="#_taffyRequest.result.getFileMime()#" deletefile="#_taffyRequest.result.getDeleteFile()#" />
|
||||
|
||||
<cfelseif _taffyRequest.resultType eq "filedata">
|
||||
<cfset m.done = getTickCount() />
|
||||
<cfset m.taffyTime = m.done - m.init - m.parseTime - m.otrTime - m.resourceTime />
|
||||
<cfheader name="X-TIME-IN-TAFFY" value="#m.taffyTime#" />
|
||||
<cfcontent reset="true" variable="#_taffyRequest.result.getFileData()#" type="#_taffyRequest.result.getFileMime()#" />
|
||||
|
||||
<cfelseif _taffyRequest.resultType eq "imagedata">
|
||||
<cfset m.done = getTickCount() />
|
||||
<cfset m.taffyTime = m.done - m.init - m.parseTime - m.otrTime - m.resourceTime />
|
||||
<cfheader name="X-TIME-IN-TAFFY" value="#m.taffyTime#" />
|
||||
<cfcontent reset="true" variable="#_taffyRequest.result.getImageData()#" type="#_taffyRequest.result.getFileMime()#" />
|
||||
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<cfset local.resultSerialized = "" />
|
||||
<cfif structKeyExists( _taffyRequest, "resultSerialized" )>
|
||||
<cfset local.resultSerialized = _taffyRequest.resultSerialized />
|
||||
</cfif>
|
||||
|
||||
<cfset local.result = StructNew() />
|
||||
<cfif structKeyExists( _taffyRequest, "result" )>
|
||||
<cfset local.result = _taffyRequest.result.getData() />
|
||||
</cfif>
|
||||
|
||||
<!--- ...after the service has finished... --->
|
||||
<cfset m.beforeOnTaffyRequestEnd = getTickCount() />
|
||||
<cfset onTaffyRequestEnd(
|
||||
_taffyRequest.verb
|
||||
,_taffyRequest.matchDetails.beanName
|
||||
,_taffyRequest.requestArguments
|
||||
,_taffyRequest.returnMimeExt
|
||||
,_taffyRequest.headers
|
||||
,_taffyRequest.methodMetadata
|
||||
,local.parsed.matchDetails.srcUri
|
||||
,local.resultSerialized
|
||||
,local.result
|
||||
,_taffyRequest.statusArgs.statusCode
|
||||
) />
|
||||
<cfset m.otreTime = getTickCount() - m.beforeOnTaffyRequestEnd />
|
||||
<cfheader name="X-TIME-IN-ONTAFFYREQUESTEND" value="#m.otreTime#" />
|
||||
|
||||
<cfif len(trim(local.resultSerialized))>
|
||||
<cfoutput>#local.resultSerialized#</cfoutput>
|
||||
</cfif>
|
||||
<!--- debug output --->
|
||||
<cfif local.debug>
|
||||
<cfoutput><h3>Request Details:</h3><cfdump var="#_taffyRequest#"></cfoutput>
|
||||
</cfif>
|
||||
|
||||
<cfreturn true />
|
||||
</cffunction>
|
||||
|
||||
</cfcomponent>
|
||||
|
||||
Reference in New Issue
Block a user