/// <summary> /// Copies a file on the server to another place on the /// server /// </summary> /// <param name="source"> /// The source path. It must be non-null and contain at /// least one character. /// </param> /// <param name="destination"> /// The destination path. It must be non-null and contain /// at least one character. /// </param> /// <param name="allowOverwrite"> /// Flag to allow overwrite /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="contentType"> /// The reported type of the content returned from the /// server. /// </param> /// <param name="resultContent"> /// The content of the resource or null if there was an /// error. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the result content is /// valid. /// </returns> public bool CopyResource( string source, string destination, bool allowOverwrite, out WebDavStatusCode resultCode, out string resultReason, out string contentType, out byte[] resultContent, ProgressContainer sendProgress, ProgressContainer receiveProgress) { return ChangeResourceCmd(CopyRequest, source, destination, allowOverwrite, out resultCode, out resultReason, out contentType, out resultContent, sendProgress, receiveProgress ); }
/// <summary> /// Get a resource from the server. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="contentType"> /// The reported type of the content returned from the /// server. /// </param> /// <param name="resultContent"> /// The content of the resource or null if there was an /// error. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the result content is /// valid. /// </returns> public bool GetResource( string path, out WebDavStatusCode resultCode, out string resultReason, out string contentType, out byte[] resultContent, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = true; // Make sure the input parameters are valid. if( ( path == null ) || ( path.Length == 0 ) ) { throw new ArgumentException( "Invalid resource path.", "path" ); } // Try to get the resource. try { DavResponse response = SendRequest( path, GetRequest, null, null, null, sendProgress, receiveProgress ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; contentType = (string) response.Headers[ ContentTypeHeader ]; resultContent = response.Content; } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; contentType = null; resultContent = null; success = false; } return( success ); }
/// <summary> /// Send a request to the server. This is a low level call /// for callers who need (or want) access to all headers /// returned by the server. /// </summary> /// <param name="resourcePath"> /// The full path to the resource being acted upon. /// </param> /// <param name="method"> /// The name of the method to use (a valid HTTP or /// WebDAV command. /// </param> /// <param name="extraHeaders"> /// An array of extra headers that should be sent in the /// request. /// </param> /// <param name="contentType"> /// The type of data being sent with the request. /// </param> /// <param name="content"> /// The content body of the request. /// </param> /// <param name="sendProgress"> /// The number of bytes sent so far. /// </param> /// <param name="receiveProgress"> /// The number of bytes received so far. /// </param> /// <returns> /// The server's response. /// </returns> protected DavResponse SendRequest( string resourcePath, string method, string[] extraHeaders, string contentType, byte[] content, ProgressContainer sendProgress, ProgressContainer receiveProgress) { // Make sure required parameters are valid. if( ( resourcePath == null ) || ( resourcePath.Length == 0 ) ) { throw new ArgumentException( "The requested resource is invalid.", "resourcePath" ); } if( Array.IndexOf( SupportedMethods, method, 0, SupportedMethods.Length ) < 0 ) { throw new ArgumentException( "The method " + method + " is not supported.", "method" ); } // Determine if the message will include some type of content. bool msgHasContents = ( contentType != null ) && ( content != null ) && ( content.Length > 0 ); // Start the headers with the HTTP method, resource path, and protocol string headers = method + " " + resourcePath + " " + ProtocolVersion + HeaderTerminator; headers += "Host: " + this.ServerUri.Authority + HeaderTerminator; // Send authorization credentials if available. if( ( username != null ) || ( password != null ) ) { string credentialsUser = username; string credentialsPass = password; if( credentialsUser == null ) { credentialsUser = ""; } if( credentialsPass == null ) { credentialsPass = ""; } byte[] credentials = Encoding.UTF8.GetBytes( username + ":" + password ); Console.WriteLine( "Credentials = " + credentials ); string encodedCredentials = System.Convert.ToBase64String( credentials , 0, credentials.Length ); Console.WriteLine( "encoded credentials = " + encodedCredentials ); headers = headers + BasicCredentialsHeader + ": " + BasicCredentialsType + " " + encodedCredentials + HeaderTerminator; Console.WriteLine( "headers = " + headers ); } // Add content headers, if any if( msgHasContents ) { headers = headers + ContentLengthHeader + ": " + content.Length + HeaderTerminator; headers = headers + ContentTypeHeader + ": " + contentType + HeaderTerminator; } // Add user specified headers if( ( extraHeaders != null ) && ( extraHeaders.Length > 0 ) ) { foreach( string header in extraHeaders ) { headers = headers + header + HeaderTerminator; } } // Finish the headers section headers = headers + HeaderTerminator; // Translate the headers into a byte array. byte[] headerBytes = Encoding.ASCII.GetBytes( headers ); // Set the total message length to the length of the headers. int msgLength = headerBytes.Length; // If there is any content in the message, add the size of the content to // the total message size. if( msgHasContents ) { msgLength = msgLength + content.Length; } // Create the message array byte[] msg = new byte[ msgLength ]; // Copy the header bytes. Array.Copy( headerBytes, 0, msg, 0, headerBytes.Length ); // If the message has contents, copy those bytes. if( msgHasContents ) { Array.Copy( content, 0, msg, headerBytes.Length, content.Length ); } //Uncomment the following call to see the message before it is sent. /* Console.WriteLine( "sending message:\n||{0}||\n", Encoding.UTF8.GetString( msg ) ); */ // Create a new TCP client to send the message and get a response. TcpClient comm = new TcpClient(); Console.WriteLine("connecting to host {0} at port {1}", ServerUri.Host, ServerUri.Port ); // Connect to the server comm.Connect( serverUri.Host, ServerUri.Port ); NetworkStream stream = comm.GetStream(); // Send the message. if( sendProgress != null ) { sendProgress.TotalBytesExpected = (ulong) msg.Length; } int sentBytes; int bytesToSend; for( sentBytes = 0; sentBytes < msg.Length; sentBytes = sentBytes + bytesToSend ) { bytesToSend = comm.SendBufferSize; if( sentBytes + bytesToSend > msg.Length ) { bytesToSend = msg.Length - sentBytes; } stream.Write( msg, sentBytes, bytesToSend ); if( sendProgress != null ) { sendProgress.TotalBytes = (ulong) sentBytes; } } if( sendProgress != null ) { sendProgress.TotalBytes = (ulong) sentBytes; } // Prepare to receive a response byte[] responseBuffer = new byte[ comm.ReceiveBufferSize ]; int bytesRead = stream.Read( responseBuffer, 0, responseBuffer.Length ); bool finishedHeaders = false; DavResponse response = null; // Keep reading bytes from the stream until there are none left. Each time // bytes are read, convert them into a string. while( bytesRead > 0 ) { if( !finishedHeaders ) { string responseString = Encoding.UTF8.GetString( responseBuffer, 0, bytesRead ); int currentIndex = 0; int endHeaderLine = responseString.IndexOf( HeaderTerminator ); int endOfHeaders = responseString.IndexOf( HeaderTerminator + HeaderTerminator ); if( endOfHeaders == -1 ) { endOfHeaders = responseString.Length; } string currentHeader = null; while( ( currentIndex < endOfHeaders ) && ( currentIndex < responseString.Length ) && ( endHeaderLine >= 0 ) ) { string line = responseString.Substring( currentIndex, endHeaderLine - currentIndex ); // If the response hasn't been created, the first line is // the status code and needs to be passed to the constructor. if( response == null ) { response = new DavResponse( line ); } // If there is no current header, the line becomes the current // header. else if( currentHeader == null ) { currentHeader = line; } // If the current header is not null and the new line starts // with a space or tab character, it is a continuation of the // current header. else if( ( currentHeader != null ) && ( line.StartsWith( " " ) || line.StartsWith( "\t" ) ) ) { currentHeader = currentHeader + line; } // Otherwise, the line is a new header. else { response.AddHeader( currentHeader ); currentHeader = line; } currentIndex = currentIndex + ( endHeaderLine - currentIndex ) + HeaderTerminator.Length; endHeaderLine = responseString.IndexOf( HeaderTerminator, currentIndex ); if( ( endHeaderLine > endOfHeaders ) && ( currentIndex > endOfHeaders ) ) { currentIndex = currentIndex + HeaderTerminator.Length; } } // Add the last header. if( currentHeader != null ) { response.AddHeader( currentHeader ); finishedHeaders = true; if( receiveProgress != null ) { receiveProgress.TotalBytesExpected = (ulong) response.ExpectedContentLength; } } // If there are additional characters after the headers that have // been unhandled and either the response includes a content or // a Content-Length header was not provided (ie unknown content // length), add whatever bytes that were read but not processed // to the response content. if( ( currentIndex < responseString.Length ) && ( ( response.ExpectedContentLength > 0 ) || ( response.ExpectedContentLength == -1 ) ) ) { byte[] processedBytes = Encoding.UTF8.GetBytes( responseString.Substring( 0, currentIndex ) ); int contentBeginIndex = processedBytes.Length; response.AppendContent( responseBuffer, contentBeginIndex, bytesRead - contentBeginIndex ); if( receiveProgress != null ) { receiveProgress.TotalBytes = receiveProgress.TotalBytes + (ulong) ( bytesRead - contentBeginIndex ); } } } else { response.AppendContent( responseBuffer, bytesRead ); if( receiveProgress != null ) { receiveProgress.TotalBytes = receiveProgress.TotalBytes + (ulong) bytesRead; } } // Try to read more bytes from the stream. bytesRead = stream.Read( responseBuffer, 0, responseBuffer.Length ); } // Close the connection comm.Close(); //Console.WriteLine( "Receieved response:\n{0}\n--------------------\n\n", // response ); return( response ); }
/// <summary> /// Returns the list of resources in the collection. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="resources"> /// The resources contained in the collection, or null if /// there were no resources, or the path did not resolve /// to a collection itself. /// </param> /// <param name="sizes"> /// The sizes of the resources in the collection. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool CollectionContents( string path, out WebDavStatusCode resultCode, out string resultReason, out string[] resources, out long[] sizes, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = true; sizes = null; // Make sure the input parameters are valid. if( ( path == null ) || ( path.Length == 0 ) ) { throw new ArgumentException( "Invalid resource path.", "path" ); } // Try to get the properties. try { string[] propertyKeys = new string[] { DavPropertyUtil.DavResourceTypeProp, DavPropertyUtil.DavContentLengthProp}; byte[] content = DavPropertyUtil.GetPropfindRequestContent( propertyKeys ); string[] propfindHeaders = new string[ 1 ]; propfindHeaders[ 0 ] = "Depth: 1"; DavResponse response = SendRequest( path, PropfindRequest, propfindHeaders, XMLTextContent, content ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; string contentType = (string) response.Headers[ ContentTypeHeader ]; string resultContent = Encoding.UTF8.GetString( response.Content, 0, response.ContentLength ); resources = null; if( resultCode == WebDavStatusCode.MultiStatus ) { Hashtable resourceInfo = DavPropertyUtil.ParseMultiStatus( response.Content ); if( resourceInfo.Count > 1 ) { // Do not return the resource path for the parent. resources = new string[ resourceInfo.Count - 1 ]; sizes = new long[ resourceInfo.Count - 1 ]; int i = 0; foreach( string resKey in resourceInfo.Keys) { if( !resKey.Equals( path ) ) { resources[ i ] = resKey; Hashtable tab = ((Hashtable)((Hashtable) resourceInfo[resKey])[WebDavStatusCode.OK]); if(tab.ContainsKey( DavPropertyUtil.DavContentLengthProp )) sizes[i] = long.Parse(tab[DavPropertyUtil.DavContentLengthProp].ToString()); else sizes[i] = -1; i++; } } } } } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; resources = null; success = false; } catch( XmlException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; resources = null; success = false; } return( success ); }
/// <summary> /// A general purpose test method. /// </summary> public bool Test() { try { WebDavStatusCode resultCode; string resultReason; string contentType; byte[] resultContent; bool success = GetResource( "/", out resultCode, out resultReason, out contentType, out resultContent ); if( success ) { Console.WriteLine("Get (not monitored) result = {0}, reason = {1}, type = {2}, length = {3}", resultCode, resultReason, contentType, resultContent.Length ); Console.WriteLine("Content = {0}", Encoding.UTF8.GetString( resultContent, 0, resultContent.Length ) ); } ProgressContainer sendContainer = new ProgressContainer(); ProgressContainer receiveContainer = new ProgressContainer(); success = GetResource( "/putty.exe", out resultCode, out resultReason, out contentType, out resultContent, sendContainer, receiveContainer ); if( success ) { Console.WriteLine("Get (monitored) result = {0}, reason = {1}, type = {2}, length = {3}", resultCode, resultReason, contentType, resultContent.Length ); } return( true ); } catch( SocketException e ) { Console.WriteLine( "Connection error: {0}", e.Message ); return( false ); } }
/// <summary> /// A template for a MOVE or COPY command /// </summary> /// <param name="command"> /// HTTP command to send /// </param> /// <param name="source"> /// The source path. It must be non-null and /// contain at least one character. /// </param> /// <param name="destination"> /// The destination path. It must be non-null and /// contain at least one character. /// </param> /// <param name="allowOverwrite"> /// Flag to allow overwrite /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the /// exception message if an exception was thrown. /// </param> /// <param name="contentType"> /// The reported type of the content returned from the /// server. /// </param> /// <param name="resultContent"> /// The content of the resource or null if there was an /// error. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the result content is /// valid. /// </returns> protected bool ChangeResourceCmd( string command, string source, string destination, bool allowOverwrite, out WebDavStatusCode resultCode, out string resultReason, out string contentType, out byte[] resultContent, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = true; // Make sure the input parameters are valid. if( ( source == null ) || ( source.Length == 0 ) || ( destination == null ) || ( destination.Length == 0 )) { throw new ArgumentException( "Invalid resource path.", "path" ); } // Try to copy the resource. try { string[] headers = new string[3]; destination = destination.TrimStart('/'); headers[0] = "Host: " + this.serverUri.Host; headers[1] = "Destination: " + this.serverUri + destination; if(allowOverwrite) headers[2] = "Overwrite: T"; else headers[2] = "Overwrite: F"; DavResponse response = SendRequest( source, command, headers, null, null, sendProgress, receiveProgress ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; contentType = (string) response.Headers[ ContentTypeHeader ]; resultContent = response.Content; } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; contentType = null; resultContent = null; success = false; } return( success ); }
/// <summary> /// Get all properties associated with a resource. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="resultContent"> /// A hashtable with the properties of the resource or /// null if there was an error. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool PropfindAll( string path, out WebDavStatusCode resultCode, out string resultReason, out Hashtable properties, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = true; Hashtable prop = new Hashtable(); // Make sure the input parameters are valid. if( ( path == null ) || ( path.Length == 0 ) ) { throw new ArgumentException( "Invalid resource path.", "path" ); } // Try to get the properties. try { byte[] content = DavPropertyUtil.GetPropfindAllRequestContent(); string[] propfindHeaders = new string[ 1 ]; propfindHeaders[ 0 ] = "Depth: 1"; DavResponse response = SendRequest( path, PropfindRequest, propfindHeaders, XMLTextContent, content, sendProgress, receiveProgress ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; string contentType = (string) response.Headers[ ContentTypeHeader ]; string resultContent = Encoding.UTF8.GetString( response.Content, 0, response.ContentLength ); if( resultCode == WebDavStatusCode.MultiStatus ) { DavPropertyUtil.ParseMultiStatus( response.Content, prop ); properties = prop; } else { properties = null; } } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; properties = null; success = false; } catch (XmlException e) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; properties = null; success = false; } return( success ); }
/// <summary> /// Retrieve the names available properties on a resource. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="propertyNames"> /// An array of property names. Just because a property is listed here does /// not mean the caller has permission to retrieve the value. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="resultContent"> /// A hashtable with the properties of the resource or /// null if there was an error. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool Propnames( string path, out WebDavStatusCode resultCode, out string resultReason, out string[] propertyNames, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = true; // Make sure the input parameters are valid. if( ( path == null ) || ( path.Length == 0 ) ) { throw new ArgumentException( "Invalid resource path.", "path" ); } // Try to get the properties. try { byte[] content = DavPropertyUtil.GetPropfindNamesRequestContent(); string[] propfindHeaders = new string[ 1 ]; propfindHeaders[ 0 ] = "Depth: 0"; DavResponse response = SendRequest( path, PropfindRequest, propfindHeaders, XMLTextContent, content, sendProgress, receiveProgress ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; string contentType = (string) response.Headers[ ContentTypeHeader ]; string resultContent = Encoding.UTF8.GetString( response.Content, 0, response.ContentLength ); propertyNames = null; if( resultCode == WebDavStatusCode.MultiStatus ) { Hashtable statusTable = (Hashtable) DavPropertyUtil.ParseMultiStatus( response.Content )[ path ]; if( statusTable.ContainsKey( WebDavStatusCode.OK ) ) { Hashtable availableProps = (Hashtable) statusTable[ WebDavStatusCode.OK ]; // Subtract 2 keys (the result code and result string are not props) propertyNames = new string[ availableProps.Count - 2 ]; int i = 0; foreach( string prop in availableProps.Keys ) { if( !prop.Equals( DavPropertyUtil.DAVSharpReasonCodeKey ) && !prop.Equals( DavPropertyUtil.DAVSharpReasonStringKey ) ) { propertyNames[ i ] = prop; i++; } } } } } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; propertyNames = null; success = false; } catch( XmlException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; propertyNames = null; success = false; } return( success ); }
/// <summary> /// Get the specified properties associated with a /// resource. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="propertyKey"> /// The key of the property to be retrieved. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="property"> /// A hashtable with the properties of the resource or /// null if there was an error. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool Propfind( string path, string propertyKey, out WebDavStatusCode resultCode, out string resultReason, out object property, ProgressContainer sendProgress, ProgressContainer receiveProgress) { string[] propertyList = new string[] { propertyKey }; Hashtable properties; bool success = Propfind(path, propertyList, out resultCode, out resultReason, out properties, sendProgress, receiveProgress ); property = null; if( success && ( properties != null ) ) { foreach( WebDavStatusCode statusCode in properties.Keys ) { Hashtable propInfo = (Hashtable) properties[ statusCode ]; if( propInfo.ContainsKey( propertyKey ) ) { resultCode = (WebDavStatusCode) propInfo[ DavPropertyUtil.DAVSharpReasonCodeKey ]; resultReason = (string) propInfo[ DavPropertyUtil.DAVSharpReasonStringKey ]; property = propInfo[ propertyKey ]; } } } return( success ); }
/// <summary> /// Make a new collection at the specified path. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool Mkcol( string resourcePath, out WebDavStatusCode resultCode, out string resultReason, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = true; // Try to get the resource. try { DavResponse response = SendRequest(resourcePath, MkcolRequest, null, null, null, sendProgress, receiveProgress ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; success = false; } return success; }
/// <summary> /// Locks a resource. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest /// if an exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the /// exception message if an exception was thrown. /// </param> /// <param name="contentType"> /// The reported type of the content returned /// from the server. /// </param> /// <param name="resultContent"> /// The content of the resource or null if /// there was an error. /// </param> /// <param name="lockToken"> /// The lock token if the resource is locked or null /// if the resource could not be locked. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication error /// prevented the request from succeeding. If true, the caller should /// examine the result code and reason to determine whether or not the /// result content is valid. /// </returns> public bool LockResource(string path, out WebDavStatusCode resultCode, out string resultReason, out string contentType, out byte[] resultContent, out string lockToken, ProgressContainer sendProgress, ProgressContainer receiveProgress) { // Local variables bool success = true; string CR = "\n"; string xmlFluff = XMLContentPreamble + CR + "<D:lockinfo xmlns:D=\"DAV:\">" + CR + " <D:lockscope><D:exclusive/></D:lockscope>" + CR + " <D:locktype><D:write/></D:locktype>" + CR + " <D:owner>" + CR + " <D:href>http://whisper.cse.ucsc.edu:16080/csharp</D:href>" + CR + " </D:owner>" + CR + "</D:lockinfo>" + CR; string[] headers = new string[] { "Depth: infinity" }; lockToken = null; // Make sure the input parameters are valid. if( ( path == null ) || ( path.Length == 0 ) ) { throw new ArgumentException( "Invalid resource path.", "path" ); } // Try to lock the resource. try { DavResponse response = SendRequest(path, LockRequest, null, XMLTextContent, System.Text.Encoding.UTF8.GetBytes(xmlFluff), sendProgress, receiveProgress ); // Extract the response data for the caller. resultCode = response.StatusCode; resultReason = response.StatusReason; contentType = (string) response.Headers[ ContentTypeHeader ]; resultContent = response.Content; // Extract lock token from XML body if (response.StatusCode == WebDavStatusCode.OK) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.Load(new System.IO.StringReader( System.Text.Encoding.UTF8.GetString( response.Content, 0, response.ContentLength ) ) ); System.Xml.XmlNodeReader xmlReader = new System.Xml.XmlNodeReader(doc); do { xmlReader.Read(); } while (xmlReader.Name != "D:locktoken"); do { xmlReader.Read(); } while (xmlReader.Name != "D:href"); xmlReader.Read(); lockToken = xmlReader.Value.Trim(); } } catch( SocketException e ) { // Flag an exception as a bad request and send the exception message // back to the caller. resultCode = WebDavStatusCode.BadRequest; resultReason = e.Message; contentType = null; resultContent = null; lockToken = null; success = false; } return( success ); }
/// <summary> /// Determine if the resource at the given path is a /// collection or not. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool IsCollection( string path, out WebDavStatusCode resultCode, out string resultReason, out bool isCollection, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = false; object typeInfo; isCollection = false; if( GetResourceType( path, out resultCode, out resultReason, out typeInfo, sendProgress, receiveProgress ) && ( typeInfo != null ) ) { success = true; Hashtable typeInfoTable = (Hashtable) typeInfo; isCollection = typeInfoTable.ContainsKey( DavPropertyUtil.DavCollectionProp ); } return( success ); }
/// <summary> /// Returns the type info associated with a resource. By /// default, resources have an empty resourcetype. /// Collections have an empty sub-element DAV:collection /// to flag the resource as a collection. /// </summary> /// <param name="path"> /// The path of the resource. It must be non-null and /// contain at least one character. /// </param> /// <param name="resultCode"> /// The result code from the server or BadRequest if an /// exception was thrown. /// </param> /// <param name="resultReason"> /// The result message from the server or the exception /// message if an exception was thrown. /// </param> /// <param name="typeInfo"> /// The resource type information as stored on the server. /// </param> /// <param name="sendProgress"> /// Used to monitor the progress of sending the request. /// </param> /// <param name="receiveProgress"> /// Used to monitor the progress of receiving the response. /// </param> /// <returns> /// true if the call succeeded, false if a communication /// error prevented the request from succeeding. If true, /// the caller should examine the result code and reason /// to determine whether or not the properties are valid. /// </returns> public bool GetResourceType( string path, out WebDavStatusCode resultCode, out string resultReason, out object typeInfo, ProgressContainer sendProgress, ProgressContainer receiveProgress) { bool success = Propfind( path, DavPropertyUtil.DavResourceTypeProp, out resultCode, out resultReason, out typeInfo, sendProgress, receiveProgress ); return( success ); }