Is there a way to allow the Google App Engine to send a body or payload using a DELETE request?

I am trying to interact with an API that requires XML data to be contained in the body of an HTTP DELETE request. I use urlfetch in AppEngine, and the payload is simply ignored for DELETE requests.

After reading this article: Is the body of the object allowed for an HTTP DELETE request? , I understand that the standard probably does not allow body content on DELETE requests and that why urlfetch robs the body.

So my question is: is there any work to add body content to the application engine when urlfetch ignores the payload?

+7
google-app-engine
source share
3 answers

Per documents ,

The URL Retrieval Service supports five HTTP Methods: GET, POST, HEAD, PUT, and DELETE. The request may include HTTP headers and body content for POST or PUT.

Given that the GAE Python runtime is highly isolated, it is highly unlikely that you can get around this limitation. I believe this is a mistake, and you should probably write a bug report here .

+6
source share

You can make a DELETE request using the body through sockets, a sample Java code that checks the HTTPRequest and makes another request for DELETE with the body:

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; } 
+2
source share

You can get around this using the Socket App Engine API, here is what it looks like in Go:

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

All Articles