代码之家  ›  专栏  ›  技术社区  ›  user9263373

关于ColdFusion的CGI作用域/结构的未记录的不一致行为

  •  6
  • user9263373  · 技术社区  · 8 年前

    我最初发布这篇文章是为了回答之前关于 Empty CGI.REDIRECT_URL on ColdFusion 2016 . 经过思考,我想得更好了,因为技术上没有回答OP的问题。相反,我决定把它变成一个单独的问题,尽管这更像是一个评论而不是一个问题。虽然这在技术上可能无法满足 Minimal, Complete, and Verifiable example 人们可能会用反对票来批评我,我认为这是值得的,希望它会成为 更容易找到 对于未来可能遇到这种情况的CFER。从而防止他们在CGI结构/范围的这种特殊行为上撞到墙上。

    综上所述,CGI结构/作用域具有来自其他结构/作用域的一些未记录的不一致行为。请注意,我个人并不相信这一发现,因为我不久前在阅读时偶然发现了这一点 Ben Nadel's blog post on this . 所以我在这里发布的所有信息都已经在那里详细了,但我想在这里写一个很好的总结。

    未记录的行为1-与其他结构不同,如果CGI结构键不存在,则在引用它时不会抛出错误。

    OP's original question ,他想知道为什么 cgi.REDIRECT_URL 存在但为空。正如他最终发现的那样,它从未真正存在过。作为一个单独的示例,您可以在不引发错误的情况下执行这行代码。不是你想的那样吧?

    <cfoutout>#cgi.THIS_IS_A_FAKE_KEY#</cfoutout>
    

    那么CFer应该做什么呢?测试密钥是否存在。

    <cfif structKeyExists( CGI, 'THIS_IS_A_FAKE_KEY' )>
        THIS_IS_A_FAKE_KEY exists
    <cfelse>
        THIS_IS_A_FAKE_KEY doesn't exist
    </cfif>
    

    未记录的行为2-与其他结构不同,如果转储CGI结构,它不会显示所有键/值对,它只会显示一组定义的键。

    OP's case ,他有一个定制的Apache CGI变量 cgi。REDIRECT\u URL 在升级到CF2016之前,他的代码中使用了这一点,并且可以直接引用它。然而,我想如果他把 cgi struct,它不会出现在转储中。在里面 Ben Nadel's case ,他也有一个习惯 cgi公司 已调用变量 cgi.document_root 这是从负载平衡器传递过来的,可以直接引用它,但在转储 cgi公司 目录

    那么CFer应该做什么呢?了解这一点,并将其牢记在心,这样你在倾倒垃圾时就不会被咬伤 cgi公司 内容和键/值对不存在。除此之外,没什么别的。

    2 回复  |  直到 8 年前
        1
  •  8
  •   Community Mohan Dere    6 年前

    我走进了 cfusion.jar ColdFusion文件。我发现有点困惑。

    CGI范围不属于 structure 人们所希望的形式。

    这就是如何处理对CGI变量的调用。如 <cfoutout>#cgi.THIS_IS_A_FAKE_KEY#</cfoutout>

    1. 正常有效的CGI范围变量是此列表中的变量,这些变量将初始化为 "" 默认情况下。

       private static final String[] names ="AUTH_PASSWORD","AUTH_TYPE","AUTH_USER","CERT_COOKIE","CERT_FLAGS","CERT_ISSUER","CERT_KEYSIZE","CERT_SECRETKEYSIZE","CERT_SERIALNUMBER","CERT_SERVER_ISSUER","CERT_SERVER_SUBJECT","CERT_SUBJECT","CF_TEMPLATE_PATH","CONTENT_LENGTH","CONTENT_TYPE","CONTEXT_PATH","GATEWAY_INTERFACE","HTTP_ACCEPT","HTTP_ACCEPT_ENCODING","HTTP_ACCEPT_LANGUAGE","HTTP_CONNECTION","HTTP_COOKIE","HTTP_HOST","HTTP_USER_AGENT","HTTP_REFERER","HTTP_URL","HTTPS","HTTPS_KEYSIZE","HTTPS_SECRETKEYSIZE","HTTPS_SERVER_ISSUER","HTTPS_SERVER_SUBJECT","LOCAL_ADDR","PATH_INFO","PATH_TRANSLATED","QUERY_STRING","REMOTE_ADDR","REMOTE_HOST","REMOTE_USER","REQUEST_METHOD","SCRIPT_NAME","SERVER_NAME","SERVER_PORT","SERVER_PORT_SECURE","SERVER_PROTOCOL","SERVER_SOFTWARE","WEB_SERVER_API" };`
      

      此外,所有这些值还来自各种java库 javax.servlet , HttpServletRequest

    2. 如果经过一点检查后请求的变量不是这些变量中的任何一个,那么ColdFusion将转到请求头。您可以使用 getHttpRequestData().headers . 然后在那里寻找带有连字符的键( - )而不是下划线( _ )在 cgi 密钥请求。(如果钥匙以开头 http_ ,则请求标头中的键将不包含它,如下所示 http_x_forward 请求标头中的 x-forward )

       value = request.getHeader(name.replace('_', '-'));
      

    根据我对ColdFusion的理解,第一点中提到的键是公认的CGI范围的一部分。但是,当Apache负载平衡器服务器向ColdFusion传递额外信息时,这些信息最终会出现在请求头中。自从爪哇 getHeader 只返回一个空白字符串(或数据类型为 undefined )而不是未定义的错误, ColdFusion不识别是否定义了任何键 .

    所以如果钥匙 THIS_IS_A_FAKE_KEY 从Apache服务器等中介发送到ColdFusion。你会在 getHttpRequestData().headers['THIS-IS-A-FAKE-KEY'] 但不是在 CGI 范围转储。

    尽管如此,我个人的意见是,最好直接在 getHttpRequestData()。标题 用于范围本身以外的自定义CGI变量。

        2
  •  7
  •   user9263373    8 年前

    编辑 感谢Ageax指出我的一个测试用例在我之前修订的这篇文章中无效。

    好一点的侦探工作RRK!所以我决定做一个实验,通过创建两个循环来验证你的发现。第一个循环将显示 getHttpRequestData().headers 第二个循环使用 cgi 通过替换 - 具有 _ . 瞧!正如RRK所报告的,我们可以看到您如何通过任何一种方法获得值。我更新了要点并发布了 here 任何感兴趣的人。

    <cfset httpHeaders = getHttpRequestData().headers>
    
    <h3>getHttpRequestData().headers</h3>
    
    <cfloop collection="#httpHeaders#" item="key" >
        <cfoutput><strong>#Key#</strong> : #httpHeaders[key]#<br></cfoutput>
    </cfloop>
    
    <h3>cgi keys dash to underscore</h3>
    
    <cfloop collection="#httpHeaders#" item="key" >
        <cfset keyUnderscore = replace(key, "-", "_", "all")>
        <cfoutput><strong>#keyUnderscore#</strong> : #cgi[keyUnderscore]#<br></cfoutput>
    </cfloop>