]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/tahoe_put.py
command-line: fix ticket #111 by requiring input to be a local file and sending Conte...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / tahoe_put.py
1 #!/usr/bin/env python
2
3 import re, socket, sys
4
5 NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
6
7 def put(nodeurl, vdrive, local_fname, vdrive_fname, verbosity):
8     """
9     @param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
10
11     @return: a Deferred which eventually fires with the exit code
12     """
13     mo = NODEURL_RE.match(nodeurl)
14     host = mo.group(1)
15     port = int(mo.group(3))
16
17     url = "/vdrive/" + vdrive + "/"
18     if vdrive_fname:
19         url += vdrive_fname
20
21     infileobj = open(local_fname, "rb")
22     infileobj.seek(0, 2)
23     infilelen = infileobj.tell()
24     infileobj.seek(0, 0)
25
26     so = socket.socket()
27     so.connect((host, port,))
28
29     CHUNKSIZE=2**16
30     data = "PUT %s HTTP/1.1\r\nConnection: close\r\nContent-Length: %s\r\nHostname: %s\r\n\r\n" % (url, infilelen, host,)
31     while data:
32         try:
33             sent = so.send(data)
34         except Exception, le:
35             print "got socket error: %s" % (le,)
36             return -1
37
38         if sent == len(data):
39             data = infileobj.read(CHUNKSIZE)
40         else:
41             data = data[sent:]
42
43     respbuf = []
44     data = so.recv(CHUNKSIZE)
45     while data:
46         respbuf.append(data)
47         data = so.recv(CHUNKSIZE)
48
49     so.shutdown(socket.SHUT_WR)
50
51     data = so.recv(CHUNKSIZE)
52     while data:
53         respbuf.append(data)
54         data = so.recv(CHUNKSIZE)
55
56     respstr = ''.join(respbuf)
57
58     headerend = respstr.find('\r\n\r\n')
59     if headerend == -1:
60         headerend = len(respstr)
61     header = respstr[:headerend]
62     RESP_RE=re.compile("^HTTP/[0-9]\.[0-9] ([0-9]*) *([A-Za-z_ ]*)")  # This regex is soooo ad hoc...  --Zooko 2007-08-16
63     mo = RESP_RE.match(header)
64     if mo:
65         code = int(mo.group(1))
66         word = mo.group(2)
67
68         if code in (200, 201,):
69             print "%s %s" % (code, word,)
70             return 0
71     
72     print respstr[headerend:]
73     return 1
74
75 def main():
76     import optparse, re
77     parser = optparse.OptionParser()
78     parser.add_option("-d", "--vdrive", dest="vdrive", default="global")
79     parser.add_option("-u", "--node-url", dest="nodeurl")
80
81     (options, args) = parser.parse_args()
82
83     NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
84     if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
85         raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
86     
87     local_file = args[0]
88     vdrive_fname = None
89     if len(args) > 1:
90         vdrive_fname = args[1]
91
92     return put(options.nodeurl, options.vdrive, vdrive_fname, local_file)
93
94 if __name__ == '__main__':
95     main()