Getting Started
Getting started with DAV SDK involves two primary steps:
- Hosting the DAVServer class
- Handling the DAVServer class's events
This page provides basic information for both of these two steps.
Hosting
DAVServer comes packaged with an embedded HTTP server, but can also be hosted in an existing Web environment such as ASP.NET Core, Apache Tomcat, or others. While the developer experience is largely the same between these two processing modes, there are some differences in authentication and request processing depending on how the server is hosted.
DAVServer's ProcessingMode property governs whether the class is operating via the embedded HTTP server, an external server, or in a fully-offline mode.
Details relevant to hosting DAVServer in an external server framework can be found in the Hosting Options page. The following information is relevant when using the embedded server.
Starting the Server
When functioning in embedded server mode, the class's StartListening method causes the embedded web server to begin listening for inbound WebDAV requests. LocalHost and LocalPort must be set prior to starting the server.
if (procmode == DAVServerProcessingModes.modeEmbeddedServer)
{
server.ServerSettings.LocalHost = "localhost";
server.ServerSettings.LocalPort = "80";
server.StartListening();
}
The StopListening method prevents future connections from being accepted, but does not forcibly end existing connections.
Enabling SSL (HTTPS)
When the ServerCert property is set to an SSL certificate, the embedded HTTP server will use SSL and only accept secure (HTTPS) connections. When this property is not set to an SSL certificate, the embedded server will accept plaintext (HTTP) connections.
Authentication
When hosting DAVServer in an external server framework, authentication is performed outside of the class. More details are provided in the Hosting Options page.
When hosting DAVServer using the embedded web server, the AllowedAuthMethods field determines which authentication schemes the embedded server will accept.
Before processing a request, the UserAuthRequest event will fire, providing access to details like the provided username, password, or Kerberos SPN. Within this event handler, developers have control over the logic used to determine if the client has successfully authenticated.
Handling Class Events
As DAVServer processes requests from WebDAV clients, the class fires events corresponding to the type and target of the DAV request. The code written in the event handlers for each event determines the behavior of the DAV server.
The parameters of these events provide access to important details, such as information provided by the client in the request. For certain events, specific event parameters must be set within the event handler to properly process and respond to client requests.
The easiest way to understand this event-driven flow is through an example, such as the series of events that fire when a client attempts to list a directory.
Example: List Directory
When a client lists a directory in the WebDAV server, the class fires the following series of events while processing the request:
SessionStart
This event fires when the class first receives a connection that it recognizes as an HTTP (or HTTPS) connection. An event parameter called SessionId provides a way for developers to track current sessions and associate a session with a particular user, context, etc.
More information can be found in the SessionStart event.
UserAuthRequest
This event fires to authenticate the user that is attempting to connect when DAVServer is hosted using the embedded web server. This event does not fire for other processing modes. The event parameters provide access to the client's authentication details, such as User and Password. Inside the event handler, developers can perform any authentication logic that is appropriate, then set the Accept event parameter to true to authenticate the user or false to refuse authentication.
More information can be found in the UserAuthRequest event.
For more information on handling authentication when using an external server framework, please see the Hosting Options page.
GetFileInfo
This event fires to get basic information about the file or folder that is the target of a client's request (e.g. whether the target exists, whether it is a file or a folder, etc). The event parameters provide the Path to the target resource, and developers should set event parameters (e.g. Size, LastModifiedTime, etc) to the appropriate values for the requested resource.
More information can be found in the GetFileInfo event.
CheckAccess
This event fires to give developers a chance to confirm that the user has the appropriate level of access to the requested resource. The event parameters provide information on the target resource and type of operation requested, and the ResultCode parameter can be set to 0 to indicate the user has access or a non-zero value to deny access.
More information can be found in the CheckAccess event.
ListDirectory
This event fires to give developers an opportunity to provide the full list of files inside the directory. Inside this event handler, developers should enumerate each file or sub-folder and call the ListFile method for each one to build the list of files and directories which will be returned to the client.
More information can be found in the ListDirectory event.
SessionEnd
This event fires after the class has responded to the client request and is ending the HTTP session. It gives developers a chance to clean up any data which may have been stored outside of the component for the specified SessionId value.
More information can be found in the SessionEnd event.
Custom Event Behavior
The benefit of DAV SDK's event-driven architecture is the ability to insert custom logic within any of the class's event handlers. The demo that comes packaged with the SDK demonstrates a simple implementation of these events, with the class servicing requests like a standard WebDAV server. However, the ability to execute custom logic within each event handler enables developers to extend WebDAV server functionality to handle additional use cases.
One such use case is extending your WebDAV server to include non-file data sources, like databases. In this model, when a client asks to list a directory, the application might service this request by listing the rows in a particular database table. The data from the database will be presented to the client as if they are file resources on a WebDAV server, and the client does not need to know that the backend storage is actually a database.
To understand this, consider the same List Directory example from above, but now assume that all relevant data exists inside of a database instead of in a file system. A developer might implement logic like the following in each event handler:
- SessionStart - Attempt to establish a connection to the database.
- UserAuthRequest - Use the authentication credentials provided by the client to try and authenticate to the database.
- GetFileInfo - Check for the existence, size, etc, of a database table that matches the name of the "directory" to list.
- CheckAccess - Perform a simple SELECT query to confirm that the user has read access to this table.
- ListDirectory - For each row, extract the relevant data and return it to the client via the ListFile method.
- SessionEnd - Close the connection to the database.
This example omits details for the sake of brevity, but demonstrates the principle that drives DAV SDK's usefulness: within the event handlers of the DAVServer class, you can perform any data access logic you wish and present any arbitrary data to WebDAV clients as if they were file resources on your WebDAV server.
Access Management
When a client makes a WebDAV request, the HTTP session associated with this request is assigned a SessionId. This SessionId is available within each of the events that fire in sequence to process the request. Developers should associate this SessionId with a user account or profile in an external data structure so that user information can be retrieved by using a SessionId as the key.
CheckAccess is a dedicated event that provides access to the SessionId, type of operation requested, and target of that operation. Within this event handler, developers can use the SessionId to determine which user is making the request, then perform any custom logic required to determine if that user has permission to perform the requested operation on the target resource.
Implementing access and permissions logic within the CheckAccess event can help logically separate and compartmentalize access control from other server behavior. However, since the SessionId is also available in other events where the operation is executed, it is possible to also (or only) perform access validation in these events.
Session Parameters
Developers can associate arbitrary parameters with SessionId's using the SetSessionParam and GetSessionParam methods. For example, a 'read-only' flag could be set in the CheckAccess event using SetSessionParam, which can then be checked via GetSessionParam in any 'write' events to confirm that the current user is now restricted to read operations.
Session parameters are not strictly necessary for server functionality, but may be convenient or help improve code clarity.
Hosting Options
The DAVServer class can be hosted via an external server framework like ASP.NET Core, via an embedded HTTP server, or in a fully offline mode. The ProcessingMode property should be set according to the type of hosting option used. Possible hosting options are:
The following aspects of class use and behavior are impacted by hosting options:
- Processing Inbound Requests
- Authentication
- Configuration Requirements
- Connection Security
- Sending Responses
Embedded Server
Processing Inbound Requests
When functioning in embedded server mode, the component's StartListening method causes the embedded web server to begin listening for inbound DAV requests. LocalHost and LocalPort must be set prior to starting the server.
if (procmode == DAVServerProcessingModes.modeEmbeddedServer)
{
server.ServerSettings.LocalHost = "localhost";
server.ServerSettings.LocalPort = "80";
server.StartListening();
}
The StopListening method disconnects any connected clients and stops listening.
Authentication
When hosting DAVServer using the embedded web server, the AllowedAuthMethods field determines which authentication schemes the embedded server will allow.
Before processing a request, the UserAuthRequest event will fire, providing access to details like the provided username, password, or Kerberos Service Principal Name (SPN). Within this event handler, developers have control over the logic used to determine if the client has successfully authenticated. Typically, this will involve maintaining a dictionary or another data structure that contains valid authentication credentials like username/password combinations. This data structure of valid authentication credentials is not maintained within the properties of DAV SDK components.
Configuration Requirements
The embedded server's behavior is configured via the ServerSettings property and the ServerCert property. These settings control the local interface and port on which the server listens, as well as the allowed authentication methods.
Connection Security
When using the embedded server, the server hosts a plaintext (HTTP) endpoint by default. The ServerCert property is used to enable TLS for secure connections. When ServerCert is set to a TLS certificate, the embedded HTTP server will use and require TLS for inbound HTTPS connections.
Sending Responses
The type of HTTP response generated by the class depends on logic that occurs within events that fire as the class processes requests. Many events include a parameter like ResultCode, and this parameter can be set to a non-zero value within event handlers to indicate specific types of failures. The Error Handling page details how ResultCode values are translated to specific error codes and responses.
After processing a request, the class automatically sends an HTTP response according to the WebDAV standard. Errors are reported to the client via HTTP error responses, and success is reported via 200 OK. The contents of the response depend on the specific operation performed; for example, the response body of a GET request to retrieve a file will include the contents of the requested file.
External Server
Processing Inbound Requests
When functioning in external server mode, the external server framework listens for HTTP requests. The HttpContext object must be passed explicitly to a DAV SDK class to process the request.
The ProcessRequest method takes a Request object as a parameter, and instructs the class to begin processing the request.
Authentication
Authentication occurs outside the scope of DAV SDK when using the external server mode. Prior to passing the Request to the class via ProcessRequest, the incoming request should be authenticated using using appropriate mechanism. For instance an ASP.NET Core application may require basic or NTLM authentication to access the endpoint where the request will be processed. Once the request has been authenticated through external verification, the Request should be passed to the ProcessRequest method.
Configuration Requirements
External servers may require configuration such that WebDAV requests can be passed to DAV SDK. The details depend on the framework used to build the external server.
Java Servlets
The server is compatible with standard implementations of HttpServlet, if they pass all requests to the service() method.
Connection Security
When hosting the class via an external server, the security settings in the external server framework determine connection security. The class has no impact on TLS in this processing mode.
Sending Responses
The type of HTTP response generated by the class depends on logic that occurs within events that fire as the class processes requests. Many events include a parameter like ResultCode, and this parameter can be set to a non-zero value within event handlers to indicate specific types of failures. The Error Handling page details how ResultCode values are translated to specific error codes and responses.
When calling the ProcessRequest method, an HttpResponse object should be passed as a method parameter (as well as the HttpRequest). The class will populate the response object with the status code, headers, and body generated while processing the request. The Java servlet can then use this object to return the response to the connected client.
Offline Mode
Processing Inbound Requests
When functioning in offline mode, the class uses the Request and RequestHeaders properties to read inbound requests. These properties should be set to the request body and headers, respectively, before processing the request by calling ProcessRequest with null Request and Response parameters.
In offline mode, the class will not attempt to send a response to clients. Instead, the Response and ResponseHeaders are set to the body content and headers (respectively) of the response.
Authentication
Authentication is fully outside the scope of the class when using offline mode. The class will process requests without any direct checks for authentication.
Configuration Requirements
In offline mode, the class is agnostic to any process that occurs prior to setting the Request and RequestHeaders properties, and as such does not require any additional configuration.
Connection Security
In offline mode, the class does not have a live connection to a client, so connection security is not directly relevant to the class's operation.
Sending Responses
The type of HTTP response generated by the class depends on logic that occurs within events that fire as the class processes requests. Many events include a parameter like ResultCode, and this parameter can be set to a non-zero value within event handlers to indicate specific types of failures. The Error Handling page details how ResultCode values are translated to specific error codes and responses.
After processing a request in offline mode, the class will populate the Response and ResponseHeaders properties with the content of the response. This data can be extracted from these properties and returned to the client using whatever approach is appropriate.
Error Handling
API Error Codes
The DAVServer class communicates errors to the client in order to provide details about issues encountered while processing the client's request. These error codes are defined on the Error Codes page.
Reporting Errors to the Class from Event Handlers
If an event has a ResultCode parameter, an event handler may use it to return the result code of the operation to the class. The ResultCode parameter is usually set to 0 by default, which indicates the operation was successful.
If an unhandled exception occurs in the event handler, it will be caught by the class, which will fire the Error event.