Saturday, March 15, 2008

How to create a WebDAV interface in 10 easy steps


Test Driven Development (TDD) is all the rage these days. And rightly so, if you ask me. Compare developing software against constantly changing client requirements and developing against a specification in the form of tests that your code must pass. I've done my share of the former for the better part of the last 9 years and I've got the gray hair to prove it. However, I only got a chance to practice the latter very recently and I must say I'm hooked.

My TDD endeavor concerns a small project to add a WebDAV interface to an existing server-side code base. The system already featured other interfaces for manipulating the resources stored in it, but a cross-platform, standards-based, nicely integrated, native client was deemed necessary. Enter WebDAV, a.k.a. HTTP on steroids. Most desktop systems nowadays have a WebDAV client installed by default (Windows calls it Web Folders, others prefer not to rename it), so testing a WebDAV server is not that complicated: if you can mount, browse, store and retrieve files and folders using your desktop client, the server implementation is fine. Nevertheless, we can do better than that. Using litmus, a "WebDAV server protocol compliance suite", we can make sure that our implementation respects the protocol, even in its more obscure corner cases and more importantly, perform the testing automatically, without painstaking clickety-click.

Implementing a WebDAV interface from scratch by reading the protocol specification is not the easiest nor the smartest path. You will have to read it in order to figure out what goes where, but you could also reuse some parts from an existing implementation. If you are extending an existing Java codebase, like me, your best bet is reusing the Tomcat implementation. You can run the litmus suite against a vanilla Tomcat installation, just to verify its WebDAV functionality. Not all tests pass, since the implementation is incomplete, but don't worry, most clients don't implement the spec completely either. However take a note of the results, since this is your target outcome.

For your own convenience, I have described the whole development process in 10 easy steps, ready to print, free of charge, batteries not included:

  1. Download the litmus test suite.
  2. Download the sources for Tomcat, particularly WebdavServlet.java and DefaultServlet.java.
  3. Create your own version of WebdavServlet that will delegate the actual functionality to your own backend and fill it with empty stub methods that correspond to the ones in Tomcat.
  4. Build & deploy your server.
  5. Run the litmus test. All tests fail the first time, but when it eventually succeeds (i.e. matches the result of vanilla tomcat), go to step 9.
  6. Fill one method at a time from Tomcat's sources, substituting the JNDI communications with your backend logic.
  7. Add any other helper methods from other Tomcat classes as necessary.
  8. Go to step 4.
  9. Most tests succeeded, so you are done!
  10. For extra credit: fix the code to pass some more tests and send your changes upstream.
You are bound to come across some hair-splitting problems when modifying the codebase to fit in you own backend, but it beats writing it all from scratch hands down, unless you are Greg Stein or Jim Whitehead. In my case, after two weeks and a submitted patch, I was done and had the tests to prove it. Furthermore, when the need for a code refactoring arises, I can rest assured that my changes won't break the protocol functionality if the litmus tests still pass. Not to mention that I have now contributed to Tomcat.

Man, I haven't felt that good in ages.

8 comments:

Anonymous said...

Hi,

I'm a student boy of Spain. I would like to create a webdav and I found your blog.
First, I don't find "litmus test". Could you say me how to find it?
Second, I understand that my servlet inherit of WebdavServlet isn't?

My e-mail is davidbadiola@hotmail.com.

I would like to meet you.

Thanks.

past said...

Hi, if you look closer, you will see that the word 'litmus' in the post is a link to the website where you can download the suite. Regarding the actual implementation, extending WebdavServlet might work for you, but what I actually advocate is to reimplement WebdavServlet using the existing code as a starting point. WebdavServlet was not designed with reusability in mind, plus I actually found it necessary to reimplement parts of its ancestor, too.

Stephan Westen said...

I was planning to do the same as you have described. Can you share your webdav implementation classes? I realize that there is a dependency on your own system, but it might save me some time.

thanks,

Stephan

past said...

The project that contains this code is about to be open-sourced anyway, so I'll update the post when it's available. It should be done by next month, as far as I know.

Unknown said...

You can also take a look at Milton (http://milton.ettrema.com/index.html)

Anonymous said...
This comment has been removed by a blog administrator.
Unknown said...

You mentioned in November 2008 that the code was about to be open-sourced. Was it ever open-sourced? I don't see a link. Thanks in advance!

past said...

I've apparently forgotten to post the link to the GSS WebDAV implementation, but you can find it here.

Creative Commons License Unless otherwise expressly stated, all original material in this weblog is licensed under a Creative Commons Attribution 3.0 License.