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.