jwagenleitner / groovy-wslite

Lightweight SOAP and REST webservice clients for Groovy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting java.net.ProtocolException: HTTP method DELETE doesn't support output

LuisMuniz opened this issue · comments

Library version 1.1.2

When using the DELETE method on a URL, I found that the HttpClient failed with the above exception.

Caused by: java.net.ProtocolException: HTTP method DELETE doesn't support output
        at wslite.http.HTTPClient.setupConnection(HTTPClient.groovy:118)
        at wslite.http.HTTPClient.execute(HTTPClient.groovy:54)

In fact, the underlying HttpURLConnection is a sun.net.www.protocol.http.HttpURLConnection (using oracle jdk 7), and this implementation throws this exception when getOutputStream() is called and the method is not GET, POST, or PUT:

                if(this.method.equals("GET")) {
                    this.method = "POST";
                }

                if(!"POST".equals(this.method) && !"PUT".equals(this.method) && "http".equals(this.url.getProtocol())) {
                    throw new ProtocolException("HTTP method " + this.method + " doesn\'t support output");

It seems like the easy fix would be to change HttpClient.setupConnection to avoid trying to obtain the OutputStream of the response when executing a DELETE request.

Actually looking at it more closely, this seems to be due to the fact that elasticsearch has a delete by query endpoint, which requires to send a DELETE request with a data payload.

The HttpUrlConnection implementation is overzealous in refusing this kind of request.

So here we are, looking at the code it does not seem obvious to use a different implementation of HttpURLConnection. What is weird is that when I use https, the error does not happen. So I'm kind of stuck. It seems like i will have to switch to another library. Any ideas?

Yes, found out why when using https there is no exception:

if(!"POST".equals(this.method) && !"PUT".equals(this.method) && "http".equals(this.url.getProtocol()))

The last condition makes sure that this exception is only thrown in case of http. HttpsURLConnection delegates to this class for the underlying http protocol, but escapes this case, because the protocol is https obviously.

@LuisMuniz, is this still an issue? I can create a pull request that only obtains the conn.outputstream in case the request method was POST/PUT/GET...

Hi.

I have decided not to use this endpoint accepting DELETE with a body.
This endpoint was being deprecated anyway, indicating the possibility that this was a bad idea.