Package: nautilus-dropbox
Version: 1.4.0-3
Severity: normal

Dear Maintainer,

When https_proxy is set, the download of the Dropbox daemon fails
with a KeyError exception, as the returned headers do not contain a
'Content-Length'.  I have attached the output log.

I had a go at patching the python script to fix this.  It seems that
using urllib2.urlopen() instead of urllib.urlopen() is a little more
promising, but I also had to disable non-blocking I/O.  It works alright
for me though.  I have attached this patch, along with some others to
get rid of compilation warnings.

Carlos

-- System Information:
Debian Release: 7.0
  APT prefers unstable
  APT policy: (990, 'unstable'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages nautilus-dropbox depends on:
ii  libatk1.0-0              2.4.0-2
ii  libc6                    2.13-37
ii  libcairo-gobject2        1.12.2-2
ii  libcairo2                1.12.2-2
ii  libgdk-pixbuf2.0-0       2.26.1-1
ii  libglib2.0-0             2.33.12+really2.32.4-3
ii  libgtk-3-0               3.4.2-4
ii  libnautilus-extension1a  3.4.2-1+build1
ii  libpango1.0-0            1.30.0-1
ii  policykit-1              0.105-1
ii  procps                   1:3.3.4-2
ii  python                   2.7.3-3
ii  python-gpgme             0.2-2
ii  python-gtk2              2.24.0-3

nautilus-dropbox recommends no packages.

Versions of packages nautilus-dropbox suggests:
ii  nautilus  3.4.2-1+build1

-- no debconf information
Setting up nautilus-dropbox (1.4.0-3) ...

Dropbox is the easiest way to share and store your files online. Want to learn more? Head to http://www.dropbox.com/

Traceback (most recent call last):
  File "/usr/bin/dropbox", line 1404, in <module>
    ret = main(sys.argv)
  File "/usr/bin/dropbox", line 1393, in main
    result = commands[argv[i]](argv[i+1:])
  File "/usr/bin/dropbox", line 817, in update
    download()
  File "/usr/bin/dropbox", line 540, in download
    download = DownloadState()
  File "/usr/bin/dropbox", line 264, in __init__
    self.size = int(self.socket.info()['content-length'])
  File "/usr/lib/python2.7/rfc822.py", line 388, in __getitem__
    return self.dict[name.lower()]
KeyError: 'content-length'
Please restart all running instances of Nautilus, or you will experience problems. i.e. nautilus --quit
Dropbox installation successfully completed! You can start Dropbox from your applications menu.
>From cc38d9510356a1baff15661154d3ff0a1217edf1 Mon Sep 17 00:00:00 2001
From: Carlos Maddela <madd...@labyrinth.net.au>
Date: Sat, 15 Dec 2012 19:39:21 +1100
Subject: link as needed

Description: Only link with required libraries.
---
 configure.in |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/configure.in b/configure.in
index 581e86c..5d781f6 100644
--- a/configure.in
+++ b/configure.in
@@ -107,6 +107,21 @@ AC_DEFINE_UNQUOTED(NAUTILUS_VERSION_MICRO, [$NAUTILUS_VERSION_MICRO], [ nautilus
 EMBLEM_DIR='${datadir}/nautilus-dropbox/emblems'
 AC_SUBST(EMBLEM_DIR)
 
+# Stolen from vim. Only Link with required libraries.
+AC_MSG_CHECKING(linker --as-needed support)
+LINK_AS_NEEDED=
+# Check if linker supports --as-needed and --no-as-needed options
+if $CC -Wl,--help 2>/dev/null | grep as-needed > /dev/null; then
+    LDFLAGS="$LDFLAGS -Wl,--as-needed"
+    LINK_AS_NEEDED=yes
+fi
+if test "$LINK_AS_NEEDED" = yes; then
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+AC_SUBST(LINK_AS_NEEDED)
+
 AC_CONFIG_FILES([
 	Makefile 
 	src/Makefile
>From 7f62e71352f063b915f19cb07fb212807b217193 Mon Sep 17 00:00:00 2001
From: Carlos Maddela <madd...@labyrinth.net.au>
Date: Sat, 15 Dec 2012 20:29:59 +1100
Subject: remove deprecated glib2.0 calls

Description: Remove deprecated glib2.0 API calls.
---
 src/dropbox-command-client.c |    5 +----
 src/nautilus-dropbox.c       |    7 +------
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/src/dropbox-command-client.c b/src/dropbox-command-client.c
index bdec125..0c3b315 100644
--- a/src/dropbox-command-client.c
+++ b/src/dropbox-command-client.c
@@ -674,12 +674,9 @@ dropbox_command_client_thread(DropboxCommandClient *dcc) {
       DropboxCommand *dc;
 
       while (1) {
-	GTimeVal gtv;
 
-	g_get_current_time(&gtv);
-	g_time_val_add(&gtv, G_USEC_PER_SEC / 10);
 	/* get a request from nautilus */
-	dc = g_async_queue_timed_pop(dcc->command_queue, &gtv);
+	dc = g_async_queue_timeout_pop(dcc->command_queue, G_USEC_PER_SEC / 10);
 	if (dc != NULL) {
 	  break;
 	}
diff --git a/src/nautilus-dropbox.c b/src/nautilus-dropbox.c
index 86a0e8a..ebd34c3 100644
--- a/src/nautilus-dropbox.c
+++ b/src/nautilus-dropbox.c
@@ -682,17 +682,12 @@ nautilus_dropbox_get_file_items(NautilusMenuProvider *provider,
   NautilusDropbox *cvs = NAUTILUS_DROPBOX(provider);
   dropbox_command_client_request(&(cvs->dc.dcc), (DropboxCommand *) dgc);
 
-  GTimeVal gtv;
-
   /*
    * 4. We have to block until it's done because nautilus expects a reply.  But we will
    * only block for 50 ms for a reply.
    */
 
-  g_get_current_time(&gtv);
-  g_time_val_add(&gtv, 50000);
-
-  GHashTable *context_options_response = g_async_queue_timed_pop(reply_queue, &gtv);
+  GHashTable *context_options_response = g_async_queue_timeout_pop(reply_queue, 50000);
   g_async_queue_unref(reply_queue);
 
   if (!context_options_response) {
>From 9261cf3586d400841447f14038476c3f18930ee8 Mon Sep 17 00:00:00 2001
From: Carlos Maddela <madd...@labyrinth.net.au>
Date: Mon, 17 Dec 2012 00:08:17 +1100
Subject: use urllib2

Description: Re-implement using urllib2 instead of urllib, as urllib
seems to fail to follow redirections when https_proxy is set.
---
 dropbox.in |   70 ++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 30 deletions(-)

diff --git a/dropbox.in b/dropbox.in
index 79210f3..32049cd 100755
--- a/dropbox.in
+++ b/dropbox.in
@@ -22,7 +22,6 @@
 from __future__ import with_statement
 
 import errno
-import fcntl
 import locale
 import optparse
 import os
@@ -37,6 +36,7 @@ import tempfile
 import threading
 import time
 import urllib
+import urllib2
 
 try:
     import gpgme
@@ -206,7 +206,7 @@ def download_file_chunk(socket, buf, size):
     with closing(socket) as f:
         while True:
             try:
-                chunk = os.read(f.fileno(), 4096)
+                chunk = f.read(4096)
                 progress += len(chunk)
                 buf.write(chunk)
                 yield (progress, True)
@@ -221,22 +221,25 @@ def download_file_chunk(socket, buf, size):
 
 def download_uri_to_buffer(uri):
     try:
-        socket = urllib.urlopen(uri)
-    except IOError as e:
-        debug_info = get_download_debug_info(uri, e)
-        FatalVisibleError("Trouble connecting to Dropbox servers. Maybe your internet connection is down, or you need to set your http_proxy environment variable.\n%s" % debug_info)
-
-    fcntl.fcntl(socket, fcntl.F_SETFL, os.O_NONBLOCK)
-    size = int(socket.info()['content-length'])
+        socket = urllib2.urlopen(uri)
+        size = int(socket.info()['content-length'])
+        buf = StringIO.StringIO()
+        download_chunk = download_file_chunk(socket, buf, size)
 
-    buf = StringIO.StringIO()
-    download_chunk = download_file_chunk(socket, buf, size)
+        for _ in download_chunk:
+            pass
 
-    for _ in download_chunk:
-        pass
+        buf.seek(0)
+        return buf
+    except IOError as e:
+        debug_info = get_download_debug_info(uri, e)
+        FatalVisibleError("""\
+Trouble connecting to Dropbox servers. Maybe your internet connection is down, \
+or you need to set your http_proxy environment variable.\n%s""" % debug_info)
+    except KeyError:
+        FatalVisibleError("""\
+Could not determine the size of the file to download.\n""")
 
-    buf.seek(0)
-    return buf
 
 def get_download_debug_info(url, e):
     msg = "\nURL that failed to download: %s\nError: %s\n" % (url, e.strerror)
@@ -247,24 +250,31 @@ def get_download_debug_info(url, e):
     return msg
 
 # This sets a custom User-Agent
-class DropboxURLopener(urllib.FancyURLopener):
-    version = "DropboxLinuxDownloader/@PACKAGE_VERSION@"
-urllib._urlopener = DropboxURLopener()
+def reset_url_opener():
+    opener = urllib2.build_opener()
+    opener.addheaders = [("User-agent",
+                          "DropboxLinuxDownloader/@PACKAGE_VERSION@")]
+    urllib2.install_opener(opener)
+
+reset_url_opener()
 
 class DownloadState(object):
     def __init__(self):
         url = "http://www.dropbox.com/download?plat=%s"; % plat()
         try:
-            self.socket = urllib.urlopen(url)
+            self.socket = urllib2.urlopen(url)
+            self.size = int(self.socket.info()['content-length'])
+            self.local_file = StringIO.StringIO()
+            self.download_chunk = \
+                download_file_chunk(self.socket, self.local_file, self.size)
         except IOError as e:
             debug_info = get_download_debug_info(url, e)
-            FatalVisibleError("Trouble connecting to Dropbox servers. Maybe your internet connection is down, or you need to set your http_proxy environment variable.\n%s" % debug_info)
-
-        fcntl.fcntl(self.socket, fcntl.F_SETFL, os.O_NONBLOCK)
-        self.size = int(self.socket.info()['content-length'])
-
-        self.local_file = StringIO.StringIO()
-        self.download_chunk = download_file_chunk(self.socket, self.local_file, self.size)
+            FatalVisibleError("""\
+Trouble connecting to Dropbox servers. Maybe your internet connection is down, \
+or you need to set your http_proxy environment variable.\n%s""" % debug_info)
+        except KeyError:
+            FatalVisibleError("""\
+Could not determine the size of the file to download.\n""")
 
     def copy_data(self):
         return self.download_chunk
@@ -1372,13 +1382,13 @@ def main(argv):
     # option parsing code
     def set_http_proxy(option, opt_str, value, parser):
         os.environ["http_proxy"] = value
-        # Need to reset _urlopener to take the new value into account
-        urllib._urlopener = DropboxURLopener()
+        # Need to reset url opener to take the new value into account
+        reset_url_opener()
 
     def set_https_proxy(option, opt_str, value, parser):
         os.environ["https_proxy"] = value
-        # Need to reset _urlopener to take the new value into account
-        urllib._urlopener = DropboxURLopener()
+        # Need to reset url opener to take the new value into account
+        reset_url_opener()
 
     globaloptionparser = optparse.OptionParser()
     globaloptionparser.add_option("--http-proxy", action="callback",

Reply via email to