commit a30d3a02a852d82b442a218c526a0a1fdfe2c861
Author: John Hensley <john@fairviewcomputing.com>
Date:   Tue Jun 28 11:03:35 2011 -0400

    Support HTTPS in sitemaps.

diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 98ab353..5161da1 100644
--- a/django/contrib/sitemaps/__init__.py
+++ b/django/contrib/sitemaps/__init__.py
@@ -39,6 +39,7 @@ class Sitemap(object):
     # This limit is defined by Google. See the index documentation at
     # http://sitemaps.org/protocol.php#index.
     limit = 50000
+    protocol = 'http'
 
     def __get(self, name, obj, default=None):
         try:
@@ -73,7 +74,7 @@ class Sitemap(object):
 
         urls = []
         for item in self.paginator.page(page).object_list:
-            loc = "http://%s%s" % (site.domain, self.__get('location', item))
+            loc = "%s://%s%s" % (self.protocol, site.domain, self.__get('location', item))
             priority = self.__get('priority', item, None)
             url_info = {
                 'item':       item,
diff --git a/django/contrib/sitemaps/tests/__init__.py b/django/contrib/sitemaps/tests/__init__.py
index c5b483c..be28c8f 100644
--- a/django/contrib/sitemaps/tests/__init__.py
+++ b/django/contrib/sitemaps/tests/__init__.py
@@ -1 +1,2 @@
 from django.contrib.sitemaps.tests.basic import *
+from django.contrib.sitemaps.tests.https import *
diff --git a/django/contrib/sitemaps/tests/https.py b/django/contrib/sitemaps/tests/https.py
new file mode 100644
index 0000000..4646215
--- /dev/null
+++ b/django/contrib/sitemaps/tests/https.py
@@ -0,0 +1,184 @@
+import os
+from datetime import date
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.contrib.sitemaps import Sitemap, GenericSitemap
+from django.contrib.sites.models import Site
+from django.core.exceptions import ImproperlyConfigured
+from django.test import TestCase
+from django.utils.unittest import skipUnless
+from django.utils.formats import localize
+from django.utils.translation import activate, deactivate
+
+
+class HTTPSSitemapTests(TestCase):
+    urls = 'django.contrib.sitemaps.tests.urls_https'
+
+    def setUp(self):
+        if Site._meta.installed:
+            self.base_url = 'https://example.com'
+        else:
+            self.base_url = 'https://testserver'
+        self.old_USE_L10N = settings.USE_L10N
+        self.old_Site_meta_installed = Site._meta.installed
+        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
+        self.old_Site_meta_installed = Site._meta.installed
+        settings.TEMPLATE_DIRS = (
+            os.path.join(os.path.dirname(__file__), 'templates'),
+        )
+        # Create a user that will double as sitemap content
+        User.objects.create_user('testuser', 'test@example.com', 's3krit')
+
+    def tearDown(self):
+        settings.USE_L10N = self.old_USE_L10N
+        Site._meta.installed = self.old_Site_meta_installed
+        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
+        Site._meta.installed = self.old_Site_meta_installed
+
+    def test_simple_sitemap_index(self):
+        "A simple sitemap index can be rendered"
+        # Retrieve the sitemap.
+        response = self.client.get('/simple/index.xml')
+        # Check for all the important bits:
+        self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
+<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
+</sitemapindex>
+""" % self.base_url)
+
+    def test_simple_sitemap_custom_index(self):
+        "A simple sitemap index can be rendered with a custom template"
+        # Retrieve the sitemap.
+        response = self.client.get('/simple/custom-index.xml')
+        # Check for all the important bits:
+        self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
+<!-- This is a customised template -->
+<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
+</sitemapindex>
+""" % self.base_url)
+
+    def test_simple_sitemap(self):
+        "A simple sitemap can be rendered"
+        # Retrieve the sitemap.
+        response = self.client.get('/simple/sitemap.xml')
+        # Check for all the important bits:
+        self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
+</urlset>
+""" % (self.base_url, date.today().strftime('%Y-%m-%d')))
+
+    def test_simple_custom_sitemap(self):
+        "A simple sitemap can be rendered with a custom template"
+        # Retrieve the sitemap.
+        response = self.client.get('/simple/custom-sitemap.xml')
+        # Check for all the important bits:
+        self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
+<!-- This is a customised template -->
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
+</urlset>
+""" % (self.base_url, date.today().strftime('%Y-%m-%d')))
+
+    @skipUnless(settings.USE_I18N, "Internationalization is not enabled")
+    def test_localized_priority(self):
+        "The priority value should not be localized (Refs #14164)"
+        # Localization should be active
+        settings.USE_L10N = True
+        activate('fr')
+        self.assertEqual(u'0,3', localize(0.3))
+
+        # Retrieve the sitemap. Check that priorities
+        # haven't been rendered in localized format
+        response = self.client.get('/simple/sitemap.xml')
+        self.assertContains(response, '<priority>0.5</priority>')
+        self.assertContains(response, '<lastmod>%s</lastmod>' % date.today().strftime('%Y-%m-%d'))
+        deactivate()
+
+    def test_generic_sitemap(self):
+        "A minimal generic sitemap can be rendered"
+        # Retrieve the sitemap.
+        response = self.client.get('/generic/sitemap.xml')
+
+        expected = ''
+        for username in User.objects.values_list("username", flat=True):
+            expected += "<url><loc>%s/users/%s/</loc></url>" % (self.base_url, username)
+        # Check for all the important bits:
+        self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+%s
+</urlset>
+""" % expected)
+
+    @skipUnless("django.contrib.flatpages" in settings.INSTALLED_APPS, "django.contrib.flatpages app not installed.")
+    def test_flatpage_sitemap(self):
+        "Basic FlatPage sitemap test"
+
+        # Import FlatPage inside the test so that when django.contrib.flatpages
+        # is not installed we don't get problems trying to delete Site
+        # objects (FlatPage has an M2M to Site, Site.delete() tries to
+        # delete related objects, but the M2M table doesn't exist.
+        from django.contrib.flatpages.models import FlatPage
+
+        public = FlatPage.objects.create(
+            url=u'/public/',
+            title=u'Public Page',
+            enable_comments=True,
+            registration_required=False,
+        )
+        public.sites.add(settings.SITE_ID)
+        private = FlatPage.objects.create(
+            url=u'/private/',
+            title=u'Private Page',
+            enable_comments=True,
+            registration_required=True
+        )
+        private.sites.add(settings.SITE_ID)
+        response = self.client.get('/flatpages/sitemap.xml')
+        # Public flatpage should be in the sitemap
+        self.assertContains(response, '<loc>%s%s</loc>' % (self.base_url, public.url))
+        # Private flatpage should not be in the sitemap
+        self.assertNotContains(response, '<loc>%s%s</loc>' % (self.base_url, private.url))
+
+    def test_requestsite_sitemap(self):
+        # Make sure hitting the flatpages sitemap without the sites framework
+        # installed doesn't raise an exception
+        Site._meta.installed = False
+        # Retrieve the sitemap.
+        response = self.client.get('/simple/sitemap.xml')
+        # Check for all the important bits:
+        self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<url><loc>https://testserver/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
+</urlset>
+""" % date.today().strftime('%Y-%m-%d'))
+
+    @skipUnless("django.contrib.sites" in settings.INSTALLED_APPS, "django.contrib.sites app not installed.")
+    def test_sitemap_get_urls_no_site_1(self):
+        """
+        Check we get ImproperlyConfigured if we don't pass a site object to
+        Sitemap.get_urls and no Site objects exist
+        """
+        Site.objects.all().delete()
+        self.assertRaises(ImproperlyConfigured, Sitemap().get_urls)
+
+    def test_sitemap_get_urls_no_site_2(self):
+        """
+        Check we get ImproperlyConfigured when we don't pass a site object to
+        Sitemap.get_urls if Site objects exists, but the sites framework is not
+        actually installed.
+        """
+        Site._meta.installed = False
+        self.assertRaises(ImproperlyConfigured, Sitemap().get_urls)
+
+    def test_sitemap_item(self):
+        """
+        Check to make sure that the raw item is included with each
+        Sitemap.get_url() url result.
+        """
+        user_sitemap = GenericSitemap({'queryset': User.objects.all()})
+        def is_user(url):
+            return isinstance(url['item'], User)
+        item_in_url_info = all(map(is_user, user_sitemap.get_urls()))
+        self.assertTrue(item_in_url_info)
diff --git a/django/contrib/sitemaps/tests/urls_https.py b/django/contrib/sitemaps/tests/urls_https.py
new file mode 100644
index 0000000..7ff0a1d
--- /dev/null
+++ b/django/contrib/sitemaps/tests/urls_https.py
@@ -0,0 +1,44 @@
+from datetime import datetime
+from django.conf.urls.defaults import *
+from django.contrib.sitemaps import Sitemap, GenericSitemap, FlatPageSitemap
+from django.contrib.auth.models import User
+
+class HTTPSSimpleSitemap(Sitemap):
+    changefreq = "never"
+    priority = 0.5
+    location = '/location/'
+    lastmod = datetime.now()
+    protocol = 'https'
+
+    def items(self):
+        return [object()]
+
+class HTTPSGenericSitemap(GenericSitemap):
+    protocol = 'https'
+
+class HTTPSFlatPageSitemap(FlatPageSitemap):
+    protocol = 'https'
+
+simple_sitemaps = {
+    'simple': HTTPSSimpleSitemap,
+}
+
+generic_sitemaps = {
+    'generic': HTTPSGenericSitemap({
+        'queryset': User.objects.all()
+    }),
+}
+
+flatpage_sitemaps = {
+    'flatpages': HTTPSFlatPageSitemap,
+}
+
+urlpatterns = patterns('django.contrib.sitemaps.views',
+    (r'^simple/index\.xml$', 'index', {'sitemaps': simple_sitemaps}),
+    (r'^simple/custom-index\.xml$', 'index', {'sitemaps': simple_sitemaps, 'template_name': 'custom_sitemap_index.xml'}),
+    (r'^simple/sitemap-(?P<section>.+)\.xml$', 'sitemap', {'sitemaps': simple_sitemaps}),
+    (r'^simple/sitemap\.xml$', 'sitemap', {'sitemaps': simple_sitemaps}),
+    (r'^simple/custom-sitemap\.xml$', 'sitemap', {'sitemaps': simple_sitemaps, 'template_name': 'custom_sitemap.xml'}),
+    (r'^generic/sitemap\.xml$', 'sitemap', {'sitemaps': generic_sitemaps}),
+    (r'^flatpages/sitemap\.xml$', 'sitemap', {'sitemaps': flatpage_sitemaps}),
+)
diff --git a/django/contrib/sitemaps/views.py b/django/contrib/sitemaps/views.py
index b117b33..7dcb303 100644
--- a/django/contrib/sitemaps/views.py
+++ b/django/contrib/sitemaps/views.py
@@ -10,7 +10,6 @@ def index(request, sitemaps,
         template_name='sitemap_index.xml', mimetype='application/xml'):
     current_site = get_current_site(request)
     sites = []
-    protocol = request.is_secure() and 'https' or 'http'
     for section, site in sitemaps.items():
         site.request = request
         if callable(site):
@@ -18,10 +17,10 @@ def index(request, sitemaps,
         else:
             pages = site.paginator.num_pages
         sitemap_url = urlresolvers.reverse('django.contrib.sitemaps.views.sitemap', kwargs={'section': section})
-        sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url))
+        sites.append('%s://%s%s' % (site.protocol, current_site.domain, sitemap_url))
         if pages > 1:
             for page in range(2, pages+1):
-                sites.append('%s://%s%s?p=%s' % (protocol, current_site.domain, sitemap_url, page))
+                sites.append('%s://%s%s?p=%s' % (site.protocol, current_site.domain, sitemap_url, page))
     return TemplateResponse(request, template_name, {'sitemaps': sites}, mimetype=mimetype)
 
 def sitemap(request, sitemaps, section=None,
@@ -44,4 +43,4 @@ def sitemap(request, sitemaps, section=None,
             raise Http404("Page %s empty" % page)
         except PageNotAnInteger:
             raise Http404("No page '%s'" % page)
-    return TemplateResponse(request, template_name, {'urlset': urls}, mimetype=mimetype)
\ No newline at end of file
+    return TemplateResponse(request, template_name, {'urlset': urls}, mimetype=mimetype)
