Appengine - 隐藏文件夹的部署

Appengine - Deployment of hidden folder

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

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

我尝试将隐藏文件夹作为静态文件添加到 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>

知道如何上传这些文件夹和文件吗?

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

< static-files >

Optional. The < static-files > element specifies patterns that match file paths to include and exclude from the list of static files, overriding or amending the default behavior. Static file are served from dedicated servers and caches that are separate from the application servers and are useful for serving static content such as images, CSS stylesheets or JavaScript files.

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

< resource-files >

Optional. The files that listed in the < resource-files > element are accessible by the application code using the filesystem. These files are stored on the application servers with the app as opposed to how static files are stored and served.

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

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

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

摘自 http://igorartamonov.com/2015/12/lets-encrypt-ssl-google-appengine/ 学分归 Igor Artamonov。

只需像这样构建一个 servlet:

public class 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 class 具有您创建的 Servlet 的完整 class路径。

该博客 post 还介绍了生成和安装证书所需的其他步骤。

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

干杯

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

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

我 运行 遇到这个问题试图提供 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>

一个丑陋但直接的解决方法是使用 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>

完成!