【问题标题】:Appengine - Deployment of hidden folderAppengine - 隐藏文件夹的部署
【发布时间】:2016-09-01 22:12:15
【问题描述】:

要验证 SSL 证书,我需要将包含一些文件的隐藏文件夹(“/.well-known”)上传到我的应用程序。

我正在使用 eclipse 部署 java 应用程序,但这些文件在 appengine 上的应用程序中没有收到。我猜他们被过滤掉了。

我尝试将隐藏文件夹作为静态文件添加到 appengine-web.xml,但没有帮助。

<!-- Configure serving/caching of GWT files -->
<static-files>
    <include path="**" />
    <include path=".**" />
    <include path="**.*" expiration="0s" />
    <include path="**.well-known" expiration="0s" />
    <include path="**.nocache.*" expiration="0s" />
    <include path="**.cache.*" expiration="365d" />
    <include path="**.css" expiration="30d"/>
    <exclude path="**.gwt.rpc" />
    <exclude path="**.html" />
</static-files>

有什么办法可以上传这些文件夹和文件吗?

【问题讨论】:

    标签: java validation google-app-engine hidden hidden-files


    【解决方案1】:

    对于像我一样尝试在 Google App Engine 中以静态方式为letsencrypt挑战并失败后来到这里的其他人,以下为我做了:(一个人可能实际上可以静态地做到这一点,但我没有'不要尝试,因为我不想花更多时间尝试东西,而 Ian 显然尝试过但无法使其工作[也许在 Google App Engine 内部完成的复制命令忽略了以点开头的目录])

    取自 http://igorartamonov.com/2015/12/lets-encrypt-ssl-google-appengine/ 致谢 Igor Artamonov。

    只需构建一个像这样的 servlet:

    公共类 LetsencryptServlet 扩展 HttpServlet {

        public static final Map<String, String> challenges = new HashMap<String, String>();
    
        static {
            challenges.put("RzrvZ9gd7EH3i_TsJM-B0vdEMslD4oo_lwsagGskp6c",
                    "RzrvZ9gd7EH3i_TsJM-B0vdEMslD4oo_lwsagGskp6c.ONrZa3UelibSWEX270nTUiRZKPFXw096nENWbMGw0-E");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            if (!req.getRequestURI().startsWith("/.well-known/acme-challenge/")) {
                resp.sendError(404);
                return;
            }
            String id = req.getRequestURI().substring("/.well-known/acme-challenge/".length());
            if (!challenges.containsKey(id)) {
                resp.sendError(404);
                return;
            }
            resp.setContentType("text/plain");
            resp.getOutputStream().print(challenges.get(id));
        }
    }
    

    并添加到web.xml 类似的东西:

    <servlet>
        <servlet-name>letsencrypt</servlet-name>
        <servlet-class>...LetsencryptServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>letsencrypt</servlet-name>
        <url-pattern>/.well-known/acme-challenge/*</url-pattern>
    </servlet-mapping>
    

    当然,请确保 servlet 类具有您创建的 Servlet 的完整类路径。

    该博文还涉及生成和安装证书所需的其他步骤。

    Ian:你确定你已经很好地部署了 servlet 吗?检查日志,确保您正在测试正确的版本..也许您遇到了编译问题..

    干杯

    【讨论】:

    • 以同样的方式做了(见下面我的回答)。感谢您的详细说明!
    【解决方案2】:

    我在尝试提供assetlinks.json 文件时遇到了这个问题。确实会出现以 .在 App Engine 的静态上下文中无法访问。 João Antunes 解决方法的更通用版本如下。

    首先,创建没有 .并在其中放置任何所需的文件。

    然后我们需要创建一个 servlet,它会在收到对隐藏文件夹的请求时以正确的数据进行响应。

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created by Will Calderwood on 17/05/2017.
     * <p>
     * It would appear to not be possible to upload hidden folders to app engine. So when files need
     * to be served from a hidden folder the URL can be bounced through this servlet
     */
    public class StaticFileServer extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // We'll remove the dots from the path
            String uri = req.getRequestURI().replace("/.", "/");
    
            // Do anything else that needs doing here
            if (uri.toLowerCase().contains(".json")) {
                resp.setContentType("application/json");
            }
    
            // Read and return the resource from the non-hidden folder
            try (InputStream in = getServletContext().getResourceAsStream(uri)) {
                if (in == null){
                    resp.sendError(404);
                    return;
                }
                byte[] buffer = new byte[8192];
                int count;
                while ((count = in.read(buffer)) > 0) {
                    resp.getOutputStream().write(buffer, 0, count);
                }
            }
        }
    }
    

    然后将以下内容添加到您的 web.xml 文件中,以将隐藏文件夹指向我们的 servlet

    <servlet>
        <servlet-name>StaticFileServer</servlet-name>
        <servlet-class>main.com.you.StaticFileServer</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>StaticFileServer</servlet-name>
        <url-pattern>/.well-known/*</url-pattern>
    </servlet-mapping>
    

    【讨论】:

      【解决方案3】:

      我确实找到了更好的方法,问题是代码存储在隐藏目录中,所以我们只需要将正确的 url 映射到可见目录。

      handlers: - url: /.well-known static_dir: _well-known

      【讨论】:

      • 我不确定 Java 版本中是否存在等价物。
      • 我在寻找 Python 的解决方案时来到这里,最终找到了它。该选项名为skip_files,您可以覆盖它。最后一个模式是隐藏文件的模式,只需将其删除并粘贴其余部分即可。
      【解决方案4】:

      静态文件不会上传到应用服务器,因此应用代码无法访问。来自appengine-web.xml Reference,在&lt;static-files&gt; 部分:

      可选。 元素指定模式 匹配文件路径以从静态文件列表中包含和排除, 覆盖或修改默认行为。提供静态文件 来自独立于服务器的专用服务器和缓存 应用程序服务器,可用于提供静态内容,例如 图片、CSS 样式表或 JavaScript 文件。

      要让应用程序代码可以访问文件,需要在&lt;resource-files&gt; 部分(与上述相同的文档)中指定它们:

      可选。 元素中列出的文件是 应用程序代码可以使用文件系统访问。这些文件 与应用程序一起存储在应用程序服务器上,而不是如何 静态文件被存储和提供。

      【讨论】:

      • 我尝试将这些文件标记为静态文件,以便从外部访问它们(请参阅我的代码片段)。也许我的语法错误,但部署后 appengine 不提供它们。
      • 未提供服务也可能意味着它们未正确访问或未在正确的位置上传。当它们没有被送达时,您在日志中看到了什么?我第一次尝试下载部署的应用程序代码,以验证目录是否实际上传(在正确的位置)。如果已上传,则焦点将进入访问文件。如果没有,它会进入上传文件。
      • 如果我在本地运行该应用程序,我可以访问本地主机上的文件,部署后,我用我的域 URL 替换了 localhost,它给了我一个 404。所以它似乎是要么未上传,要么未提供。
      • 有关于这个@jan 的消息吗?
      • @João Antunes 我以与您相同的方式解决了它:使用 servlet。感谢您的详细回复!
      【解决方案5】:

      我尝试了所有方法,但无法上传该隐藏文件夹。然后,我为该路径定义了一个 servlet 映射,servlet 写出 SSL 颁发者所期望的验证字符串:

      <servlet-mapping>
          <servlet-name>SSLVerificationServlet</servlet-name>
          <url-pattern>/.well-known/acme-challenge/roQH_vUmRQsuKH8lZGedft9O6TK-UoZWzv_kY8MukH4F8</url-pattern>
      </servlet-mapping> 
      

      【讨论】:

      【解决方案6】:

      一个丑陋但直接的解决方法是使用 JSP 支持来映射页面。一个例子:

      package/src/main/webapp/_well-known/assetlinks.json.jsp中创建你的json文件

      <%@ page contentType="application/json;charset=UTF-8" language="java"%>
      [JSON CONTENT]
      

      将“servlet”映射到web.xml中的所需路径:

      <servlet>
          <servlet-name>Asset Links</servlet-name>
          <jsp-file>/_well-known/assetlinks.json.jsp</jsp-file>
      </servlet>
      <servlet-mapping>
          <servlet-name>Asset Links</servlet-name>
          <url-pattern>/.well-known/assetlinks.json</url-pattern>
      </servlet-mapping>
      

      完成!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多