Bug 39220 - Missing body in a PROPFIND request
Summary: Missing body in a PROPFIND request
Status: RESOLVED DUPLICATE of bug 35213
Alias: None
Product: Slide
Classification: Unclassified
Component: WebDAV client (show other bugs)
Version: 2.1
Hardware: Other Windows XP
: P2 major (vote)
Target Milestone: ---
Assignee: Slide Developer List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-04-06 11:07 UTC by Nick Dolgov
Modified: 2007-02-05 12:30 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Dolgov 2006-04-06 11:07:58 UTC
1. Invocations of the setHttpURL() method made from constructors lead to 
generation of a PROPFIND request with a missing body. Moreover, the "Content-
Type" header is not set for that request as well. As a result, a WebdavResource 
constructor throws an exception: 

    public void test() throws Exception {
        HttpURL url = new HttpURL("http://localhost:8080/slide/");
        WebdavResource webdav = new WebdavResource(url, 1, true);
    }

generates (Apache Tomcat/5.5.9)

PROPFIND /slide/ HTTP/1.1
Content-Type: text/xml; charset=utf-8
User-Agent: Jakarta Commons-HttpClient/3.0
Host: 127.0.0.1:8081
Depth: 1

which leads to

org.apache.commons.httpclient.HttpException
	at org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.
java:3467)
	at org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.
java:3423)
	at org.apache.webdav.lib.WebdavResource.setNamedProp(WebdavResource.java:
967)
	at org.apache.webdav.lib.WebdavResource.setBasicProperties(WebdavResource.
java:912)
	at org.apache.webdav.lib.WebdavResource.setProperties(WebdavResource.java:
1894)
	at org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:
1301)
	at org.apache.webdav.lib.WebdavResource.<init>(WebdavResource.java:275)


because of

HTTP/1.1 400 Bad Request: Request content missing
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=7006BD8F1AE1863B56B86D1C79276E8D; Path=/slide
Content-Type: text/html;charset=utf-8
Content-Length: 1077
Date: Thu, 06 Apr 2006 08:50:30 GMT
Connection: close


2. There is a typo in a constructor (there should not be "this." prefix!)

public WebdavResource(HttpURL httpURL, int action, int depth,             
boolean followRedirects)throws HttpException, IOException {
       
    setFollowRedirects(this.followRedirects);

}
Comment 1 Gilles Gaillard 2006-05-30 21:19:37 UTC
The issue lies in method HttpRequestBodyMethodBase#writeRequestBody where
the bytes are not properly written to the underlying ChunkedOutputStream stream 
when using chunked contents. The corrected method is shown below.

Additionally, please also note the wrong comment in the method comment and in 
the class header.

    protected boolean writeRequestBody(HttpState state, HttpConnection conn)
        throws IOException, HttpException {
        OutputStream out = conn.getRequestOutputStream();
        if (isHttp11() && (null == getRequestHeader("Content-Length"))) {
            out = new ChunkedOutputStream(out);
        }

        InputStream inputStream = null;
        if (file != null && file.exists()) {
            inputStream = new FileInputStream(file);
        } else if (url != null) {
            inputStream = url.openConnection().getInputStream();
        } else if(data != null){
            inputStream = new ByteArrayInputStream(data);
        } else {
            return true;
        }

        byte[] buffer = new byte[4096];
        int nb = 0;
        while (true) {
            nb = inputStream.read(buffer);
            if (nb == -1) {
                break;
            }
            out.write(buffer, 0, nb);
        }
        if (out instanceof ChunkedOutputStream){
          ((ChunkedOutputStream)out).finish();
        }
        out.flush();
        return true;
    }
Comment 2 Gilles Gaillard 2006-06-15 15:46:10 UTC
You also need to override the inherited method #addRequestHeaders otherwise
there is no Content-Length nor Transfer-Encoding header, and some server does 
not like that.

    /**
     * Overrides the inherited method to add a header "Transfer-Encoding: 
     * chunked" if the content-length has not been already set, as expected by 
     * the method writeRequestBody.
     *  
     * @see #writeRequestBody
     */
    protected void addRequestHeaders(HttpState state, HttpConnection conn)
    throws IOException, HttpException {
      super.addRequestHeaders(state, conn);
      if (isHttp11() && getRequestHeader("Content-Length")==null) {
        int len = getRequestContentLength();
        if (len>=0){
          setRequestHeader("Content-Length", String.valueOf(len));
        }
        else setRequestHeader("Transfer-Encoding", "chunked");
      }
    }
Comment 3 Vadim Gritsenko 2007-02-05 12:30:55 UTC
Very similar patch from the bug #35213 was applied to the trunk by antoine.

*** This bug has been marked as a duplicate of 35213 ***