diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index 791382b..07484ef 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -73,6 +73,106 @@ class BaseHandler(object):
         # as a flag for initialization being complete.
         self._request_middleware = request_middleware
 
+    def _get_response(self, request, urlconf, resolver, url_patterns=None):
+        "Returns an HttpResponse object for the given HttpRequest"
+        from django.core import exceptions, urlresolvers
+        from django.conf import settings
+
+        try:
+            response = None
+            # Apply request middleware
+            for middleware_method in self._request_middleware:
+                response = middleware_method(request)
+                if response:
+                    break
+
+            if response is None:
+                if hasattr(request, "urlconf"):
+                    # Reset url resolver with a custom urlconf.
+                    urlconf = request.urlconf
+                    urlresolvers.set_urlconf(urlconf)
+                    resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
+
+                callback, callback_args, callback_kwargs = resolver.resolve(
+                        request.path_info, url_patterns=url_patterns)
+
+                # Apply view middleware
+                for middleware_method in self._view_middleware:
+                    response = middleware_method(request, callback, callback_args, callback_kwargs)
+                    if response:
+                        break
+
+            if response is None:
+                try:
+                    response = callback(request, *callback_args, **callback_kwargs)
+                except urlresolvers.DoesNotResolve, e:
+                    return self._get_response(request, urlconf, resolver, url_patterns=url_patterns)
+                except Exception as e:
+                    # If the view raised an exception, run it through exception
+                    # middleware, and if the exception middleware returns a
+                    # response, use that. Otherwise, reraise the exception.
+                    for middleware_method in self._exception_middleware:
+                        response = middleware_method(request, e)
+                        if response:
+                            break
+                    if response is None:
+                        raise
+
+            # Complain if the view returned None (a common error).
+            if response is None:
+                if isinstance(callback, types.FunctionType):    # FBV
+                    view_name = callback.__name__
+                else:                                           # CBV
+                    view_name = callback.__class__.__name__ + '.__call__'
+                raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name))
+
+            # If the response supports deferred rendering, apply template
+            # response middleware and the render the response
+            if hasattr(response, 'render') and callable(response.render):
+                for middleware_method in self._template_response_middleware:
+                    response = middleware_method(request, response)
+                response = response.render()
+
+        except http.Http404 as e:
+            logger.warning('Not Found: %s', request.path,
+                        extra={
+                            'status_code': 404,
+                            'request': request
+                        })
+            if settings.DEBUG:
+                from django.views import debug
+                response = debug.technical_404_response(request, e)
+            else:
+                try:
+                    callback, param_dict = resolver.resolve404()
+                    response = callback(request, **param_dict)
+                except:
+                    signals.got_request_exception.send(sender=self.__class__, request=request)
+                    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
+        except exceptions.PermissionDenied:
+            logger.warning(
+                'Forbidden (Permission denied): %s', request.path,
+                extra={
+                    'status_code': 403,
+                    'request': request
+                })
+            try:
+                callback, param_dict = resolver.resolve403()
+                response = callback(request, **param_dict)
+            except:
+                signals.got_request_exception.send(
+                        sender=self.__class__, request=request)
+                response = self.handle_uncaught_exception(request,
+                        resolver, sys.exc_info())
+        except SystemExit:
+            # Allow sys.exit() to actually exit. See tickets #1023 and #4701
+            raise
+        except: # Handle everything else, including SuspiciousOperation, etc.
+            # Get the exception info now, in case another exception is thrown later.
+            signals.got_request_exception.send(sender=self.__class__, request=request)
+            response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
+        return response
+
     def get_response(self, request):
         "Returns an HttpResponse object for the given HttpRequest"
         from django.core import exceptions, urlresolvers
@@ -86,97 +186,9 @@ class BaseHandler(object):
             urlconf = settings.ROOT_URLCONF
             urlresolvers.set_urlconf(urlconf)
             resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
-            try:
-                response = None
-                # Apply request middleware
-                for middleware_method in self._request_middleware:
-                    response = middleware_method(request)
-                    if response:
-                        break
-
-                if response is None:
-                    if hasattr(request, "urlconf"):
-                        # Reset url resolver with a custom urlconf.
-                        urlconf = request.urlconf
-                        urlresolvers.set_urlconf(urlconf)
-                        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
+            url_patterns = (pattern for pattern in resolver.url_patterns)
+            response = self._get_response(request, urlconf, resolver, url_patterns)
 
-                    callback, callback_args, callback_kwargs = resolver.resolve(
-                            request.path_info)
-
-                    # Apply view middleware
-                    for middleware_method in self._view_middleware:
-                        response = middleware_method(request, callback, callback_args, callback_kwargs)
-                        if response:
-                            break
-
-                if response is None:
-                    try:
-                        response = callback(request, *callback_args, **callback_kwargs)
-                    except Exception as e:
-                        # If the view raised an exception, run it through exception
-                        # middleware, and if the exception middleware returns a
-                        # response, use that. Otherwise, reraise the exception.
-                        for middleware_method in self._exception_middleware:
-                            response = middleware_method(request, e)
-                            if response:
-                                break
-                        if response is None:
-                            raise
-
-                # Complain if the view returned None (a common error).
-                if response is None:
-                    if isinstance(callback, types.FunctionType):    # FBV
-                        view_name = callback.__name__
-                    else:                                           # CBV
-                        view_name = callback.__class__.__name__ + '.__call__'
-                    raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name))
-
-                # If the response supports deferred rendering, apply template
-                # response middleware and the render the response
-                if hasattr(response, 'render') and callable(response.render):
-                    for middleware_method in self._template_response_middleware:
-                        response = middleware_method(request, response)
-                    response = response.render()
-
-            except http.Http404 as e:
-                logger.warning('Not Found: %s', request.path,
-                            extra={
-                                'status_code': 404,
-                                'request': request
-                            })
-                if settings.DEBUG:
-                    from django.views import debug
-                    response = debug.technical_404_response(request, e)
-                else:
-                    try:
-                        callback, param_dict = resolver.resolve404()
-                        response = callback(request, **param_dict)
-                    except:
-                        signals.got_request_exception.send(sender=self.__class__, request=request)
-                        response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
-            except exceptions.PermissionDenied:
-                logger.warning(
-                    'Forbidden (Permission denied): %s', request.path,
-                    extra={
-                        'status_code': 403,
-                        'request': request
-                    })
-                try:
-                    callback, param_dict = resolver.resolve403()
-                    response = callback(request, **param_dict)
-                except:
-                    signals.got_request_exception.send(
-                            sender=self.__class__, request=request)
-                    response = self.handle_uncaught_exception(request,
-                            resolver, sys.exc_info())
-            except SystemExit:
-                # Allow sys.exit() to actually exit. See tickets #1023 and #4701
-                raise
-            except: # Handle everything else, including SuspiciousOperation, etc.
-                # Get the exception info now, in case another exception is thrown later.
-                signals.got_request_exception.send(sender=self.__class__, request=request)
-                response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
         finally:
             # Reset URLconf for this thread on the way out for complete
             # isolation of request.urlconf
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index af3df83..f697eab 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -73,6 +73,9 @@ class ResolverMatch(object):
 class Resolver404(Http404):
     pass
 
+class DoesNotResolve(Http404):
+    pass
+
 class NoReverseMatch(Exception):
     # Don't make this raise an error when used in a template.
     silent_variable_failure = True
@@ -310,12 +313,16 @@ class RegexURLResolver(LocaleRegexProvider):
             self._populate()
         return self._app_dict[language_code]
 
-    def resolve(self, path):
+    def resolve(self, path, url_patterns=None):
         tried = []
         match = self.regex.search(path)
         if match:
             new_path = path[match.end():]
-            for pattern in self.url_patterns:
+            
+            if url_patterns == None:
+                url_patterns = self.url_patterns
+
+            for pattern in url_patterns:
                 try:
                     sub_match = pattern.resolve(new_path)
                 except Resolver404 as e:
diff --git a/tests/regressiontests/views/generic_urls.py b/tests/regressiontests/views/generic_urls.py
index 0f214d1..b163287 100644
--- a/tests/regressiontests/views/generic_urls.py
+++ b/tests/regressiontests/views/generic_urls.py
@@ -54,4 +54,8 @@ urlpatterns += patterns('regressiontests.views.views',
     (r'^shortcuts/render/status/$', 'render_view_with_status'),
     (r'^shortcuts/render/current_app/$', 'render_view_with_current_app'),
     (r'^shortcuts/render/current_app_conflict/$', 'render_view_with_current_app_conflict'),
+    url(r'^overlapping_view/(?P<title>[a-z]+)/$', 'overlapping_view1', name='overlapping_view1'),
+    url(r'^overlapping_view/(?P<author>[a-z]+)/$', 'overlapping_view2', name='overlapping_view2'),
+    url(r'^overlapping_view/(?P<keywords>[a-z]+)/$', 'overlapping_view3', name='overlapping_view3'),
+    url(r'^no_overlapping_view/(?P<keywords>[a-z]+)/$', 'no_overlapping_view', name='no_overlapping_view'),
 )
diff --git a/tests/regressiontests/views/tests/specials.py b/tests/regressiontests/views/tests/specials.py
index 7d65284..d0fbbe9 100644
--- a/tests/regressiontests/views/tests/specials.py
+++ b/tests/regressiontests/views/tests/specials.py
@@ -2,6 +2,7 @@
 from __future__ import unicode_literals
 
 from django.test import TestCase
+from django.core import urlresolvers
 
 
 class URLHandling(TestCase):
@@ -37,3 +38,17 @@ class URLHandling(TestCase):
         response = self.client.get('/permanent_nonascii_redirect/')
         self.assertRedirects(response, self.redirect_target, status_code=301)
 
+    def test_overlapping_urls_reverse(self):
+        url = urlresolvers.reverse('overlapping_view1', kwargs={'title':'sometitle'})
+        self.assertEqual(url, '/overlapping_view/sometitle/')
+        url = urlresolvers.reverse('overlapping_view2', kwargs={'author':'someauthor'})
+        self.assertEqual(url, '/overlapping_view/someauthor/')
+
+    def test_overlapping_urls_resolve(self):
+        response = self.client.get('/overlapping_view/sometitle/')
+        self.assertContains(response, 'overlapping_view2')
+
+    def test_overlapping_urls_not_resolve(self):
+        response = self.client.get('/no_overlapping_view/sometitle/')
+        self.assertEqual(response.status_code, 404)
+
diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
index 2836d1b..8bc0688 100644
--- a/tests/regressiontests/views/views.py
+++ b/tests/regressiontests/views/views.py
@@ -11,6 +11,7 @@ from django.views.debug import technical_500_response, SafeExceptionReporterFilt
 from django.views.decorators.debug import (sensitive_post_parameters,
                                            sensitive_variables)
 from django.utils.log import getLogger
+from django.core import urlresolvers
 
 from . import BrokenException, except_args
 
@@ -227,4 +228,16 @@ class Klass(object):
             return technical_500_response(request, *exc_info)
 
 def sensitive_method_view(request):
-    return Klass().method(request)
\ No newline at end of file
+    return Klass().method(request)
+
+def overlapping_view1(request, title=None):
+    raise urlresolvers.DoesNotResolve
+
+def overlapping_view2(request, author=None):
+    return HttpResponse("overlapping_view2")
+
+def overlapping_view3(request, keywords=None):
+    return HttpResponse("overlapping_view3")
+
+def no_overlapping_view(request, keywords=None):
+    raise urlresolvers.DoesNotResolve
