RE: PUT to a Microsoft Sharepoint working with Slide

2006-12-13 Thread Miguel Figueiredo

Hey Chandler,

 Many thanks for this important piece of the information!
 I'm sure it can be used in many other situations related with NTLM
authentication.
 
Best regards,
Miguel Figueiredo


-Original Message-
From: Andy Chandler [mailto:[EMAIL PROTECTED] 
Sent: quarta-feira, 13 de Dezembro de 2006 17:53
To: slide-user@jakarta.apache.org
Subject: PUT to a Microsoft Sharepoint working with Slide

Well since I've seen others with similar issues I thought I'd share how
I managed to get it working - it does take a modification to both the
slide and the httpclient libraries.   Please Note I've done my work with
HTTPClient 3.01 and Slide 2.1 (I've also done the same work with the
trunks of both projects and the result is the same)
 
 
Problem:   Need to upload files to Microsoft Sharepoint with NTLM
authentication.   NTLM authentication will cause an exception about
unbuffered enclosing entity can't be resent or retried (I'm sorry I no
longer get the message so I can't paste it in).   Contrary to other
messages if the server is Microsoft and the client is java turning off
expect-continue does not fix the problem.   The problem stems from the
fact that the Put Method on http client is setting the size of the
content when it creates an InputStreamRequestEntity.   This causes the
entity to not buffer itself (Why you would want this I don't know since
it only buffers 4k at a time).   I haven't tried large files yet so
there may still be additional work that has to be done to get this to
work out correctly if the file is large.   Anyhow the buffering is
important simply because when you try to put a file to an NTLM
authenticated resource the first attempt will fail with a not
authorized.   This will cause a challenge response handshake and then a
retry happens.   The problem is with an unbuffered input stream the
retry does not occur because the enclosing entity claims its not
repeatable.   Failure every time.
 
 
 
My solution which is not necessarily elegant but may help some desperate
developer out there consists of the following changes:
 
1: In the jakarta.commons.httpclient project modify:
org.apache.commons.httpclient.methods.InputStreamRequestEntity
When contentlength is declared set it equal to
CONTENT_LENGTH_AUTO  // This change is probably not absolutely required
but its what I did.
org.apache.commons.httpclient.methods.EntityEnclosingMethod
Modify method generateRequestEntity - change the new for
new InputStreamRequestEntity to use the single arge constructor   as in
 new InputStreamRequestEntity(is)// By not passing the size it
stays in CONTENT_LENGTH_AUTO mode which permits buffering.
 
 
2:  In the Slide webdavclient project modify 
org.apache.webdav.lib.WebdavResource
In the put(String,InputStream) method remove the content length
chunked set command.
 
 
 
Sample code that now works:
 
public static void main(String[] args){
 
try {
File file = new File(src);
 
if (file.exists()) {
System.out.println(Uploading ' + file.getCanonicalPath()
+ ' to ' + dest + ' );
uploadWebDav(file);
 
 
} catch (Exception e) {
System.out.println(e.getMessage());
}
 
 
private static void uploadWebDav(File file) {
WebdavResource webdavResource = null;
try {
NTCredentials creds2 = new NTCredentials(myusername, mypassword,
myclientpc, NTDOMAIN); 
 
 
 
webdavResource = new WebdavResource(
http://SHAREPOINTSERVER/Shared Documents, creds2);
 
String[] list = webdavResource.list();
for (String s :list){
System.out.println(s);
}
 
 
 
System.out.println(Uploading);
// Note - use the putmethod where specify a destination path and that
you include the desired filename 
if (webdavResource.putMethod(http://SHAREPOINTSERVER/Shared
Documents/cofs9.zip , new FileInputStream(file))) {
System.out.println(succeeded.);
 
}
} catch (Exception e1) {
System.out.println(e1.getMessage());
}
}
 
 
 
 
 
 
 
 
 


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: PUT to a Microsoft Sharepoint working with Slide

2006-12-13 Thread Andy Chandler
 I actually have an improvement - you no longer have to modify the
httpclient library at all.   Simply a 1 line change to the
webdavresource method does the trick!  I can't figure out why httpclient
doesn't handle chunked code better but since auto seems to chunk if
needed it seems a harmless change and makes sharepoint much happier.



Change this method
   public boolean putMethod(String path, InputStream is)
throws HttpException, IOException {

setClient();
PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
generateIfHeader(method);
if (getGetContentType() != null 
!getGetContentType().equals())
method.setRequestHeader(Content-Type,
getGetContentType());
method.setRequestContentLength(method.CONTENT_LENGTH_CHUNKED);
method.setRequestBody(is);
generateTransactionHeader(method);
int statusCode = client.executeMethod(method);

setStatusCode(statusCode);
return (statusCode = 200  statusCode  300) ? true : false;
}


To:
   public boolean putMethod(String path, InputStream is)
throws HttpException, IOException {

setClient();
PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
generateIfHeader(method);
if (getGetContentType() != null 
!getGetContentType().equals())
method.setRequestHeader(Content-Type,
getGetContentType());
method.setRequestContentLength(method.CONTENT_LENGTH_AUTO);
method.setRequestBody(is);
generateTransactionHeader(method);
int statusCode = client.executeMethod(method);

setStatusCode(statusCode);
return (statusCode = 200  statusCode  300) ? true : false;
}










-Original Message-
From: Miguel Figueiredo [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, December 13, 2006 12:24 PM
To: 'Slide Users Mailing List'
Subject: RE: PUT to a Microsoft Sharepoint working with Slide


Hey Chandler,

 Many thanks for this important piece of the information!
 I'm sure it can be used in many other situations related with NTLM
authentication.
 
Best regards,
Miguel Figueiredo


-Original Message-
From: Andy Chandler [mailto:[EMAIL PROTECTED]
Sent: quarta-feira, 13 de Dezembro de 2006 17:53
To: slide-user@jakarta.apache.org
Subject: PUT to a Microsoft Sharepoint working with Slide

Well since I've seen others with similar issues I thought I'd share how
I managed to get it working - it does take a modification to both the
slide and the httpclient libraries.   Please Note I've done my work with
HTTPClient 3.01 and Slide 2.1 (I've also done the same work with the
trunks of both projects and the result is the same)
 
 
Problem:   Need to upload files to Microsoft Sharepoint with NTLM
authentication.   NTLM authentication will cause an exception about
unbuffered enclosing entity can't be resent or retried (I'm sorry I no
longer get the message so I can't paste it in).   Contrary to other
messages if the server is Microsoft and the client is java turning off
expect-continue does not fix the problem.   The problem stems from the
fact that the Put Method on http client is setting the size of the
content when it creates an InputStreamRequestEntity.   This causes the
entity to not buffer itself (Why you would want this I don't know since
it only buffers 4k at a time).   I haven't tried large files yet so
there may still be additional work that has to be done to get this to
work out correctly if the file is large.   Anyhow the buffering is
important simply because when you try to put a file to an NTLM
authenticated resource the first attempt will fail with a not
authorized.   This will cause a challenge response handshake and then a
retry happens.   The problem is with an unbuffered input stream the
retry does not occur because the enclosing entity claims its not
repeatable.   Failure every time.
 
 
 
My solution which is not necessarily elegant but may help some desperate
developer out there consists of the following changes:
 
1: In the jakarta.commons.httpclient project modify:
org.apache.commons.httpclient.methods.InputStreamRequestEntity
When contentlength is declared set it equal to
CONTENT_LENGTH_AUTO  // This change is probably not absolutely required
but its what I did.
org.apache.commons.httpclient.methods.EntityEnclosingMethod
Modify method generateRequestEntity - change the new for
new InputStreamRequestEntity to use the single arge constructor   as in
 new InputStreamRequestEntity(is)// By not passing the size it
stays in CONTENT_LENGTH_AUTO mode which permits buffering.
 
 
2:  In the Slide webdavclient project modify
org.apache.webdav.lib.WebdavResource
In the put(String,InputStream) method remove the content length
chunked set command.
 
 
 
Sample code that now works:
 
public static void main(String[] args){
 
try {
File file = new File(src);
 
if (file.exists()) {
System.out.println(Uploading