diff --git a/src/de/aflx/sardine/DavResource.java b/src/de/aflx/sardine/DavResource.java index 6eba99f..2515f2f 100644 --- a/src/de/aflx/sardine/DavResource.java +++ b/src/de/aflx/sardine/DavResource.java @@ -215,13 +215,24 @@ private String getContentType(Response response) */ private long getContentLength(Response response) { -// Propstat list = response.getPropstat(); -// if(list.equals("") || null == list) { -// return null; -// } -// Getcontentlength gcl = list.getProp().ge; + + Propstat list = response.getPropstat(); + if(list.equals("") || null == list) { + return DEFAULT_CONTENT_LENGTH; + } - return -1; + String gcl = list.getProp().getGetcontentlength(); + if ((gcl != null) && (!gcl.isEmpty())) + { + try + { + return Long.parseLong(gcl); + } catch (NumberFormatException e) + { + log.warn(String.format("Failed to parse content length %s", gcl)); + } + } + return DEFAULT_CONTENT_LENGTH; /*List list = response.getPropstat(); if (list.isEmpty()) { return DEFAULT_CONTENT_LENGTH; diff --git a/src/de/aflx/sardine/Sardine.java b/src/de/aflx/sardine/Sardine.java index 93e9757..1f76845 100644 --- a/src/de/aflx/sardine/Sardine.java +++ b/src/de/aflx/sardine/Sardine.java @@ -3,6 +3,8 @@ //import javax.xml.namespace.QName; import de.aflx.sardine.impl.io.ConsumingInputStream; import de.aflx.sardine.util.QName; + +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; @@ -61,6 +63,19 @@ public interface Sardine */ List list(String url, int depth) throws IOException; + /** + * Gets a directory listing using WebDAV PROPFIND. + * + * @param url Path to the resource including protocol and hostname + * @param depth The depth to look at (use 0 for single ressource, 1 for directory listing) + * @param allProp If allprop should be used, which can be inefficient sometimes; + * warning: no allprop does not retrieve custom props, just the basic ones + * @return List of resources for this URI including the parent resource itself + * @throws IOException I/O error or HTTP response validation failure + */ + List list(String url, int depth, boolean allProp) + throws IOException; + /** * @see #patch(String, java.util.Map, java.util.List) */ @@ -170,6 +185,19 @@ public interface Sardine */ void put(String url, InputStream dataStream, Map headers) throws IOException; + /** + * Uses PUT to send data to a server with a specific content + * type header. Not repeatable on authentication failure. + * + * @param url Path to the resource including protocol and hostname + * @param dataStream Input source + * @param contentType MIME type to add to the HTTP request header + * @param length length of the stream + * @throws IOException I/O error or HTTP response validation failure + */ + void put(String url, File dataStream, int length, String contentType) + throws IOException; + /** * Delete a resource using HTTP DELETE at the specified url * @@ -274,4 +302,5 @@ public interface Sardine */ void disablePreemptiveAuthentication(); + } \ No newline at end of file diff --git a/src/de/aflx/sardine/impl/SardineImpl.java b/src/de/aflx/sardine/impl/SardineImpl.java index 4a3d273..4bdbc3d 100644 --- a/src/de/aflx/sardine/impl/SardineImpl.java +++ b/src/de/aflx/sardine/impl/SardineImpl.java @@ -16,6 +16,7 @@ package de.aflx.sardine.impl; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.ProxySelector; @@ -26,10 +27,7 @@ import java.util.List; import java.util.Map; -import de.aflx.sardine.util.QName; - import org.apache.http.HttpEntity; -//import org.apache.http.HttpHeaders; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -42,7 +40,6 @@ import org.apache.http.auth.Credentials; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; -//import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; @@ -53,8 +50,6 @@ import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.params.AuthPolicy; import org.apache.http.client.protocol.ClientContext; -//import org.apache.http.client.protocol.RequestAcceptEncoding; -//import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.PlainSocketFactory; @@ -62,13 +57,12 @@ import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.FileEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.AbstractHttpClient; -//import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; -//import org.apache.http.impl.client.DefaultRedirectStrategy; import org.apache.http.impl.conn.ProxySelectorRoutePlanner; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; @@ -95,17 +89,22 @@ import de.aflx.sardine.impl.methods.HttpMove; import de.aflx.sardine.impl.methods.HttpPropFind; import de.aflx.sardine.impl.methods.HttpUnlock; -import de.aflx.sardine.model.Allprop; import de.aflx.sardine.model.Exclusive; import de.aflx.sardine.model.Lockinfo; import de.aflx.sardine.model.Lockscope; import de.aflx.sardine.model.Locktype; import de.aflx.sardine.model.Multistatus; -import de.aflx.sardine.model.Propfind; import de.aflx.sardine.model.Response; import de.aflx.sardine.model.Write; import de.aflx.sardine.util.Logger; +import de.aflx.sardine.util.QName; import de.aflx.sardine.util.SardineUtil; +//import org.apache.http.HttpHeaders; +//import org.apache.http.client.AuthCache; +//import org.apache.http.client.protocol.RequestAcceptEncoding; +//import org.apache.http.client.protocol.ResponseContentEncoding; +//import org.apache.http.impl.client.BasicAuthCache; +//import org.apache.http.impl.client.DefaultRedirectStrategy; /** * Implementation of the Sardine interface. This is where the meat of the @@ -390,14 +389,25 @@ public List list(String url) throws IOException { * * @see de.aflx.sardine.Sardine#list(java.lang.String) */ - public List list(String url, int depth) throws IOException { + @Override + public List list(String url, int depth) throws IOException + { + return list(url, depth, true); + } + + @Override + public List list(String url, int depth, boolean allProp) throws IOException + { log.warn("list"); HttpPropFind entity = new HttpPropFind(url); entity.setDepth(Integer.toString(depth)); - Propfind body = new Propfind(); - body.setAllprop(new Allprop()); +// Propfind body = new Propfind(); + if (allProp) + entity.setEntity(new StringEntity(" ", UTF_8)); + else + entity.setEntity(new StringEntity(" ", UTF_8)); + // entity.setEntity(new StringEntity(SardineUtil.toXml(body), UTF_8)); - entity.setEntity(new StringEntity(" ", UTF_8)); Multistatus multistatus = this.execute(entity, new MultiStatusResponseHandler()); List responses = multistatus.getResponse(); @@ -688,6 +698,39 @@ public void put(String url, HttpEntity entity, Map headers) } } + @Override + public void put(String url, File dataStream, int length, String contentType) + throws IOException { + HttpPut put = new HttpPut(url); + FileEntity entity = new FileEntity(dataStream, contentType); + + put.setEntity(entity); + Map headers = new HashMap(); + if (contentType != null) { + headers.put("Content-Type", contentType); + } + /*for (String header : headers.keySet()) { + put.addHeader(header, headers.get(header)); + }*/ + if (!put.containsHeader("Content-Type")) { + put.addHeader("Content-Type", HTTP.DEFAULT_CONTENT_TYPE); + } + try { + this.execute(put, new VoidResponseHandler()); + } catch (HttpResponseException e) { + if (e.getStatusCode() == HttpStatus.SC_EXPECTATION_FAILED) { + // Retry with the Expect header removed + put.removeHeaders(HTTP.EXPECT_DIRECTIVE); + if (entity.isRepeatable()) { + this.execute(put, new VoidResponseHandler()); + return; + } + } + + throw e; + } + } + /** * (non-Javadoc) * @@ -823,6 +866,7 @@ protected HttpParams createDefaultHttpParams() { HttpConnectionParams.setTcpNoDelay(params, true); HttpConnectionParams.setSocketBufferSize(params, 8192); + HttpConnectionParams.setConnectionTimeout(params, 10*1000); //10 seconds return params; } diff --git a/src/de/aflx/sardine/model/Prop.java b/src/de/aflx/sardine/model/Prop.java index 102e068..26c02a7 100644 --- a/src/de/aflx/sardine/model/Prop.java +++ b/src/de/aflx/sardine/model/Prop.java @@ -57,14 +57,16 @@ public class Prop { @Element private Resourcetype resourcetype; - @Element + @Element (required = false) private String creationdate; - @Element + @Element (required = false) private String getlastmodified; - @Element + @Element (required = false) private String getetag; @Element (required = false) private String getcontenttype; + @Element (required = false) + private String getcontentlength; public Resourcetype getResourcetype() { return resourcetype; @@ -85,9 +87,13 @@ public String getGetetag() { public String getGetcontenttype() { return getcontenttype; } - - /*protected Creationdate creationdate; + public String getGetcontentlength() { + return getcontentlength; + } + + + /*protected Creationdate creationdate; protected Displayname displayname; protected Getcontentlanguage getcontentlanguage; protected Getcontentlength getcontentlength;