]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blobdiff - src/allmydata/scripts/common_http.py
When the CLI cannot connect to the gateway, it prints an error message rather than...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / common_http.py
index fbeaa5978158387f262e30c1dd44208f909fe33d..7ffa41bddba37eb307eb3cf43ae6cb060d197cfa 100644 (file)
@@ -1,7 +1,12 @@
 
+import os
 from cStringIO import StringIO
 import urlparse, httplib
-import allmydata # for __version__
+import allmydata # for __full_version__
+
+from allmydata.util.encodingutil import quote_output
+from allmydata.scripts.common import TahoeError
+from socket import error as socket_error
 
 # copied from twisted/web/client.py
 def parse_url(url, defaultPort=None):
@@ -27,8 +32,11 @@ def do_http(method, url, body=""):
     if isinstance(body, str):
         body = StringIO(body)
     elif isinstance(body, unicode):
-        raise RuntimeError("do_http body must be a bytestring, not unicode")
+        raise TypeError("do_http body must be a bytestring, not unicode")
     else:
+        # We must give a Content-Length header to twisted.web, otherwise it
+        # seems to get a zero-length file. I suspect that "chunked-encoding"
+        # may fix this.
         assert body.tell
         assert body.seek
         assert body.read
@@ -41,16 +49,25 @@ def do_http(method, url, body=""):
         raise ValueError("unknown scheme '%s', need http or https" % scheme)
     c.putrequest(method, path)
     c.putheader("Hostname", host)
-    c.putheader("User-Agent", "tahoe_cli/%s" % allmydata.__version__)
+    c.putheader("User-Agent", allmydata.__full_version__ + " (tahoe-client)")
+    c.putheader("Accept", "text/plain, application/octet-stream")
     c.putheader("Connection", "close")
 
     old = body.tell()
-    body.seek(0, 2)
+    body.seek(0, os.SEEK_END)
     length = body.tell()
     body.seek(old)
     c.putheader("Content-Length", str(length))
-    c.endheaders()
 
+    try:
+        c.endheaders()
+    except socket_error, err:
+        class BadResponse(object):
+            status=-1
+            reason="Error trying to connect to %s: %s" % (url, err)
+            read=lambda _: ""
+        return BadResponse()
+        
     while True:
         data = body.read(8192)
         if not data:
@@ -58,3 +75,21 @@ def do_http(method, url, body=""):
         c.send(data)
 
     return c.getresponse()
+
+
+def format_http_success(resp):
+    return "%s %s" % (resp.status, quote_output(resp.reason, quotemarks=False))
+
+def format_http_error(msg, resp):
+    return "%s: %s %s\n%s" % (msg, resp.status, quote_output(resp.reason, quotemarks=False),
+                              quote_output(resp.read(), quotemarks=False))
+
+def check_http_error(resp, stderr):
+    if resp.status < 200 or resp.status >= 300:
+        print >>stderr, format_http_error("Error during HTTP request", resp)
+        return 1
+
+
+class HTTPError(TahoeError):
+    def __init__(self, msg, resp):
+        TahoeError.__init__(self, format_http_error(msg, resp))