Here is a simple example how to make native WebDAV client with Ruby sockets. No additional gems or extensions needed – just all basic classes.
class WebDAV attr_reader :host, :port, :protocol, :chunk_size @socket = nil def initialize(host,port=80,protocol='HTTP/1.1',chunk=8096) @host = host.to_s @port = port.to_i @protocol = protocol @chunk_size = chunk.to_i end def build_header(method, path, content_length=nil) header = "#{method} #{path} #{@protocol} \r\n" header += "Content-Length: #{content_length}\r\n" if !content_length.nil? header += "Host: #{@host}\r\n" header += "Connection: close\r\n\r\n" return header end def request(method, path) open header = build_header(method, path) if @socket.write(header) == header.length then return @socket.gets.split[1] end end def delete(path) request('DELETE', path) end def head(path) request('HEAD', path) end def mkcol(path) request('MKCOL', path) end def put(path, localfile, auto_head=true) if !File.exists?(localfile) || !File.readable?(localfile) raise "File not exists or not accessible for reading!" end open datalen = File.size(localfile) header = build_header('PUT', path, datalen) begin if @socket.write(header) == header.length then written = 0 File.open(localfile,'r') do |f| until f.eof? do written += @socket.write(f.read(@chunk_size)) end end if written == datalen close if !auto_head return true else return head(path) end end end rescue Exception => e puts e return false end end def open begin @socket = TCPSocket.open(@host,@port) return true rescue Exception => e puts e return false end end def close begin return @socket.close rescue return false end end end
This class supports only basic http/dav methods (PUT, DELETE, MKCOL, HEAD) and can be extended very easily and designed to work with all files, reading them by small chunks (default is 8096 bytes).
Im using this class sometimes with nginx.
Deps:
require 'socket' require 'digest'
Usage:
# create connection conn = WebDAV.new('your.host.com') # upload file (without autocheck), return true/false value result = conn.put('/test.mp3','/home/.../..../..../file.mp3', false) # upload file with autocheck, returns http response code (201, 404, ... ) so you`ll know what exactly happened result = conn.put('/test2.mp3','/home/.../file.mp3')
Also, here is a wrapper class to produce MD5, SHA1 file hashes that supports big files.
class FileHash def self.md5(path) d = Digest::MD5.new File.open(path,'r') do |f| d.update(f.read(8192)) until f.eof? end return d.hexdigest end def self.sha1(path) d = Digest::SHA1.new File.open(path,'r') do |f| d.update(f.read(8192)) until f.eof? end return d.hexdigest end end
Usage:
FileHash.md5('/path/to/file') FileHash.sha1('/path/to/file')
This webdav class not pretending to be stable in production environment, but can be useful for some “one-time” tasks with less code.


[...] Life in Server Box ยป WebDAV client in ruby [...]