0

I have a cloud storage at strato namely hidrive. It uses the webdav protocol. Note that it's based on HTTP. The client application they provide is poor and buggy so I tried various other tools for synchronization but none just worked the way I need it.

I'm therefore trying to implement it in Java using the Sardine project. Is there any code for hard-copying a local source folder to an external cloud folder? I haven't found anything in that direction.

The following code is supposed to upload the file...

Sardine sardine = SardineFactory.begin("username", "password");

InputStream fis = new FileInputStream(new File("some/file/test.txt"));
sardine.put("https://webdav.hidrive.strato.com/users/username/Backup", fis);

... but throws an exception instead:

Exception in thread "main" com.github.sardine.impl.SardineException: Unexpected response (301 Moved Permanently)
    at com.github.sardine.impl.handler.ValidatingResponseHandler.validateResponse(ValidatingResponseHandler.java:48)
    at com.github.sardine.impl.handler.VoidResponseHandler.handleResponse(VoidResponseHandler.java:34)
    at com.github.sardine.impl.handler.VoidResponseHandler.handleResponse(VoidResponseHandler.java:1)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:218)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:160)
    at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:828)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:755)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:738)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:726)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:696)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:689)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:682)
    at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:676)

Printing out the folders in that directory works so the connection/ authentication did succeed:

List<DavResource> resources = sardine.list("https://webdav.hidrive.strato.com/users/username/Backup");

for (DavResource res : resources)
{
    System.out.println(res);
}

Please either help me fix my code or link me to some file synchronization library that works for my purpose.

printminion
  • 2,988
  • 1
  • 26
  • 30
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185

3 Answers3

0

Sardine uses (internally) HttpClient. There is similar question here where you can find an answer Httpclient 4, error 302. How to redirect?.

Community
  • 1
  • 1
kulatamicuda
  • 1,603
  • 2
  • 21
  • 40
  • How to do it using `Sardine`? There's a `SardineRedirectStrategy` class but no methods in the `Sardine` class to change the redirect strategy. No examples exist on this. – BullyWiiPlaza Jul 04 '14 at 14:22
  • Not expert on Sardine, but if you look on Sardine source on GitHub (SardineImpl.java) you will see what exactly they are doing with HttpClient they obtain via HttpClientBuilder. So you can modify behaviour by decorating this class if there is no other public API in Sardine itself. – kulatamicuda Jul 04 '14 at 14:35
0

Try converting the InputStream obj into byte array before you call put(). Something like the below,

byte[] fisByte = IOUtils.toByteArray(fis);
sardine.put("https://webdav.hidrive.strato.com/users/username/Backup", fisByte);

It worked for me. Let me know.

Augie
  • 33
  • 6
0

I had to extend the "org.apache.http.impl.client.LaxRedirectStrategy" and also the getRedirect() Method of org.apache.http.impl.client.DefaultRedirectStrategy with a treatment of the needed methods: PUT, MKOL, etc. . By default only GET is redirected.

It looks like this:

private static final String[] REDIRECT_METHODS = new String[] { HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME, HttpPut.METHOD_NAME, HttpDelete.METHOD_NAME, HttpMkCol.METHOD_NAME };

isRedirectable-Method

for (final String m : REDIRECT_METHODS) {
  if (m.equalsIgnoreCase(method)) {
    System.out.println("isRedirectable true");
    return true;
  }
}

return method.equalsIgnoreCase(HttpPropFind.METHOD_NAME);

getRedirect-Method:

final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
  return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
  return new HttpGet(uri);
} else if (method.equalsIgnoreCase(HttpPut.METHOD_NAME)) {

  HttpPut httpPut = new HttpPut(uri);
  httpPut.setEntity(((HttpEntityEnclosingRequest) request).getEntity());
  return httpPut;
} else if (method.equalsIgnoreCase("MKCOL")) {
  return new HttpMkCol(uri);
} else if (method.equalsIgnoreCase("DELETE")) {
  return new HttpDelete(uri);

} else {
  final int status = response.getStatusLine().getStatusCode();

  if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
    return RequestBuilder.copy(request).setUri(uri).build();
  } else {
    return new HttpGet(uri);
  }
}

That worked for me.

Jay
  • 1
  • 1