【问题标题】:Is there a way to allow Google App Engine to send body or payload with a DELETE request?有没有办法允许 Google App Engine 发送带有 DELETE 请求的正文或有效负载?
【发布时间】:2010-02-05 21:47:58
【问题描述】:

我正在尝试与要求将 XML 数据包含在 HTTP DELETE 请求的正文中的 API 进行交互。我在 AppEngine 中使用 urlfetch 并且对于 DELETE 请求,负载被简单地忽略了。

阅读这篇文章:Is an entity body allowed for an HTTP DELETE request? 后,我意识到标准可能不允许 DELETE 请求中的正文内容,这就是 urlfetch 剥离正文的原因。

所以我的问题是:当 urlfetch 忽略有效负载时,是否有某种解决方法可以在应用引擎中附加正文内容?

【问题讨论】:

    标签: http google-app-engine httpwebrequest


    【解决方案1】:

    the docs

    网址提取服务支持五 HTTP 方法:GET、POST、HEAD、PUT 和 删除。请求可以包括 HTTP POST 的标题和正文内容 或 PUT 请求。

    鉴于 GAE Python 运行时是高度沙盒化的,您极不可能绕过此限制。我认为这是一个错误,您应该提交错误报告here

    【讨论】:

    【解决方案2】:

    您可以通过套接字发出带有正文的 DELETE 请求,示例 Java 代码检查 HTTPRequest 并对带有正文的 DELETE 执行不同的请求:

    public static HTTPResponse execute(HTTPRequest request) throws ExecutionException, InterruptedException {
    
        if (request == null) {
            throw new IllegalArgumentException("Missing request!");
        }
    
        if (request.getMethod() == HTTPMethod.DELETE && request.getPayload() != null && request.getPayload().length > 0) {
            URL obj = request.getURL();
            SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            try {
                HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
    
                HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
    
                con.setRequestMethod("DELETE");
                for (HTTPHeader httpHeader : request.getHeaders()) {
                    con.setRequestProperty(httpHeader.getName(), httpHeader.getValue());
                }
                con.setDoOutput(true);
                con.setDoInput(true);
    
                OutputStream out = con.getOutputStream();
                out.write(request.getPayload());
                out.flush();
                out.close();
                List<HTTPHeader> responseHeaders = new ArrayList<>();
                for (Map.Entry<String, List<String>> stringListEntry : con.getHeaderFields().entrySet()) {
                    for (String value : stringListEntry.getValue()) {
                        responseHeaders.add(new HTTPHeader(stringListEntry.getKey(), value));
                    }
                }
                return new HTTPResponse(con.getResponseCode(), StreamUtils.getBytes(con.getInputStream()), con.getURL(), responseHeaders);
            } catch (IOException e) {
                log.severe(e.getMessage());
            }
        } else {
            Future<HTTPResponse> future = URLFetchServiceFactory.getURLFetchService().fetchAsync(request);
            return future.get();
        }
        return null;
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用 App Engine Socket API 解决此问题,以下是在 Go 中的外观:

          client := http.Client{
              Transport: &http.Transport{
                  Dial: func(network, addr string) (net.Conn, error) {
                      return socket.Dial(c, network, addr)
                  },
              },
          }
      

      【讨论】:

        猜你喜欢
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 2020-04-28
        • 2014-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-17
        相关资源
        最近更新 更多