Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.261
diff -u -p -r1.261 locale.inc
--- includes/locale.inc	26 Oct 2010 15:24:50 -0000	1.261
+++ includes/locale.inc	30 Oct 2010 16:29:42 -0000
@@ -23,6 +23,12 @@ define('LOCALE_LANGUAGE_NEGOTIATION_BROW
 define('LOCALE_LANGUAGE_NEGOTIATION_INTERFACE', 'locale-interface');
 
 /**
+ * The language is determined using the current content language if no URL
+ * language is available.
+ */
+define('LOCALE_LANGUAGE_NEGOTIATION_URL_FALLBACK', 'locale-url-fallback');
+
+/**
  * The language is set based on the user language settings.
  */
 define('LOCALE_LANGUAGE_NEGOTIATION_USER', 'locale-user');
@@ -78,6 +84,29 @@ function locale_language_from_interface(
 }
 
 /**
+ * Identifies the language to be assigned to URLs when none is detected.
+ *
+ * If no URL language can be detcted and the default language is configured to
+ * always provide language information through URLs via prefix or domain, we
+ * need to fall back to the most suitable language, which is an already detected
+ * language.
+ *
+ * @param $languages
+ *   Optional. An array of valid language objects. Defaults to NULL.
+ * @param $language_type
+ *   Optional. The language type to fall back to. Defaults to the interface
+ *   language.
+ *
+ * @return
+ *   A valid language code on success, FALSE otherwise.
+ */
+function locale_language_from_url_fallback($language = NULL, $language_type = LANGUAGE_TYPE_INTERFACE) {
+  $default = language_default();
+  $prefix = variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX) == LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX;
+  return ($prefix && empty($default->prefix)) || (!$prefix && empty($default->domain)) ? FALSE : $GLOBALS[$language_type]->language;
+}
+
+/**
  * Identify language from the Accept-language HTTP header we got.
  *
  * We perform browser accept-language parsing only if page cache is disabled,
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.304
diff -u -p -r1.304 locale.module
--- modules/locale/locale.module	25 Oct 2010 15:14:33 -0000	1.304
+++ modules/locale/locale.module	30 Oct 2010 16:07:44 -0000
@@ -503,8 +503,8 @@ function locale_entity_info_alter(&$enti
  *   language negotiated value. It is used by the Field API to determine the
  *   display language for fields if no explicit value is specified.
  * - URL language is by default non-configurable and is determined through the
- *   URL language provider. It is used by l() as the default language if none is
- *   specified.
+ *   URL language provider or the URL fallback provider if no language could be
+ *   detected. It is used by l() as the default language if none is specified.
  */
 function locale_language_types_info() {
   require_once DRUPAL_ROOT . '/includes/locale.inc';
@@ -517,7 +517,7 @@ function locale_language_types_info() {
       'fixed' => array(LOCALE_LANGUAGE_NEGOTIATION_INTERFACE),
     ),
     LANGUAGE_TYPE_URL => array(
-      'fixed' => array(LOCALE_LANGUAGE_NEGOTIATION_URL),
+      'fixed' => array(LOCALE_LANGUAGE_NEGOTIATION_URL, LOCALE_LANGUAGE_NEGOTIATION_URL_FALLBACK),
     ),
   );
 }
@@ -582,6 +582,15 @@ function locale_language_negotiation_inf
     'description' => t('Use the detected interface language.'),
   );
 
+  $providers[LOCALE_LANGUAGE_NEGOTIATION_URL_FALLBACK] = array(
+    'types' => array(LANGUAGE_TYPE_URL),
+    'callbacks' => array('language' => 'locale_language_from_url_fallback'),
+    'file' => $file,
+    'weight' => 8,
+    'name' => t('URL Fallback'),
+    'description' => t('Return a suitable language for URLs if none is detected.'),
+  );
+
   return $providers;
 }
 
