spec/lib/track.cfm
2025-06-02 16:16:51 +03:00

104 lines
4.8 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<cfsilent><!--- утилита для передачи стека вызовов через URL --->
<!---v1.01 14:00 03.04.2019 added output param thisURL--->
<!---v1.02 06:16 26.12.2019 symbols -._ are not encoded --->
<cfparam name="ATTRIBUTES.thisUrl" type="string" default=""><!--- текущий URL без трэка --->
<cfparam name="ATTRIBUTES.output" type="string" default="tr">
<cfparam name="ATTRIBUTES.input" type="string" default="track"><!--- имя параметра в URL или FORM, в которой лежит текущий трэк --->
<cfparam name="ATTRIBUTES.urlParamName" type="string" default="#ATTRIBUTES.input#">
<cfparam name="ATTRIBUTES.defaultBackUrl" type="string">
<!---<cffunction name="urlSafeWrap">
<cfargument name="s" type="string"/>
<cfreturn replace(URLEncodedFormat(s), "%", "!", "ALL")/>
</cffunction>--->
<!---<cffunction name="urlSafeWrap">
<cfargument name="s" type="string"/>
<cfreturn
replace(
replaceList(
URLEncodedFormat(s),
"#URLEncodedFormat('_')#,#URLEncodedFormat('.')#,#URLEncodedFormat('-')#,#URLEncodedFormat('~')#,#URLEncodedFormat('=')#",
"_,.,-,~,="
),
"%", "!", "ALL"
)/>
</cffunction>--->
<cffunction name="urlSafeWrap">
<cfargument name="s" type="string"/>
<cfreturn
replace(
replaceList(
URLEncodedFormat(s),
"#URLEncodedFormat('_')#,#URLEncodedFormat('.')#,#URLEncodedFormat('-')#",
"_,.,-"
),
"%", "!", "ALL"
)/><!---unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" https://www.ietf.org/rfc/rfc3986.txt--->
</cffunction>
<cffunction name="urlSafeUnWrap">
<cfargument name="s" type="string"/>
<cfreturn URLDecode(replace(s, "!", "%","ALL"))/>
</cffunction>
<cfif StructKeyExists(form, ATTRIBUTES.input)>
<cfset track=structFind(form, ATTRIBUTES.input)/>
<cfelseif StructKeyExists(url, ATTRIBUTES.input)>
<cfset track=structFind(url, ATTRIBUTES.input)/>
<cfelse>
<cfset track=""/>
</cfif>
<!--- для предохранения спецсимволов (особенно запятых) в урле используется заворачивание в URLEncodedFormat. ColdFusion (по крайней мере старые версии) не умеет возвращать множественные значения иначе, как списком через запятую. Чтобы избежать непрошенного разворачивания URLEncodedFormat при отправке GETом, мы заменяем % на !.
Реализовал вариант с заворачиванием в GZIP, работает неплохо, но вариант с URLEncodedFormat сохраняет хоть какую-то читабельность.
Можно было бы кодировать в base64. Или вообще хранить на сервере в сессии, а передавать хэш - но непонятно, когда можно забыть этот урл, а накапливать их зря в сессии не хочется.
Попробовал Base64 - очень плохо, все размножается при повторном кодировании и начинает виснуть.
--->
<cfset trackBack="">
<cfif listLen(track) GT 0>
<cfset trackBack=ListDeleteAt(track, listLen(track))>
</cfif>
<cfset trackForward=ListAppend(track, urlSafeWrap(ATTRIBUTES.thisUrl))/>
<cfset backUrlBase=urlSafeUnWrap(listLast(track))/>
<cfif len(backUrlBase) GT 0>
<cfif len(trackBack) GT 0>
<cfif find("?", backUrlBase) GT 0>
<!--- has query string --->
<cfset backUrl="#backUrlBase#&#ATTRIBUTES.urlParamName#=#trackBack#"/>
<cfelse>
<!--- no query string --->
<cfset backUrl="#backUrlBase#?#ATTRIBUTES.urlParamName#=#trackBack#"/>
</cfif>
<cfelse>
<cfset backUrl="#backUrlBase#"/>
</cfif>
<cfelse>
<cfset backUrl="#ATTRIBUTES.defaultBackUrl#"/>
</cfif>
<cfif NOT (find("?", ATTRIBUTES.thisUrl) GT 0)>
<cfset selfUrl="#ATTRIBUTES.thisUrl#?#ATTRIBUTES.urlParamName#=#track#"/>
<cfelse>
<cfset selfUrl="#ATTRIBUTES.thisUrl#&#ATTRIBUTES.urlParamName#=#track#"/>
</cfif>
<cfset setVariable("CALLER.#ATTRIBUTES.output#", structNew())/>
<cfset setVariable("CALLER.#ATTRIBUTES.output#.fw", trackForward)/><!--- значение стэка: &track=#tr.fw# --->
<cfset setVariable("CALLER.#ATTRIBUTES.output#.fwx", "#ATTRIBUTES.urlParamName#=#trackForward#")/><!--- готовый суффикс для URL: &#tr.fwx#--->
<cfset setVariable("CALLER.#ATTRIBUTES.output#.bk", trackBack)/>
<cfset setVariable("CALLER.#ATTRIBUTES.output#.backUrl", backUrl)/>
<cfset setVariable("CALLER.#ATTRIBUTES.output#.self", track)/>
<cfset setVariable("CALLER.#ATTRIBUTES.output#.selfUrl", selfUrl)/>
<cfset setVariable("CALLER.#ATTRIBUTES.output#.thisUrl", ATTRIBUTES.thisUrl)/>
<cfset setVariable("CALLER.#ATTRIBUTES.output#.len", listLen(track))/>
<cfexit method="exitTag"/>
</cfsilent>