diff --git a/cdn.basic.css.inc b/cdn.basic.css.inc
index be7175d..8bba66c 100644
--- a/cdn.basic.css.inc
+++ b/cdn.basic.css.inc
@@ -133,7 +133,7 @@ function _cdn_build_css_cache($css, $suffix = '') {
 }
 
 /**
- * Near-identical to @see drupal_build_css_path().
+ * Near-identical to @see _drupal_build_css_path().
  *
  * Changes: apply file_create_url() to every file!
  */
@@ -145,12 +145,31 @@ function _cdn_build_css_path($matches, $base = NULL) {
   }
 
   // Prefix with base and remove '../' segments where possible.
-  $path = $_base . $matches[1];
+  $url = $_base . $matches[1];
   $last = '';
-  while ($path != $last) {
-    $last = $path;
-    $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
+  while ($url != $last) {
+    $last = $url;
+    $url = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $url);
   }
 
-  return 'url(' . file_create_url($path) . ')';
+  $parsed_url = parse_url($url);
+  $scheme   = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
+  $host     = isset($parsed_url['host']) ? $parsed_url['host'] : '';
+  $port     = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
+  $user     = isset($parsed_url['user']) ? $parsed_url['user'] : '';
+  $pass     = isset($parsed_url['pass']) ? ':' . $parsed_url['pass']  : '';
+  $pass     = ($user !== '' || $pass !== '') ? "$pass@" : '';
+  $path     = isset($parsed_url['path']) ? $parsed_url['path'] : '';
+  $query    = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
+  // In the case of certain URLs, we may have simply a '?' character without
+  // further parameters. parse_url() misses this and leaves 'query' blank, so
+  // need to this back in.
+  // See http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax
+  // for more information.
+  if ($query === '' && strpos($url, $scheme . $user . $pass . $host . $port . $path . '?') === 0) {
+    $query = '?';
+  }
+  $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
+
+  return 'url(' . file_create_url($scheme . $user . $pass . $host . $port . $path) . $query . $fragment . ')';
 }
diff --git a/cdn.info b/cdn.info
index c2eba3b..1844459 100644
--- a/cdn.info
+++ b/cdn.info
@@ -4,4 +4,4 @@ description = "Integrates your site with a CDN, through altering file URLs."
 core = 7.x
 package = Performance and scalability
 configure = admin/config/development/cdn
-files[] = cdn.test
+files[] = tests/cdn.test
diff --git a/cdn.test b/tests/cdn.test
similarity index 91%
rename from cdn.test
rename to tests/cdn.test
index c1b49a2..011f68e 100644
--- a/cdn.test
+++ b/tests/cdn.test
@@ -547,3 +547,58 @@ class CDNImageTestCase extends CDNTestCase {
     $this->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified, even with query strings).');
   }
 }
+
+class CDNCssUrlTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CSS URLs',
+      'description' => 'Verify URLs in CSS files are rewritten properly.',
+      'group' => 'CDN',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+
+    // Pretend the CDN module is enabled; this ensures invocations of its own
+    // hook implementations will work as expected.
+    $cdn_module_file = drupal_get_path('module', 'cdn') . '/cdn.module';
+    $module_list = module_list();
+    $module_list['cdn']['filename'] = $cdn_module_file;
+    module_list(TRUE, FALSE, FALSE, $module_list);
+    $implementations = &drupal_static('module_implements');
+    $implementations = array();
+
+    $this->loadFile('cdn.constants.inc');
+    $this->loadFile('cdn.module');
+    $this->loadFile('cdn.basic.inc');
+    $this->loadFile('cdn.basic.css.inc');
+    $this->loadFile('cdn.basic.farfuture.inc');
+    variable_set(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
+    variable_set(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
+  }
+
+  function loadFile($file) {
+    $cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
+    require_once "$cdn_path/$file";
+  }
+
+  // Makes sure the URL components are preserved.
+  function testCssUrl() {
+    global $base_url;
+    $css_info = array(
+      array(
+        'type' => 'file',
+        'data' => drupal_get_path('module', 'cdn') . '/tests/css/orig/url.css',
+      ),
+    );
+    try {
+      // Make sure the URL in the supplied CSS file matches what we expect.
+      // trim() is needed to avoid issues with differences in newlines.
+      $this->assertEqual(trim(file_get_contents(_cdn_build_css_cache($css_info))), '.home{background:url('. $base_url . '/' . drupal_get_path('module', 'cdn') . '/tests/css/orig/geo-md-webfont.eot?#iefix);}');
+    } catch (Exception $exc) {
+      $this->fail($exc);
+    }
+  }
+
+}
diff --git a/tests/css/orig/url.css b/tests/css/orig/url.css
new file mode 100644
index 0000000..4707af1
--- /dev/null
+++ b/tests/css/orig/url.css
@@ -0,0 +1,3 @@
+.home {
+  background: url('geo-md-webfont.eot?#iefix');
+}
