I guess everybody with a laptop has experienced this problem at some
point: You plug into a network and just want to exchange files with
other participants. It always is a pain until you can exchange
files with the person vis-a-vis.
Of course there are a lot of tools to tackle this problem. For large
scale communities there are dozens of filesharing networks. However,
they don't work for small local networks. Of course you could put your
stuff to exchange on a local web server, but who really wants to
maintain this? Tools like the ingenious
npush/npoll are
extremely helpful, provided that both parties have it installed,
SAFT/sendfile
also aims to solve this problem, but needs a permanently running daemon...
Woof (Web Offer One File) tries a different approach. It
assumes that everybody has a web-browser or a commandline web-client
installed. Woof is a small simple stupid webserver that can
easily be invoked on a single file. Your partner can access the file
with tools he trusts (e.g. wget). No need to enter
passwords on keyboards where you don't know about keyboard sniffers, no
need to start a huge lot of infrastructure, just do a
$ woof filename
and tell the recipient the URL woof spits out. When he got that
file, woof will quit and everything is done.
Abaixo está uma implementação em setenta e poucas linhas de código em Chicken Scheme, usando o servidor web Spiffy.
#! /usr/bin/csi -s
(use posix srfi-13 spiffy)
(define (woof file count ip-addr port)
(when port (server-port port))
(root-path (or (pathname-directory file) (current-directory)))
(let ((current-count 0)
(ip-addresses (and ip-addr (string-split ip-addr ",")))
(file (pathname-strip-directory file)))
(handle-file
(lambda (path)
(if (equal? (pathname-strip-directory path) file)
(if (or (not ip-addr) (member (remote-address) ip-addresses))
(let* ((ext (pathname-extension path))
(handler (alist-ref ext (file-extension-handlers)
string-ci=? send-static-file)))
(set! current-count (add1 current-count))
(print "Serving file " file
" to " (remote-address)
" (count=" current-count ").")
(handler path)
(when (>= current-count count)
(exit 0)))
(begin
(print "Denying access to host " (remote-address) ".")
(send-status 403 "Forbidden")))
(begin
(print "Denying access to file " path ".")
(send-status 403 "Forbidden")))))
(print "Sharing '" file "' with "
(if ip-addresses
(string-intersperse ip-addresses ", ")
"anybody")
".")
(print "URL: http://" (get-host-name) ":" port "/" file)
(start-server)))
(define (usage #!optional exit-code)
(display
(string-append
(pathname-strip-directory (program-name))
" [ --port=<port> ] [ --ip-addr=<ip address> ] [ --count=<count> ] file\n")
(if exit-code (current-error-port) (current-output-port)))
(when exit-code (exit exit-code)))
(define (cl-option-value option args #!optional (converter identity))
(let loop ((args args))
(and (not (null? args))
(let ((arg (car args)))
(if (string-prefix? option arg)
(cond ((string-match (string-append option "=(.*)") arg)
=> (lambda (m)
(converter (cadr m))))
(else (loop (cdr args))))
(loop (cdr args)))))))
(let ((args (command-line-arguments)))
(when (null? args)
(usage 1))
(when (or (member "-h" args) (member "--help" args))
(usage 0))
(let ((count (cl-option-value "--count" args string->number))
(ip-addr (cl-option-value "--ip-addr" args))
(port (cl-option-value "--port" args string->number))
(file (car (reverse args))))
(if (file-exists? file)
(woof file (or count 1) ip-addr port)
(begin
(display (string-append file " does not exist.\n")
(current-error-port))
(exit 1)))))
Nem todas as funcionalidades do woof original estão presentes, mas é possível especificar:
- o arquivo a ser compartilhado
- a porta a ser usada pelo servidor
- o número IP da máquina que poderá pegar o arquivo (pode-se liberar o acesso para mais de uma máquina separando os números IP por vírgula)
- o número de vezes que o arquivo pode ser acessado
Abaixo está a sintaxe para utilização do woof em Chicken na linha de comando:
$ woof --help
woof [ --port=<port> ] [ --ip-addr=<ip address> ] [ --count=<count> ] file
Nenhum comentário:
Postar um comentário