Using Apache WebDAV with FileMaker

A common need in integrated business systems utilizing is the ability to place files onto a public server for later consumption by external parties, with the most convenient being having the file accessible via a simple HTTP URL. There are numerous ways this can be accomplished. In this guide I’ll show a fairly simple process using the well established and widely available WebDAV protocol. If you already know a few things about HTTP, like the methods GET and POST, then you will be pleased to learn that WebDAV is simply an extension to the standard HTTP protocol. This extension adds additional methods to help with the manipulation of files and folders on the server. Yes, WebDAV is old news, but it works and is still widely used.
Threeprong Consulting Ad

Why choose WebDAV?

  • You are already maintaining an SSL enabled web server (like Apache/IIS/Nginx)
  • WebDAV is an extremely simple REST API
  • WebDAV is supported by curl
  • WebDAV is supported by Insert From URL throughout the FileMaker platform (no plug-in needed)
  • WebDAV is supported by the MacOS Finder and Windows Explorer
  • Adding a bucket of files to a solution can often be done without adding any new dependancies or points of failure

When to choose other options like AWS S3, Backblaze B2, Vultr Object Stoage, SFTP,  CDN, or other PaaS?

  • You need large scaling or denial of service protections
  • You need more complex access controls or expiring links
  • You don’t already have a web server

It is certainly possible to alter the configuration of FileMaker’s webserver which is deployed when you use any of the web components of FileMaker server. However, this comes with risks, the largest of which in my mind is the likelihood that future platform software updates could munge your configuration.

Let’s get started.

Enable Apache DAV Module

Check to see if you already have the DAV module enabled on your server. We are looking for an indication that the modules dav_module and dav_fs_module are currently installed and enabled.

httpd -M

If you don’t see one of the required modules, then you need to load them. On my system I found the modules files in the folder /usr/local/libexec/apache24/. Depending on your UNIX flavor they might be at /usr/libexec/apache2/ or at /usr/lib64/httpd/modules/. On some UNIX flavors, you might need to install an additional package to get the necessary WebDAV files.

You need to update your apache configuring file to include these lines in the global area:

LoadModule dav_module libexec/apache24/mod_dav.so
LoadModule dav_fs_module libexec/apache24/mod_dav_fs.so

While you are at it, go ahead and configure a suitable location of your choice for keeping a small database of locks. On my system I created a directory for this where I focus my system modifications under /usr/local. The directory needs to be owned and writable by the user which runs Apache, typically the user will be called, www, apache, or httpd.

sudo mkdir -p /usr/local/3prong/apache24/var

sudo chown www:www /usr/local/3prong/apache24/var

sudo chmod 755 /usr/local/3prong/apache24/var

Add the configuration directive to utilize your directory for the locks.

DavLockDB "/usr/local/3prong/apache24/var/DavLock"

Enable DAV on a specific directory of your website

Choose a subfolder within an existing website where you want to enable WebDAV. Every folder under that folder will also have DAV, so you probably do not want to overlap this feature with other resources. Here is an example:

<Directory "/home/some-site-www/public_html/fm-file-area">
        Dav On
        AuthType Basic
        AuthName "Restricted File Area"
        AuthUserFile "/home/some-site-www/webdav.htpwd"
        <LimitExcept GET HEAD OPTIONS>
                Require valid-user
        </LimitExcept>
        RewriteEngine off
</Directory>

This setup presumes that your site is isolated inside a user home directory and that you want to create a new DAV area off the webroot in a folder called fm-file-area. This setup assumes you want the world to be able to fetch these files with no password required, but that users wishing to manipulate the files need to be authorized with a username and password.

mkdir /home/some-site-www/public_html/fm-file-area

sudo chown www /home/some-site-www/public_html/fm-file-area

sudo chmod 755 /home/some-site-www/public_html/fm-file-area

We needed to setup the folder such that the apache process has permission to manipulate files in this directory. (Note this assumes your web author exists as “some-site-www”, and your apache server is executing as the user “www”. Various combinations of permissions might be suitable here. It might be a good idea to create a common group that both users are a member of.)

Next create the authorization file and create a user. This is a new user database, seperate from the server’s operating system, that apache will use for this site. Use a good password here instead of my sample.

htpasswd -b -c /home/some-site-www/webdav.htpwd my_fm_agent_name RaNd0mSeCr3t

Verify your configuration files and notify the apache server of the changes.

sudo apachectl configtest

sudo apachectl graceful

Test your setup – Practice with curl

Back on your client machine, see if the server is advertising WebDAV capabilities for the desired directory. The -i option for curl returns the response headers to the terminal which is handy for testing.

curl -i --request OPTIONS https://www.somesite.dom/fm-file-area/

Compare this to the capabilities advertised for a different directory. You should clearly see a much shorter list of Allows: methods and no mention of DAV.

curl -i --request OPTIONS https://www.somesite.dom/other-dir/

Try making a new folder via WebDAV as a guest, and then again as an authorized user. MKCOL is WebDAV’s command to make a collection, also known as a directory or folder.

curl -i --request MKCOL https://www.somesite.dom/fm-file-area/testing123

Failure should get response code 401 Unauthorized.

curl -i --request MKCOL --user "my_fm_agent_name:RaNd0mSeCr3t" https://www.somesite.dom/fm-file-area/testing123

Success should return response code 201 Created. At this point we can try uploading a file.

curl -i --request PUT --upload-file /Users/chrisi/Documents/test.pdf --user "my_fm_agent_name:RaNd0mSeCr3t" https://www.somesite.dom/fm-file-area/testing123/Test54321.pdf

At this point, anyone can GET the file at this URL. Now cleanup by removing the folder. (Note this recursively deletes the files in the folder as well.)

curl -i --request DELETE --user "my_fm_agent_name:RaNd0mSeCr3t" https://www.somesite.dom/fm-file-area/testing123/

Build some FileMaker calls for Similar Function


Set Variable [ $user ; Value: "my_fm_agent_name" ] Set Variable [ $pass ; Value: "RaNd0mSeCr3t" ] Set Variable [ $base_url ; Value: "https://www.somesite.dom/fm-file-area" ] Set Variable [ $folder_name ; Value: "testing123" ] Set Variable [ $target_url ; $base_url & "/" & $folder_name ] Insert From URL [ $response_body ; $target_url ; cURL options: "--dump-header $response_headers " & "--user \"" & $user & ":" & $pass & "\" " & "--request MKCOL"

If this worked, the folder now exists. Go ahead and upload contents of a container. Notice the final named location of the file should have an extension indicating the type, but doesn’t have to have the same filename as was in the container field.

Set Variable [ $final_file ; Value: "Test54321.pdf" ] Set Variable [ $target_url ; Value: $base_url & "/" & $folder_name & "/" & $final_file ] Set Variable [ $file_blob ; Value: DocumentsTable::File ] Insert From URL [ $response_body ; $target_url ; cURL options: "--dump-header $response_headers " & "--user \"" & $user & ":" & $pass & "\" " & "--upload-file $file_blob " & "--request PUT"

A few things to note here. Sometimes user names and passwords include special characters or spaces. Usually putting quotes into the curl options around the credentials is enough to handle this. Also, most variables have their evaluated values concatenated into the curl options string but –upload-file is special. It doesn’t go fetch contents of the variable until the upload is actually occurring. If you put $file_blob outside of string literal it will not work. This is an unfortunate and potentially confusing side effect when adopting the command line unix curl options into FileMaker.

Another tricky area is the WebDAV behavior when you are trying to make a directory and one already exists. The output may be unexpected and it changes slightly depending on if you include the trailing / at the end of the URL or not. Run some extra tests if this behavior is important to your application.

ALWAYS USE SSL! While WebDAV is supported for insecure http, authentication as configured in this example would be easily intercepted. SSL adds privacy to the body of requests and responses, including credentials and file names.

FileMaker doesn’t have a convenient way read back the HTTP response code, which can make it tricky to do proper error handling when communicating with WebDAV or other APIs. See the attached sample file for a more complete solution that catches most error cases and fully decodes the response code.

Download FileMaker sample file

Download a WebDAV Sample File for FileMaker that we have prepared. It demonstrates basic syncing functionality with more robust calls and error checking.


Bonus: Mount WebDAV with Mac OS Finder

In the Mac OS Finder, pull down Go -> Connect to Server … [command-K]. Then enter the URL where WebDAV is enabled, in the above example it was https://www.somesite.dom/fm-file-area/

"Connect to Server" Dialog

After you provide credentials, you will be able to directly browse and modify the remote filesystem, similar to any other file server.

Mounted WebDAV File System

Additional Resources

Threeprong Consulting Ad