[{"data":1,"prerenderedAt":9871},["ShallowReactive",2],{"navigation":3,"/security/https-setup-and-hsts":1016,"/security/https-setup-and-hsts-surround":9866},[4,54,89,123,165,211,253,331,389,439,462,488,514,540,578,624,650,672,702,736,774,800,850,856,862,868,874,928],{"title":5,"path":6,"stem":7,"children":8},"Introduction and Foundations","/introduction-and-foundations","01.introduction-and-foundations/01.index",[9,10,14,18,22,26,30,34,38,42,46,50],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"What is Django","/introduction-and-foundations/what-is-django","01.introduction-and-foundations/02.what-is-django",{"title":15,"path":16,"stem":17},"Key Concepts and Philosophy","/introduction-and-foundations/key-concepts-and-philosophy","01.introduction-and-foundations/03.key-concepts-and-philosophy",{"title":19,"path":20,"stem":21},"MVC vs MVT: Understanding Django's Architecture","/introduction-and-foundations/mvc-vs-mvt","01.introduction-and-foundations/04.mvc-vs-mvt",{"title":23,"path":24,"stem":25},"Project Structure Overview","/introduction-and-foundations/project-structure-overview","01.introduction-and-foundations/05.project-structure-overview",{"title":27,"path":28,"stem":29},"Installing Django","/introduction-and-foundations/installing-django","01.introduction-and-foundations/06.installing-django",{"title":31,"path":32,"stem":33},"Creating Your First Django Project","/introduction-and-foundations/creating-first-project","01.introduction-and-foundations/07.creating-first-project",{"title":35,"path":36,"stem":37},"Creating Your First Django App","/introduction-and-foundations/creating-first-app","01.introduction-and-foundations/08.creating-first-app",{"title":39,"path":40,"stem":41},"Your First Django \"Hello World\"","/introduction-and-foundations/hello-world","01.introduction-and-foundations/09.hello-world",{"title":43,"path":44,"stem":45},"Django Quick Start Guide","/introduction-and-foundations/quick-start-guide","01.introduction-and-foundations/10.quick-start-guide",{"title":47,"path":48,"stem":49},"How Django Handles Requests","/introduction-and-foundations/how-django-handles-requests","01.introduction-and-foundations/11.how-django-handles-requests",{"title":51,"path":52,"stem":53},"Django Settings","/introduction-and-foundations/django-settings","01.introduction-and-foundations/12.django-settings",{"title":55,"path":56,"stem":57,"children":58},"The Development Environment","/development-environment","02.development-environment/1.index",[59,61,65,69,73,77,81,85],{"title":60,"path":56,"stem":57},"Development Environment",{"title":62,"path":63,"stem":64},"Recommended Tooling for Django Development","/development-environment/recommended-tooling","02.development-environment/2.recommended-tooling",{"title":66,"path":67,"stem":68},"Virtual Environments","/development-environment/virtual-environments","02.development-environment/3.virtual-environments",{"title":70,"path":71,"stem":72},"Django Admin and Management Commands","/development-environment/admin-and-management-commands","02.development-environment/4.admin-and-management-commands",{"title":74,"path":75,"stem":76},"Django Project Settings","/development-environment/project-settings","02.development-environment/5.project-settings",{"title":78,"path":79,"stem":80},"Managing Django Environments: Local, Staging, and Production","/development-environment/environments-local-staging-production","02.development-environment/6.environments-local-staging-production",{"title":82,"path":83,"stem":84},"Running Django Development Server","/development-environment/running-development-server","02.development-environment/7.running-development-server",{"title":86,"path":87,"stem":88},"Working with Django Shell","/development-environment/working-with-shell","02.development-environment/8.working-with-shell",{"title":90,"path":91,"stem":92,"children":93},"Templates and Presentation Layer","/templates-and-presentation","03.templates-and-presentation/1.index",[94,95,99,103,107,111,115,119],{"title":90,"path":91,"stem":92},{"title":96,"path":97,"stem":98},"Introduction to Django Templates","/templates-and-presentation/introduction-to-templates","03.templates-and-presentation/2.introduction-to-templates",{"title":100,"path":101,"stem":102},"The Django Template Language","/templates-and-presentation/django-template-language","03.templates-and-presentation/3.django-template-language",{"title":104,"path":105,"stem":106},"Template Inheritance","/templates-and-presentation/template-inheritance","03.templates-and-presentation/4.template-inheritance",{"title":108,"path":109,"stem":110},"Built-in Template Tags and Filters","/templates-and-presentation/built-in-template-tags-and-filters","03.templates-and-presentation/5.built-in-template-tags-and-filters",{"title":112,"path":113,"stem":114},"Including Static Files","/templates-and-presentation/including-static-files","03.templates-and-presentation/6.including-static-files",{"title":116,"path":117,"stem":118},"Working with Media Files","/templates-and-presentation/working-with-media-files","03.templates-and-presentation/7.working-with-media-files",{"title":120,"path":121,"stem":122},"Using Alternative Template Engines","/templates-and-presentation/using-alternative-template-engines","03.templates-and-presentation/8.using-alternative-template-engines",{"title":124,"path":125,"stem":126,"children":127},"URLs and Views","/urls-and-views","04.urls-and-views/01.index",[128,129,133,137,141,145,149,153,157,161],{"title":124,"path":125,"stem":126},{"title":130,"path":131,"stem":132},"The URL Dispatcher","/urls-and-views/the-url-dispatcher","04.urls-and-views/02.the-url-dispatcher",{"title":134,"path":135,"stem":136},"Writing Function-Based Views","/urls-and-views/writing-function-based-views","04.urls-and-views/03.writing-function-based-views",{"title":138,"path":139,"stem":140},"View Decorators","/urls-and-views/view-decorators","04.urls-and-views/04.view-decorators",{"title":142,"path":143,"stem":144},"Rendering Responses","/urls-and-views/rendering-responses","04.urls-and-views/05.rendering-responses",{"title":146,"path":147,"stem":148},"Redirects","/urls-and-views/redirects","04.urls-and-views/06.redirects",{"title":150,"path":151,"stem":152},"Handling HTTP Methods","/urls-and-views/handling-http-methods","04.urls-and-views/07.handling-http-methods",{"title":154,"path":155,"stem":156},"Conditional View Processing","/urls-and-views/conditional-view-processing","04.urls-and-views/08.conditional-view-processing",{"title":158,"path":159,"stem":160},"File Uploads","/urls-and-views/file-uploads","04.urls-and-views/09.file-uploads",{"title":162,"path":163,"stem":164},"Using Django Shortcut Functions","/urls-and-views/using-django-shortcut-functions","04.urls-and-views/10.using-django-shortcut-functions",{"title":166,"path":167,"stem":168,"children":169},"Class Based Views","/class-based-views","05.class-based-views/01.index",[170,171,175,179,183,187,191,195,199,203,207],{"title":166,"path":167,"stem":168},{"title":172,"path":173,"stem":174},"Introduction to Class-Based Views","/class-based-views/introduction-to-class-based-views","05.class-based-views/02.introduction-to-class-based-views",{"title":176,"path":177,"stem":178},"Common Base Classes","/class-based-views/common-base-classes","05.class-based-views/03.common-base-classes",{"title":180,"path":181,"stem":182},"Built-in Generic Views","/class-based-views/built-in-generic-views","05.class-based-views/04.built-in-generic-views",{"title":184,"path":185,"stem":186},"Views for CRUD Operations","/class-based-views/views-for-crud-operations","05.class-based-views/05.views-for-crud-operations",{"title":188,"path":189,"stem":190},"Handling Forms with Class-Based Views","/class-based-views/handling-forms-with-class-based-views","05.class-based-views/06.handling-forms-with-class-based-views",{"title":192,"path":193,"stem":194},"Using Mixins","/class-based-views/using-mixins","05.class-based-views/07.using-mixins",{"title":196,"path":197,"stem":198},"URL Configuration with Class-Based Views","/class-based-views/url-configuration-with-class-based-views","05.class-based-views/08.url-configuration-with-class-based-views",{"title":200,"path":201,"stem":202},"Subclassing Generic Views","/class-based-views/subclassing-generic-views","05.class-based-views/09.subclassing-generic-views",{"title":204,"path":205,"stem":206},"Asynchronous Class-Based Views","/class-based-views/asynchronous-class-based-views","05.class-based-views/10.asynchronous-class-based-views",{"title":208,"path":209,"stem":210},"Pagination","/class-based-views/pagination","05.class-based-views/11.pagination",{"title":212,"path":213,"stem":214,"children":215},"Forms and User Input","/forms-and-user-input","06.forms-and-user-input/01.index",[216,217,221,225,229,233,237,241,245,249],{"title":212,"path":213,"stem":214},{"title":218,"path":219,"stem":220},"Understanding HTML Forms","/forms-and-user-input/understanding-html-forms","06.forms-and-user-input/02.understanding-html-forms",{"title":222,"path":223,"stem":224},"Django's Role in Form Handling","/forms-and-user-input/djangos-role-in-form-handling","06.forms-and-user-input/03.djangos-role-in-form-handling",{"title":226,"path":227,"stem":228},"Creating Forms with Forms API","/forms-and-user-input/creating-forms-with-forms-api","06.forms-and-user-input/04.creating-forms-with-forms-api",{"title":230,"path":231,"stem":232},"Form Validation","/forms-and-user-input/form-validation","06.forms-and-user-input/05.form-validation",{"title":234,"path":235,"stem":236},"Built-in Fields and Widgets","/forms-and-user-input/built-in-fields-and-widgets","06.forms-and-user-input/06.built-in-fields-and-widgets",{"title":238,"path":239,"stem":240},"Form Rendering in Templates","/forms-and-user-input/form-rendering-in-templates","06.forms-and-user-input/07.form-rendering-in-templates",{"title":242,"path":243,"stem":244},"Model Forms","/forms-and-user-input/model-forms","06.forms-and-user-input/08.model-forms",{"title":246,"path":247,"stem":248},"Advanced Form Techniques","/forms-and-user-input/advanced-form-techniques","06.forms-and-user-input/09.advanced-form-techniques",{"title":250,"path":251,"stem":252},"Security Considerations for Forms","/forms-and-user-input/security-considerations-for-forms","06.forms-and-user-input/10.security-considerations-for-forms",{"title":254,"path":255,"stem":256,"children":257},"Models and Databases","/models-and-databases","07.models-and-databases/01.index",[258,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327],{"title":254,"path":255,"stem":256},{"title":260,"path":261,"stem":262},"Understanding Django Models","/models-and-databases/understanding-django-models","07.models-and-databases/02.understanding-django-models",{"title":264,"path":265,"stem":266},"Defining Fields","/models-and-databases/defining-fields","07.models-and-databases/03.defining-fields",{"title":268,"path":269,"stem":270},"Relationships and Foreign Keys","/models-and-databases/relationships-and-foreign-keys","07.models-and-databases/04.relationships-and-foreign-keys",{"title":272,"path":273,"stem":274},"Examples of Relationship Patterns","/models-and-databases/examples-of-relationship-patterns","07.models-and-databases/05.examples-of-relationship-patterns",{"title":276,"path":277,"stem":278},"Making Queries","/models-and-databases/making-queries","07.models-and-databases/06.making-queries",{"title":280,"path":281,"stem":282},"Filtering, Ordering, and Slicing","/models-and-databases/filtering-ordering-slicing","07.models-and-databases/07.filtering-ordering-slicing",{"title":284,"path":285,"stem":286},"Managers and QuerySets","/models-and-databases/managers-and-querysets","07.models-and-databases/08.managers-and-querysets",{"title":288,"path":289,"stem":290},"Aggregation","/models-and-databases/aggregation","07.models-and-databases/09.aggregation",{"title":292,"path":293,"stem":294},"Search","/models-and-databases/search","07.models-and-databases/10.search",{"title":296,"path":297,"stem":298},"Raw SQL Queries","/models-and-databases/raw-sql-queries","07.models-and-databases/11.raw-sql-queries",{"title":300,"path":301,"stem":302},"Transactions","/models-and-databases/transactions","07.models-and-databases/12.transactions",{"title":304,"path":305,"stem":306},"Multiple Databases","/models-and-databases/multiple-databases","07.models-and-databases/13.multiple-databases",{"title":308,"path":309,"stem":310},"Tablespaces","/models-and-databases/tablespaces","07.models-and-databases/14.tablespaces",{"title":312,"path":313,"stem":314},"Composite Primary Keys","/models-and-databases/composite-primary-keys","07.models-and-databases/15.composite-primary-keys",{"title":316,"path":317,"stem":318},"Database Instrumentation","/models-and-databases/database-instrumentation","07.models-and-databases/16.database-instrumentation",{"title":320,"path":321,"stem":322},"Database Optimization","/models-and-databases/database-optimization","07.models-and-databases/17.database-optimization",{"title":324,"path":325,"stem":326},"Fixtures","/models-and-databases/fixtures","07.models-and-databases/18.fixtures",{"title":328,"path":329,"stem":330},"Signals","/models-and-databases/signals","07.models-and-databases/19.signals",{"title":332,"path":333,"stem":334,"children":335},"Migrations","/migrations","08.migrations/01.index",[336,337,341,345,349,353,357,361,365,369,373,377,381,385],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"How Migrations Work","/migrations/how-migrations-work","08.migrations/02.how-migrations-work",{"title":342,"path":343,"stem":344},"Management Commands","/migrations/management-commands","08.migrations/03.management-commands",{"title":346,"path":347,"stem":348},"Dependencies and Workflow","/migrations/dependencies-and-workflow","08.migrations/04.dependencies-and-workflow",{"title":350,"path":351,"stem":352},"Transaction Handling","/migrations/transaction-handling","08.migrations/05.transaction-handling",{"title":354,"path":355,"stem":356},"Adding Migrations to Apps","/migrations/adding-migrations-to-apps","08.migrations/06.adding-migrations-to-apps",{"title":358,"path":359,"stem":360},"Reversing Migrations","/migrations/reversing-migrations","08.migrations/07.reversing-migrations",{"title":362,"path":363,"stem":364},"Historical Models","/migrations/historical-models","08.migrations/08.historical-models",{"title":366,"path":367,"stem":368},"Considerations When Removing Fields","/migrations/considerations-when-removing-fields","08.migrations/09.considerations-when-removing-fields",{"title":370,"path":371,"stem":372},"Data Migrations","/migrations/data-migrations","08.migrations/10.data-migrations",{"title":374,"path":375,"stem":376},"Squashing Migrations","/migrations/squashing-migrations","08.migrations/11.squashing-migrations",{"title":378,"path":379,"stem":380},"Serializing Values","/migrations/serializing-values","08.migrations/12.serializing-values",{"title":382,"path":383,"stem":384},"Supporting Multiple Django Versions","/migrations/supporting-multiple-django-versions","08.migrations/13.supporting-multiple-django-versions",{"title":386,"path":387,"stem":388},"Django Serialization Framework","/migrations/django-serialization-framework","08.migrations/14.django-serialization-framework",{"title":390,"path":391,"stem":392,"children":393},"Authentication and Authorization","/authentication-and-authorization","09.authentication-and-authorization/01.index",[394,395,399,403,407,411,415,419,423,427,431,435],{"title":390,"path":391,"stem":392},{"title":396,"path":397,"stem":398},"Overview of Django's Authentication System","/authentication-and-authorization/overview-of-django-authentication-system","09.authentication-and-authorization/02.overview-of-django-authentication-system",{"title":400,"path":401,"stem":402},"Users and Groups","/authentication-and-authorization/users-and-groups","09.authentication-and-authorization/03.users-and-groups",{"title":404,"path":405,"stem":406},"Permissions","/authentication-and-authorization/permissions","09.authentication-and-authorization/04.permissions",{"title":408,"path":409,"stem":410},"Password Management","/authentication-and-authorization/password-management","09.authentication-and-authorization/05.password-management",{"title":412,"path":413,"stem":414},"Authentication Views","/authentication-and-authorization/authentication-views","09.authentication-and-authorization/06.authentication-views",{"title":416,"path":417,"stem":418},"Login and Logout","/authentication-and-authorization/login-and-logout","09.authentication-and-authorization/07.login-and-logout",{"title":420,"path":421,"stem":422},"Custom User Models","/authentication-and-authorization/custom-user-models","09.authentication-and-authorization/08.custom-user-models",{"title":424,"path":425,"stem":426},"Middleware for Authentication","/authentication-and-authorization/middleware-for-authentication","09.authentication-and-authorization/09.middleware-for-authentication",{"title":428,"path":429,"stem":430},"Authorization in Views and Templates","/authentication-and-authorization/authorization-in-views-and-templates","09.authentication-and-authorization/10.authorization-in-views-and-templates",{"title":432,"path":433,"stem":434},"Integrating Social Authentication","/authentication-and-authorization/integrating-social-authentication","09.authentication-and-authorization/11.integrating-social-authentication",{"title":436,"path":437,"stem":438},"Security Best Practices","/authentication-and-authorization/security-best-practices","09.authentication-and-authorization/12.security-best-practices",{"title":440,"path":441,"stem":442,"children":443},"Sessions, Cookies, and State","/sessions-cookies-state","10.sessions-cookies-state/01.index",[444,446,450,454,458],{"title":445,"path":441,"stem":442},"Sessions, Cookies, and State Management",{"title":447,"path":448,"stem":449},"Introduction to Sessions","/sessions-cookies-state/introduction-to-sessions","10.sessions-cookies-state/02.introduction-to-sessions",{"title":451,"path":452,"stem":453},"Working with Cookies","/sessions-cookies-state/working-with-cookies","10.sessions-cookies-state/03.working-with-cookies",{"title":455,"path":456,"stem":457},"Server-Side Session Storage Options","/sessions-cookies-state/server-side-session-storage-options","10.sessions-cookies-state/04.server-side-session-storage-options",{"title":459,"path":460,"stem":461},"Session Security","/sessions-cookies-state/session-security","10.sessions-cookies-state/05.session-security",{"title":463,"path":464,"stem":465,"children":466},"Working with Files","/working-with-files","11.working-with-files/01.index",[467,468,472,476,480,484],{"title":463,"path":464,"stem":465},{"title":469,"path":470,"stem":471},"Files in Models","/working-with-files/files-in-models","11.working-with-files/02.files-in-models",{"title":473,"path":474,"stem":475},"The File Object","/working-with-files/the-file-object","11.working-with-files/03.the-file-object",{"title":477,"path":478,"stem":479},"Storage Backends","/working-with-files/storage-backends","11.working-with-files/04.storage-backends",{"title":481,"path":482,"stem":483},"Using Cloud Storage Providers","/working-with-files/using-cloud-storage-providers","11.working-with-files/05.using-cloud-storage-providers",{"title":485,"path":486,"stem":487},"Managing Media in Production","/working-with-files/managing-media-in-production","11.working-with-files/06.managing-media-in-production",{"title":489,"path":490,"stem":491,"children":492},"Admin Site","/admin-site","12.admin-site/01.index",[493,494,498,502,506,510],{"title":489,"path":490,"stem":491},{"title":495,"path":496,"stem":497},"Enabling the Admin","/admin-site/enabling-the-admin","12.admin-site/02.enabling-the-admin",{"title":499,"path":500,"stem":501},"Registering Models","/admin-site/registering-models","12.admin-site/03.registering-models",{"title":503,"path":504,"stem":505},"Customizing Admin Display","/admin-site/customizing-admin-display","12.admin-site/04.customizing-admin-display",{"title":507,"path":508,"stem":509},"Admin Actions","/admin-site/admin-actions","12.admin-site/05.admin-actions",{"title":511,"path":512,"stem":513},"Admin Security Best Practices","/admin-site/admin-security-best-practices","12.admin-site/06.admin-security-best-practices",{"title":515,"path":516,"stem":517,"children":518},"Middleware","/middleware","13.middleware/01.index",[519,520,524,528,532,536],{"title":515,"path":516,"stem":517},{"title":521,"path":522,"stem":523},"Middleware Overview","/middleware/middleware-overview","13.middleware/02.middleware-overview",{"title":525,"path":526,"stem":527},"Built-in Middleware","/middleware/built-in-middleware","13.middleware/03.built-in-middleware",{"title":529,"path":530,"stem":531},"Creating Custom Middleware","/middleware/creating-custom-middleware","13.middleware/04.creating-custom-middleware",{"title":533,"path":534,"stem":535},"Middleware Ordering","/middleware/middleware-ordering","13.middleware/05.middleware-ordering",{"title":537,"path":538,"stem":539},"Performance and Debugging","/middleware/performance-and-debugging","13.middleware/06.performance-and-debugging",{"title":541,"path":542,"stem":543,"children":544},"Security","/security","14.security/01.index",[545,546,550,554,558,562,566,570,574],{"title":541,"path":542,"stem":543},{"title":547,"path":548,"stem":549},"Django Security Philosophy","/security/django-security-philosophy","14.security/02.django-security-philosophy",{"title":551,"path":552,"stem":553},"Cross Site Request Forgery","/security/cross-site-request-forgery","14.security/03.cross-site-request-forgery",{"title":555,"path":556,"stem":557},"Cross Site Scripting","/security/cross-site-scripting","14.security/04.cross-site-scripting",{"title":559,"path":560,"stem":561},"SQL Injection Protection","/security/sql-injection-protection","14.security/05.sql-injection-protection",{"title":563,"path":564,"stem":565},"Clickjacking Protection","/security/clickjacking-protection","14.security/06.clickjacking-protection",{"title":567,"path":568,"stem":569},"HTTPS Setup and HSTS","/security/https-setup-and-hsts","14.security/07.https-setup-and-hsts",{"title":571,"path":572,"stem":573},"Password Storage and Cryptography","/security/password-storage-and-cryptography","14.security/08.password-storage-and-cryptography",{"title":575,"path":576,"stem":577},"Secure Deployment Checklist","/security/secure-deployment-checklist","14.security/09.secure-deployment-checklist",{"title":579,"path":580,"stem":581,"children":582},"Testing","/testing","15.testing/01.index",[583,584,588,592,596,600,604,608,612,616,620],{"title":579,"path":580,"stem":581},{"title":585,"path":586,"stem":587},"Introduction to Django Testing","/testing/introduction-to-django-testing","15.testing/02.introduction-to-django-testing",{"title":589,"path":590,"stem":591},"Writing and Running Tests","/testing/writing-and-running-tests","15.testing/03.writing-and-running-tests",{"title":593,"path":594,"stem":595},"Test Tools","/testing/test-tools","15.testing/04.test-tools",{"title":597,"path":598,"stem":599},"Testing Models","/testing/testing-models","15.testing/05.testing-models",{"title":601,"path":602,"stem":603},"Testing Views","/testing/testing-views","15.testing/06.testing-views",{"title":605,"path":606,"stem":607},"Testing Forms","/testing/testing-forms","15.testing/07.testing-forms",{"title":609,"path":610,"stem":611},"Testing Templates","/testing/testing-templates","15.testing/08.testing-templates",{"title":613,"path":614,"stem":615},"Testing Authentication","/testing/testing-authentication","15.testing/09.testing-authentication",{"title":617,"path":618,"stem":619},"Advanced Testing Topics","/testing/advanced-testing-topics","15.testing/10.advanced-testing-topics",{"title":621,"path":622,"stem":623},"Performance Testing","/testing/performance-testing","15.testing/11.performance-testing",{"title":625,"path":626,"stem":627,"children":628},"Static Assets and Frontend Integration","/static-assets-and-frontend-integration","16.static-assets-and-frontend-integration/01.index",[629,630,634,638,642,646],{"title":625,"path":626,"stem":627},{"title":631,"path":632,"stem":633},"Working with Static Files","/static-assets-and-frontend-integration/working-with-static-files","16.static-assets-and-frontend-integration/02.working-with-static-files",{"title":635,"path":636,"stem":637},"Integrating CSS and JavaScript","/static-assets-and-frontend-integration/integrating-css-and-javascript","16.static-assets-and-frontend-integration/03.integrating-css-and-javascript",{"title":639,"path":640,"stem":641},"Using Build Tools like Vite or Webpack","/static-assets-and-frontend-integration/using-build-tools-like-vite-or-webpack","16.static-assets-and-frontend-integration/04.using-build-tools-like-vite-or-webpack",{"title":643,"path":644,"stem":645},"Using React or Vue with Django","/static-assets-and-frontend-integration/using-react-or-vue-with-django","16.static-assets-and-frontend-integration/05.using-react-or-vue-with-django",{"title":647,"path":648,"stem":649},"Managing CORS","/static-assets-and-frontend-integration/managing-cors","16.static-assets-and-frontend-integration/06.managing-cors",{"title":651,"path":652,"stem":653,"children":654},"Internationalization and Localization","/internationalization-and-localization","17.internationalization-and-localization/01.index",[655,656,660,664,668],{"title":651,"path":652,"stem":653},{"title":657,"path":658,"stem":659},"Enabling Translation","/internationalization-and-localization/enabling-translation","17.internationalization-and-localization/02.enabling-translation",{"title":661,"path":662,"stem":663},"Translating Text in Code and Templates","/internationalization-and-localization/translating-text-in-code-and-templates","17.internationalization-and-localization/03.translating-text-in-code-and-templates",{"title":665,"path":666,"stem":667},"Timezone Support","/internationalization-and-localization/timezone-support","17.internationalization-and-localization/04.timezone-support",{"title":669,"path":670,"stem":671},"Locale Middleware","/internationalization-and-localization/locale-middleware","17.internationalization-and-localization/05.locale-middleware",{"title":673,"path":674,"stem":675,"children":676},"Caching","/caching","18.caching/01.index",[677,678,682,686,690,694,698],{"title":673,"path":674,"stem":675},{"title":679,"path":680,"stem":681},"Introduction to Caching","/caching/introduction-to-caching","18.caching/02.introduction-to-caching",{"title":683,"path":684,"stem":685},"Cache Backends","/caching/cache-backends","18.caching/03.cache-backends",{"title":687,"path":688,"stem":689},"Per View Caching","/caching/per-view-caching","18.caching/04.per-view-caching",{"title":691,"path":692,"stem":693},"Low Level Cache API","/caching/low-level-cache-api","18.caching/05.low-level-cache-api",{"title":695,"path":696,"stem":697},"Template Fragment Caching","/caching/template-fragment-caching","18.caching/06.template-fragment-caching",{"title":699,"path":700,"stem":701},"Deployment Level Caching Patterns","/caching/deployment-level-caching-patterns","18.caching/07.deployment-level-caching-patterns",{"title":703,"path":704,"stem":705,"children":706},"Asynchronous Django","/asynchronous-django","19.asynchronous-django/01.index",[707,708,712,716,720,724,728,732],{"title":703,"path":704,"stem":705},{"title":709,"path":710,"stem":711},"Introduction to ASGI","/asynchronous-django/introduction-to-asgi","19.asynchronous-django/02.introduction-to-asgi",{"title":713,"path":714,"stem":715},"Async Views","/asynchronous-django/async-views","19.asynchronous-django/03.async-views",{"title":717,"path":718,"stem":719},"Async ORM Status","/asynchronous-django/async-orm-status","19.asynchronous-django/04.async-orm-status",{"title":721,"path":722,"stem":723},"WebSockets with Channels","/asynchronous-django/websockets-with-channels","19.asynchronous-django/05.websockets-with-channels",{"title":725,"path":726,"stem":727},"Background Tasks with Celery or RQ","/asynchronous-django/background-tasks-with-celery-or-rq","19.asynchronous-django/06.background-tasks-with-celery-or-rq",{"title":729,"path":730,"stem":731},"Asynchronous Support","/asynchronous-django/asynchronous-support","19.asynchronous-django/07.asynchronous-support",{"title":733,"path":734,"stem":735},"Django's Tasks Framework","/asynchronous-django/django-tasks-framework","19.asynchronous-django/08.django-tasks-framework",{"title":737,"path":738,"stem":739,"children":740},"Deployment","/deployment","20.deployment/01.index",[741,742,746,750,754,758,762,766,770],{"title":737,"path":738,"stem":739},{"title":743,"path":744,"stem":745},"Preparing for Production","/deployment/preparing-for-production","20.deployment/02.preparing-for-production",{"title":747,"path":748,"stem":749},"Using WSGI and ASGI Servers","/deployment/using-wsgi-and-asgi-servers","20.deployment/03.using-wsgi-and-asgi-servers",{"title":751,"path":752,"stem":753},"Deploying on Linux Servers","/deployment/deploying-on-linux-servers","20.deployment/04.deploying-on-linux-servers",{"title":755,"path":756,"stem":757},"Using Docker","/deployment/using-docker","20.deployment/05.using-docker",{"title":759,"path":760,"stem":761},"Cloud Deployment Guides","/deployment/cloud-deployment-guides","20.deployment/06.cloud-deployment-guides",{"title":763,"path":764,"stem":765},"Scaling and Load Balancing","/deployment/scaling-and-load-balancing","20.deployment/07.scaling-and-load-balancing",{"title":767,"path":768,"stem":769},"Monitoring and Logging","/deployment/monitoring-and-logging","20.deployment/08.monitoring-and-logging",{"title":771,"path":772,"stem":773},"Backup Strategies","/deployment/backup-strategies","20.deployment/09.backup-strategies",{"title":775,"path":776,"stem":777,"children":778},"Performance and Optimization","/performance-and-optimization","21.performance-and-optimization/01.index",[779,780,784,788,792,796],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Query Optimization","/performance-and-optimization/query-optimization","21.performance-and-optimization/02.query-optimization",{"title":785,"path":786,"stem":787},"Template Rendering Optimization","/performance-and-optimization/template-rendering-optimization","21.performance-and-optimization/03.template-rendering-optimization",{"title":789,"path":790,"stem":791},"Using Select Related and Prefetch Related","/performance-and-optimization/using-select-related-and-prefetch-related","21.performance-and-optimization/04.using-select-related-and-prefetch-related",{"title":793,"path":794,"stem":795},"Caching Strategies","/performance-and-optimization/caching-strategies","21.performance-and-optimization/05.caching-strategies",{"title":797,"path":798,"stem":799},"Profiling Django Apps","/performance-and-optimization/profiling-django-apps","21.performance-and-optimization/06.profiling-django-apps",{"title":801,"path":802,"stem":803,"children":804},"Advanced and Expert Topics","/advanced-and-expert-topics","22.advanced-and-expert-topics/01.index",[805,806,810,814,818,822,826,830,834,838,842,846],{"title":801,"path":802,"stem":803},{"title":807,"path":808,"stem":809},"System Architecture Patterns","/advanced-and-expert-topics/system-architecture-patterns","22.advanced-and-expert-topics/02.system-architecture-patterns",{"title":811,"path":812,"stem":813},"Domain Driven Design with Django","/advanced-and-expert-topics/domain-driven-design-with-django","22.advanced-and-expert-topics/03.domain-driven-design-with-django",{"title":815,"path":816,"stem":817},"Building Large Scale Django Projects","/advanced-and-expert-topics/building-large-scale-django-projects","22.advanced-and-expert-topics/04.building-large-scale-django-projects",{"title":819,"path":820,"stem":821},"Plugin Architectures for Django Apps","/advanced-and-expert-topics/plugin-architectures-for-django-apps","22.advanced-and-expert-topics/05.plugin-architectures-for-django-apps",{"title":823,"path":824,"stem":825},"Extending Django's Core","/advanced-and-expert-topics/extending-djangos-core","22.advanced-and-expert-topics/06.extending-djangos-core",{"title":827,"path":828,"stem":829},"Custom ORM Expressions","/advanced-and-expert-topics/custom-orm-expressions","22.advanced-and-expert-topics/07.custom-orm-expressions",{"title":831,"path":832,"stem":833},"Custom Management Commands","/advanced-and-expert-topics/custom-management-commands","22.advanced-and-expert-topics/08.custom-management-commands",{"title":835,"path":836,"stem":837},"Working with Signals","/advanced-and-expert-topics/working-with-signals","22.advanced-and-expert-topics/09.working-with-signals",{"title":839,"path":840,"stem":841},"Building Reusable Django Packages","/advanced-and-expert-topics/building-reusable-django-packages","22.advanced-and-expert-topics/10.building-reusable-django-packages",{"title":843,"path":844,"stem":845},"Integrating Microservices","/advanced-and-expert-topics/integrating-microservices","22.advanced-and-expert-topics/11.integrating-microservices",{"title":847,"path":848,"stem":849},"Advanced Security Hardening","/advanced-and-expert-topics/advanced-security-hardening","22.advanced-and-expert-topics/12.advanced-security-hardening",{"title":851,"path":852,"stem":853,"children":854},"Logging in Django","/logging-in-django","23.logging-in-django/01.index",[855],{"title":851,"path":852,"stem":853},{"title":857,"path":858,"stem":859,"children":860},"FAQ and Troubleshooting","/faq-and-troubleshooting","24.faq-and-troubleshooting/01.index",[861],{"title":857,"path":858,"stem":859},{"title":863,"path":864,"stem":865,"children":866},"External Packages and Ecosystem","/external-packages-and-ecosystem","25.external-packages-and-ecosystem/01.index",[867],{"title":863,"path":864,"stem":865},{"title":869,"path":870,"stem":871,"children":872},"Django Internals and Contributing","/django-internals-and-contributing","26.django-internals-and-contributing/01.index",[873],{"title":869,"path":870,"stem":871},{"title":875,"path":876,"stem":877,"children":878},"Microservices with Django","/microservices-with-django","27.microservices-with-django/01.index",[879,880,884,888,892,896,900,904,908,912,916,920,924],{"title":875,"path":876,"stem":877},{"title":881,"path":882,"stem":883},"What Is a Microservice?","/microservices-with-django/what-is-a-microservice","27.microservices-with-django/02.what-is-a-microservice",{"title":885,"path":886,"stem":887},"Introducing the Django Microservices Architecture","/microservices-with-django/django-microservices-architecture","27.microservices-with-django/03.django-microservices-architecture",{"title":889,"path":890,"stem":891},"Setting Up the Development and Runtime Environment","/microservices-with-django/development-environment","27.microservices-with-django/04.development-environment",{"title":893,"path":894,"stem":895},"Cloud-native Data Processing with MongoDB","/microservices-with-django/cloud-native-data-processing","27.microservices-with-django/05.cloud-native-data-processing",{"title":897,"path":898,"stem":899},"Creating RESTful APIs for Microservices","/microservices-with-django/restful-apis","27.microservices-with-django/06.restful-apis",{"title":901,"path":902,"stem":903},"Orchestrating Microservices with Celery and RabbitMQ","/microservices-with-django/orchestrating-celery-rabbitmq","27.microservices-with-django/07.orchestrating-celery-rabbitmq",{"title":905,"path":906,"stem":907},"Testing Microservices","/microservices-with-django/testing-microservices","27.microservices-with-django/08.testing-microservices",{"title":909,"path":910,"stem":911},"Deploying Microservices","/microservices-with-django/deploying-microservices","27.microservices-with-django/09.deploying-microservices",{"title":913,"path":914,"stem":915},"Securing Microservices","/microservices-with-django/securing-microservices","27.microservices-with-django/10.securing-microservices",{"title":917,"path":918,"stem":919},"Improving Microservices Performance with Caching","/microservices-with-django/performance-caching","27.microservices-with-django/11.performance-caching",{"title":921,"path":922,"stem":923},"Best Practices","/microservices-with-django/best-practices","27.microservices-with-django/12.best-practices",{"title":925,"path":926,"stem":927},"Transforming a Monolithic Web App into a Microservice version","/microservices-with-django/monolith-to-microservices","27.microservices-with-django/13.monolith-to-microservices",{"title":929,"path":930,"stem":931,"children":932},"Releases","/releases","releases",[933,936,940,944,948,952,956,960,964,968,972,976,980,984,988,992,996,1000,1004,1008,1012],{"title":934,"path":930,"stem":935},"Django Releases","releases/index",{"title":937,"path":938,"stem":939},"Django 5.1.10 release notes","/releases/5.1.10","releases/5.1.10",{"title":941,"path":942,"stem":943},"Django 5.1.11 release notes","/releases/5.1.11","releases/5.1.11",{"title":945,"path":946,"stem":947},"Django 5.1.12 release notes","/releases/5.1.12","releases/5.1.12",{"title":949,"path":950,"stem":951},"Django 5.1.13 release notes","/releases/5.1.13","releases/5.1.13",{"title":953,"path":954,"stem":955},"Django 5.1.14 release notes","/releases/5.1.14","releases/5.1.14",{"title":957,"path":958,"stem":959},"Django 5.1.15 release notes","/releases/5.1.15","releases/5.1.15",{"title":961,"path":962,"stem":963},"Django 5.2 release notes","/releases/5.2","releases/5.2",{"title":965,"path":966,"stem":967},"Django 5.2.1 release notes","/releases/5.2.1","releases/5.2.1",{"title":969,"path":970,"stem":971},"Django 5.2.10 release notes","/releases/5.2.10","releases/5.2.10",{"title":973,"path":974,"stem":975},"Django 5.2.2 release notes","/releases/5.2.2","releases/5.2.2",{"title":977,"path":978,"stem":979},"Django 5.2.3 release notes","/releases/5.2.3","releases/5.2.3",{"title":981,"path":982,"stem":983},"Django 5.2.4 release notes","/releases/5.2.4","releases/5.2.4",{"title":985,"path":986,"stem":987},"Django 5.2.5 release notes","/releases/5.2.5","releases/5.2.5",{"title":989,"path":990,"stem":991},"Django 5.2.6 release notes","/releases/5.2.6","releases/5.2.6",{"title":993,"path":994,"stem":995},"Django 5.2.7 release notes","/releases/5.2.7","releases/5.2.7",{"title":997,"path":998,"stem":999},"Django 5.2.8 release notes","/releases/5.2.8","releases/5.2.8",{"title":1001,"path":1002,"stem":1003},"Django 5.2.9 release notes","/releases/5.2.9","releases/5.2.9",{"title":1005,"path":1006,"stem":1007},"Django 6.0 release notes","/releases/6.0","releases/6.0",{"title":1009,"path":1010,"stem":1011},"Django 6.0.1 release notes","/releases/6.0.1","releases/6.0.1",{"title":1013,"path":1014,"stem":1015},"Django 6.1 release notes - UNDER DEVELOPMENT","/releases/6.1","releases/6.1",{"id":1017,"title":567,"body":1018,"description":1028,"extension":9861,"links":9862,"meta":9863,"navigation":1063,"path":568,"seo":9864,"stem":569,"__hash__":9865},"docs/14.security/07.https-setup-and-hsts.md",{"type":1019,"value":1020,"toc":9827},"minimark",[1021,1025,1029,1034,1039,1190,1194,1326,1330,1334,1549,1553,1829,1833,3357,3361,3365,3693,3697,5052,5056,5060,5205,5209,6004,6008,7630,7634,7638,7923,7927,8200,8204,8208,9740,9744,9748,9764,9767,9781,9785,9799,9803,9817,9821,9824],[1022,1023,567],"h1",{"id":1024},"https-setup-and-hsts",[1026,1027,1028],"p",{},"HTTPS (HTTP Secure) is essential for protecting data in transit and ensuring the integrity and confidentiality of communications between clients and servers. This chapter covers implementing HTTPS in Django applications and configuring HTTP Strict Transport Security (HSTS) for enhanced security.",[1030,1031,1033],"h2",{"id":1032},"understanding-https-and-tls","Understanding HTTPS and TLS",[1035,1036,1038],"h3",{"id":1037},"why-https-is-essential","Why HTTPS is Essential",[1040,1041,1046],"pre",{"className":1042,"code":1043,"language":1044,"meta":1045,"style":1045},"language-python shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# Without HTTPS, sensitive data is transmitted in plain text:\n\n# HTTP Request (VISIBLE TO ANYONE ON THE NETWORK):\n\"\"\"\nPOST /login/ HTTP/1.1\nHost: example.com\nContent-Type: application/x-www-form-urlencoded\n\nusername=admin&password=secretpassword123&csrfmiddlewaretoken=abc123\n\"\"\"\n\n# HTTPS Request (ENCRYPTED):\n\"\"\"\nPOST /login/ HTTP/1.1\nHost: example.com\nContent-Type: application/x-www-form-urlencoded\n[ENCRYPTED DATA - UNREADABLE TO EAVESDROPPERS]\n\"\"\"\n\n# Security benefits of HTTPS:\n# 1. Encryption - Data is encrypted in transit\n# 2. Authentication - Verifies server identity\n# 3. Integrity - Prevents data tampering\n# 4. Trust - Required for modern web features\n","python","",[1047,1048,1049,1058,1065,1071,1078,1085,1091,1097,1102,1108,1113,1118,1124,1129,1134,1139,1144,1150,1155,1160,1166,1172,1178,1184],"code",{"__ignoreMap":1045},[1050,1051,1054],"span",{"class":1052,"line":1053},"line",1,[1050,1055,1057],{"class":1056},"s9Tkl","# Without HTTPS, sensitive data is transmitted in plain text:\n",[1050,1059,1061],{"class":1052,"line":1060},2,[1050,1062,1064],{"emptyLinePlaceholder":1063},true,"\n",[1050,1066,1068],{"class":1052,"line":1067},3,[1050,1069,1070],{"class":1056},"# HTTP Request (VISIBLE TO ANYONE ON THE NETWORK):\n",[1050,1072,1074],{"class":1052,"line":1073},4,[1050,1075,1077],{"class":1076},"sm7ve","\"\"\"\n",[1050,1079,1081],{"class":1052,"line":1080},5,[1050,1082,1084],{"class":1083},"sVyVU","POST /login/ HTTP/1.1\n",[1050,1086,1088],{"class":1052,"line":1087},6,[1050,1089,1090],{"class":1083},"Host: example.com\n",[1050,1092,1094],{"class":1052,"line":1093},7,[1050,1095,1096],{"class":1083},"Content-Type: application/x-www-form-urlencoded\n",[1050,1098,1100],{"class":1052,"line":1099},8,[1050,1101,1064],{"emptyLinePlaceholder":1063},[1050,1103,1105],{"class":1052,"line":1104},9,[1050,1106,1107],{"class":1083},"username=admin&password=secretpassword123&csrfmiddlewaretoken=abc123\n",[1050,1109,1111],{"class":1052,"line":1110},10,[1050,1112,1077],{"class":1076},[1050,1114,1116],{"class":1052,"line":1115},11,[1050,1117,1064],{"emptyLinePlaceholder":1063},[1050,1119,1121],{"class":1052,"line":1120},12,[1050,1122,1123],{"class":1056},"# HTTPS Request (ENCRYPTED):\n",[1050,1125,1127],{"class":1052,"line":1126},13,[1050,1128,1077],{"class":1076},[1050,1130,1132],{"class":1052,"line":1131},14,[1050,1133,1084],{"class":1083},[1050,1135,1137],{"class":1052,"line":1136},15,[1050,1138,1090],{"class":1083},[1050,1140,1142],{"class":1052,"line":1141},16,[1050,1143,1096],{"class":1083},[1050,1145,1147],{"class":1052,"line":1146},17,[1050,1148,1149],{"class":1083},"[ENCRYPTED DATA - UNREADABLE TO EAVESDROPPERS]\n",[1050,1151,1153],{"class":1052,"line":1152},18,[1050,1154,1077],{"class":1076},[1050,1156,1158],{"class":1052,"line":1157},19,[1050,1159,1064],{"emptyLinePlaceholder":1063},[1050,1161,1163],{"class":1052,"line":1162},20,[1050,1164,1165],{"class":1056},"# Security benefits of HTTPS:\n",[1050,1167,1169],{"class":1052,"line":1168},21,[1050,1170,1171],{"class":1056},"# 1. Encryption - Data is encrypted in transit\n",[1050,1173,1175],{"class":1052,"line":1174},22,[1050,1176,1177],{"class":1056},"# 2. Authentication - Verifies server identity\n",[1050,1179,1181],{"class":1052,"line":1180},23,[1050,1182,1183],{"class":1056},"# 3. Integrity - Prevents data tampering\n",[1050,1185,1187],{"class":1052,"line":1186},24,[1050,1188,1189],{"class":1056},"# 4. Trust - Required for modern web features\n",[1035,1191,1193],{"id":1192},"tlsssl-certificates","TLS/SSL Certificates",[1040,1195,1197],{"className":1042,"code":1196,"language":1044,"meta":1045,"style":1045},"# Certificate types and their use cases:\n\n# 1. Domain Validated (DV) Certificates\n# - Validates domain ownership only\n# - Suitable for most websites\n# - Quick issuance (minutes to hours)\n\n# 2. Organization Validated (OV) Certificates  \n# - Validates organization identity\n# - Shows organization name in certificate\n# - More trust indicators\n\n# 3. Extended Validation (EV) Certificates\n# - Highest level of validation\n# - Shows organization name in browser\n# - Most expensive but highest trust\n\n# 4. Wildcard Certificates\n# - Covers all subdomains (*.example.com)\n# - Useful for multiple subdomains\n# - Single certificate management\n\n# 5. Multi-Domain (SAN) Certificates\n# - Covers multiple different domains\n# - Cost-effective for multiple sites\n# - Single certificate for multiple domains\n",[1047,1198,1199,1204,1208,1213,1218,1223,1228,1232,1237,1242,1247,1252,1256,1261,1266,1271,1276,1280,1285,1290,1295,1300,1304,1309,1314,1320],{"__ignoreMap":1045},[1050,1200,1201],{"class":1052,"line":1053},[1050,1202,1203],{"class":1056},"# Certificate types and their use cases:\n",[1050,1205,1206],{"class":1052,"line":1060},[1050,1207,1064],{"emptyLinePlaceholder":1063},[1050,1209,1210],{"class":1052,"line":1067},[1050,1211,1212],{"class":1056},"# 1. Domain Validated (DV) Certificates\n",[1050,1214,1215],{"class":1052,"line":1073},[1050,1216,1217],{"class":1056},"# - Validates domain ownership only\n",[1050,1219,1220],{"class":1052,"line":1080},[1050,1221,1222],{"class":1056},"# - Suitable for most websites\n",[1050,1224,1225],{"class":1052,"line":1087},[1050,1226,1227],{"class":1056},"# - Quick issuance (minutes to hours)\n",[1050,1229,1230],{"class":1052,"line":1093},[1050,1231,1064],{"emptyLinePlaceholder":1063},[1050,1233,1234],{"class":1052,"line":1099},[1050,1235,1236],{"class":1056},"# 2. Organization Validated (OV) Certificates  \n",[1050,1238,1239],{"class":1052,"line":1104},[1050,1240,1241],{"class":1056},"# - Validates organization identity\n",[1050,1243,1244],{"class":1052,"line":1110},[1050,1245,1246],{"class":1056},"# - Shows organization name in certificate\n",[1050,1248,1249],{"class":1052,"line":1115},[1050,1250,1251],{"class":1056},"# - More trust indicators\n",[1050,1253,1254],{"class":1052,"line":1120},[1050,1255,1064],{"emptyLinePlaceholder":1063},[1050,1257,1258],{"class":1052,"line":1126},[1050,1259,1260],{"class":1056},"# 3. Extended Validation (EV) Certificates\n",[1050,1262,1263],{"class":1052,"line":1131},[1050,1264,1265],{"class":1056},"# - Highest level of validation\n",[1050,1267,1268],{"class":1052,"line":1136},[1050,1269,1270],{"class":1056},"# - Shows organization name in browser\n",[1050,1272,1273],{"class":1052,"line":1141},[1050,1274,1275],{"class":1056},"# - Most expensive but highest trust\n",[1050,1277,1278],{"class":1052,"line":1146},[1050,1279,1064],{"emptyLinePlaceholder":1063},[1050,1281,1282],{"class":1052,"line":1152},[1050,1283,1284],{"class":1056},"# 4. Wildcard Certificates\n",[1050,1286,1287],{"class":1052,"line":1157},[1050,1288,1289],{"class":1056},"# - Covers all subdomains (*.example.com)\n",[1050,1291,1292],{"class":1052,"line":1162},[1050,1293,1294],{"class":1056},"# - Useful for multiple subdomains\n",[1050,1296,1297],{"class":1052,"line":1168},[1050,1298,1299],{"class":1056},"# - Single certificate management\n",[1050,1301,1302],{"class":1052,"line":1174},[1050,1303,1064],{"emptyLinePlaceholder":1063},[1050,1305,1306],{"class":1052,"line":1180},[1050,1307,1308],{"class":1056},"# 5. Multi-Domain (SAN) Certificates\n",[1050,1310,1311],{"class":1052,"line":1186},[1050,1312,1313],{"class":1056},"# - Covers multiple different domains\n",[1050,1315,1317],{"class":1052,"line":1316},25,[1050,1318,1319],{"class":1056},"# - Cost-effective for multiple sites\n",[1050,1321,1323],{"class":1052,"line":1322},26,[1050,1324,1325],{"class":1056},"# - Single certificate for multiple domains\n",[1030,1327,1329],{"id":1328},"django-https-configuration","Django HTTPS Configuration",[1035,1331,1333],{"id":1332},"basic-https-settings","Basic HTTPS Settings",[1040,1335,1337],{"className":1042,"code":1336,"language":1044,"meta":1045,"style":1045},"# settings.py - Basic HTTPS configuration\nimport os\n\n# Force HTTPS in production\nSECURE_SSL_REDIRECT = True  # Redirect HTTP to HTTPS\n\n# Secure cookie settings\nSESSION_COOKIE_SECURE = True  # Send session cookies over HTTPS only\nCSRF_COOKIE_SECURE = True    # Send CSRF cookies over HTTPS only\n\n# Secure headers\nSECURE_BROWSER_XSS_FILTER = True\nSECURE_CONTENT_TYPE_NOSNIFF = True\n\n# HSTS (HTTP Strict Transport Security)\nSECURE_HSTS_SECONDS = 31536000  # 1 year\nSECURE_HSTS_INCLUDE_SUBDOMAINS = True\nSECURE_HSTS_PRELOAD = True\n\n# Proxy configuration (if behind load balancer/proxy)\nSECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')\n\n# Referrer policy\nSECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin'\n",[1047,1338,1339,1344,1354,1358,1363,1380,1384,1389,1401,1413,1417,1422,1432,1441,1445,1450,1464,1473,1482,1486,1491,1525,1529,1534],{"__ignoreMap":1045},[1050,1340,1341],{"class":1052,"line":1053},[1050,1342,1343],{"class":1056},"# settings.py - Basic HTTPS configuration\n",[1050,1345,1346,1350],{"class":1052,"line":1060},[1050,1347,1349],{"class":1348},"siDh9","import",[1050,1351,1353],{"class":1352},"sftqT"," os\n",[1050,1355,1356],{"class":1052,"line":1067},[1050,1357,1064],{"emptyLinePlaceholder":1063},[1050,1359,1360],{"class":1052,"line":1073},[1050,1361,1362],{"class":1056},"# Force HTTPS in production\n",[1050,1364,1365,1369,1373,1377],{"class":1052,"line":1080},[1050,1366,1368],{"class":1367},"se3Ec","SECURE_SSL_REDIRECT",[1050,1370,1372],{"class":1371},"soVBu"," =",[1050,1374,1376],{"class":1375},"s8XtY"," True",[1050,1378,1379],{"class":1056},"  # Redirect HTTP to HTTPS\n",[1050,1381,1382],{"class":1052,"line":1087},[1050,1383,1064],{"emptyLinePlaceholder":1063},[1050,1385,1386],{"class":1052,"line":1093},[1050,1387,1388],{"class":1056},"# Secure cookie settings\n",[1050,1390,1391,1394,1396,1398],{"class":1052,"line":1099},[1050,1392,1393],{"class":1367},"SESSION_COOKIE_SECURE",[1050,1395,1372],{"class":1371},[1050,1397,1376],{"class":1375},[1050,1399,1400],{"class":1056},"  # Send session cookies over HTTPS only\n",[1050,1402,1403,1406,1408,1410],{"class":1052,"line":1104},[1050,1404,1405],{"class":1367},"CSRF_COOKIE_SECURE",[1050,1407,1372],{"class":1371},[1050,1409,1376],{"class":1375},[1050,1411,1412],{"class":1056},"    # Send CSRF cookies over HTTPS only\n",[1050,1414,1415],{"class":1052,"line":1110},[1050,1416,1064],{"emptyLinePlaceholder":1063},[1050,1418,1419],{"class":1052,"line":1115},[1050,1420,1421],{"class":1056},"# Secure headers\n",[1050,1423,1424,1427,1429],{"class":1052,"line":1120},[1050,1425,1426],{"class":1367},"SECURE_BROWSER_XSS_FILTER",[1050,1428,1372],{"class":1371},[1050,1430,1431],{"class":1375}," True\n",[1050,1433,1434,1437,1439],{"class":1052,"line":1126},[1050,1435,1436],{"class":1367},"SECURE_CONTENT_TYPE_NOSNIFF",[1050,1438,1372],{"class":1371},[1050,1440,1431],{"class":1375},[1050,1442,1443],{"class":1052,"line":1131},[1050,1444,1064],{"emptyLinePlaceholder":1063},[1050,1446,1447],{"class":1052,"line":1136},[1050,1448,1449],{"class":1056},"# HSTS (HTTP Strict Transport Security)\n",[1050,1451,1452,1455,1457,1461],{"class":1052,"line":1141},[1050,1453,1454],{"class":1367},"SECURE_HSTS_SECONDS",[1050,1456,1372],{"class":1371},[1050,1458,1460],{"class":1459},"s7CZa"," 31536000",[1050,1462,1463],{"class":1056},"  # 1 year\n",[1050,1465,1466,1469,1471],{"class":1052,"line":1146},[1050,1467,1468],{"class":1367},"SECURE_HSTS_INCLUDE_SUBDOMAINS",[1050,1470,1372],{"class":1371},[1050,1472,1431],{"class":1375},[1050,1474,1475,1478,1480],{"class":1052,"line":1152},[1050,1476,1477],{"class":1367},"SECURE_HSTS_PRELOAD",[1050,1479,1372],{"class":1371},[1050,1481,1431],{"class":1375},[1050,1483,1484],{"class":1052,"line":1157},[1050,1485,1064],{"emptyLinePlaceholder":1063},[1050,1487,1488],{"class":1052,"line":1162},[1050,1489,1490],{"class":1056},"# Proxy configuration (if behind load balancer/proxy)\n",[1050,1492,1493,1496,1498,1501,1505,1509,1511,1514,1517,1520,1522],{"class":1052,"line":1168},[1050,1494,1495],{"class":1367},"SECURE_PROXY_SSL_HEADER",[1050,1497,1372],{"class":1371},[1050,1499,1500],{"class":1371}," (",[1050,1502,1504],{"class":1503},"sbYkP","'",[1050,1506,1508],{"class":1507},"sTbE_","HTTP_X_FORWARDED_PROTO",[1050,1510,1504],{"class":1503},[1050,1512,1513],{"class":1371},",",[1050,1515,1516],{"class":1503}," '",[1050,1518,1519],{"class":1507},"https",[1050,1521,1504],{"class":1503},[1050,1523,1524],{"class":1371},")\n",[1050,1526,1527],{"class":1052,"line":1174},[1050,1528,1064],{"emptyLinePlaceholder":1063},[1050,1530,1531],{"class":1052,"line":1180},[1050,1532,1533],{"class":1056},"# Referrer policy\n",[1050,1535,1536,1539,1541,1543,1546],{"class":1052,"line":1186},[1050,1537,1538],{"class":1367},"SECURE_REFERRER_POLICY",[1050,1540,1372],{"class":1371},[1050,1542,1516],{"class":1503},[1050,1544,1545],{"class":1507},"strict-origin-when-cross-origin",[1050,1547,1548],{"class":1503},"'\n",[1035,1550,1552],{"id":1551},"environment-specific-configuration","Environment-Specific Configuration",[1040,1554,1556],{"className":1042,"code":1555,"language":1044,"meta":1045,"style":1045},"# settings/base.py - Base security settings\nSECURE_BROWSER_XSS_FILTER = True\nSECURE_CONTENT_TYPE_NOSNIFF = True\nSECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin'\n\n# settings/development.py - Development settings\nfrom .base import *\n\n# Allow HTTP in development\nSECURE_SSL_REDIRECT = False\nSESSION_COOKIE_SECURE = False\nCSRF_COOKIE_SECURE = False\nSECURE_HSTS_SECONDS = 0  # Disable HSTS in development\n\n# settings/production.py - Production settings\nfrom .base import *\n\n# Enforce HTTPS in production\nSECURE_SSL_REDIRECT = True\nSESSION_COOKIE_SECURE = True\nCSRF_COOKIE_SECURE = True\n\n# HSTS configuration\nSECURE_HSTS_SECONDS = 31536000  # 1 year\nSECURE_HSTS_INCLUDE_SUBDOMAINS = True\nSECURE_HSTS_PRELOAD = True\n\n# Proxy configuration for production\nSECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')\n\n# Additional production security\nALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']\n",[1047,1557,1558,1563,1571,1579,1591,1595,1600,1617,1621,1626,1635,1643,1651,1663,1667,1672,1684,1688,1693,1701,1709,1717,1721,1726,1736,1744,1752,1757,1763,1788,1793,1799],{"__ignoreMap":1045},[1050,1559,1560],{"class":1052,"line":1053},[1050,1561,1562],{"class":1056},"# settings/base.py - Base security settings\n",[1050,1564,1565,1567,1569],{"class":1052,"line":1060},[1050,1566,1426],{"class":1367},[1050,1568,1372],{"class":1371},[1050,1570,1431],{"class":1375},[1050,1572,1573,1575,1577],{"class":1052,"line":1067},[1050,1574,1436],{"class":1367},[1050,1576,1372],{"class":1371},[1050,1578,1431],{"class":1375},[1050,1580,1581,1583,1585,1587,1589],{"class":1052,"line":1073},[1050,1582,1538],{"class":1367},[1050,1584,1372],{"class":1371},[1050,1586,1516],{"class":1503},[1050,1588,1545],{"class":1507},[1050,1590,1548],{"class":1503},[1050,1592,1593],{"class":1052,"line":1080},[1050,1594,1064],{"emptyLinePlaceholder":1063},[1050,1596,1597],{"class":1052,"line":1087},[1050,1598,1599],{"class":1056},"# settings/development.py - Development settings\n",[1050,1601,1602,1605,1608,1611,1613],{"class":1052,"line":1093},[1050,1603,1604],{"class":1348},"from",[1050,1606,1607],{"class":1371}," .",[1050,1609,1610],{"class":1352},"base ",[1050,1612,1349],{"class":1348},[1050,1614,1616],{"class":1615},"sVsLi"," *\n",[1050,1618,1619],{"class":1052,"line":1099},[1050,1620,1064],{"emptyLinePlaceholder":1063},[1050,1622,1623],{"class":1052,"line":1104},[1050,1624,1625],{"class":1056},"# Allow HTTP in development\n",[1050,1627,1628,1630,1632],{"class":1052,"line":1110},[1050,1629,1368],{"class":1367},[1050,1631,1372],{"class":1371},[1050,1633,1634],{"class":1375}," False\n",[1050,1636,1637,1639,1641],{"class":1052,"line":1115},[1050,1638,1393],{"class":1367},[1050,1640,1372],{"class":1371},[1050,1642,1634],{"class":1375},[1050,1644,1645,1647,1649],{"class":1052,"line":1120},[1050,1646,1405],{"class":1367},[1050,1648,1372],{"class":1371},[1050,1650,1634],{"class":1375},[1050,1652,1653,1655,1657,1660],{"class":1052,"line":1126},[1050,1654,1454],{"class":1367},[1050,1656,1372],{"class":1371},[1050,1658,1659],{"class":1459}," 0",[1050,1661,1662],{"class":1056},"  # Disable HSTS in development\n",[1050,1664,1665],{"class":1052,"line":1131},[1050,1666,1064],{"emptyLinePlaceholder":1063},[1050,1668,1669],{"class":1052,"line":1136},[1050,1670,1671],{"class":1056},"# settings/production.py - Production settings\n",[1050,1673,1674,1676,1678,1680,1682],{"class":1052,"line":1141},[1050,1675,1604],{"class":1348},[1050,1677,1607],{"class":1371},[1050,1679,1610],{"class":1352},[1050,1681,1349],{"class":1348},[1050,1683,1616],{"class":1615},[1050,1685,1686],{"class":1052,"line":1146},[1050,1687,1064],{"emptyLinePlaceholder":1063},[1050,1689,1690],{"class":1052,"line":1152},[1050,1691,1692],{"class":1056},"# Enforce HTTPS in production\n",[1050,1694,1695,1697,1699],{"class":1052,"line":1157},[1050,1696,1368],{"class":1367},[1050,1698,1372],{"class":1371},[1050,1700,1431],{"class":1375},[1050,1702,1703,1705,1707],{"class":1052,"line":1162},[1050,1704,1393],{"class":1367},[1050,1706,1372],{"class":1371},[1050,1708,1431],{"class":1375},[1050,1710,1711,1713,1715],{"class":1052,"line":1168},[1050,1712,1405],{"class":1367},[1050,1714,1372],{"class":1371},[1050,1716,1431],{"class":1375},[1050,1718,1719],{"class":1052,"line":1174},[1050,1720,1064],{"emptyLinePlaceholder":1063},[1050,1722,1723],{"class":1052,"line":1180},[1050,1724,1725],{"class":1056},"# HSTS configuration\n",[1050,1727,1728,1730,1732,1734],{"class":1052,"line":1186},[1050,1729,1454],{"class":1367},[1050,1731,1372],{"class":1371},[1050,1733,1460],{"class":1459},[1050,1735,1463],{"class":1056},[1050,1737,1738,1740,1742],{"class":1052,"line":1316},[1050,1739,1468],{"class":1367},[1050,1741,1372],{"class":1371},[1050,1743,1431],{"class":1375},[1050,1745,1746,1748,1750],{"class":1052,"line":1322},[1050,1747,1477],{"class":1367},[1050,1749,1372],{"class":1371},[1050,1751,1431],{"class":1375},[1050,1753,1755],{"class":1052,"line":1754},27,[1050,1756,1064],{"emptyLinePlaceholder":1063},[1050,1758,1760],{"class":1052,"line":1759},28,[1050,1761,1762],{"class":1056},"# Proxy configuration for production\n",[1050,1764,1766,1768,1770,1772,1774,1776,1778,1780,1782,1784,1786],{"class":1052,"line":1765},29,[1050,1767,1495],{"class":1367},[1050,1769,1372],{"class":1371},[1050,1771,1500],{"class":1371},[1050,1773,1504],{"class":1503},[1050,1775,1508],{"class":1507},[1050,1777,1504],{"class":1503},[1050,1779,1513],{"class":1371},[1050,1781,1516],{"class":1503},[1050,1783,1519],{"class":1507},[1050,1785,1504],{"class":1503},[1050,1787,1524],{"class":1371},[1050,1789,1791],{"class":1052,"line":1790},30,[1050,1792,1064],{"emptyLinePlaceholder":1063},[1050,1794,1796],{"class":1052,"line":1795},31,[1050,1797,1798],{"class":1056},"# Additional production security\n",[1050,1800,1802,1805,1807,1810,1812,1815,1817,1819,1821,1824,1826],{"class":1052,"line":1801},32,[1050,1803,1804],{"class":1367},"ALLOWED_HOSTS",[1050,1806,1372],{"class":1371},[1050,1808,1809],{"class":1371}," [",[1050,1811,1504],{"class":1503},[1050,1813,1814],{"class":1507},"yourdomain.com",[1050,1816,1504],{"class":1503},[1050,1818,1513],{"class":1371},[1050,1820,1516],{"class":1503},[1050,1822,1823],{"class":1507},"www.yourdomain.com",[1050,1825,1504],{"class":1503},[1050,1827,1828],{"class":1371},"]\n",[1035,1830,1832],{"id":1831},"custom-https-middleware","Custom HTTPS Middleware",[1040,1834,1836],{"className":1042,"code":1835,"language":1044,"meta":1045,"style":1045},"# middleware.py - Custom HTTPS enforcement middleware\nfrom django.http import HttpResponsePermanentRedirect\nfrom django.conf import settings\nfrom django.urls import reverse\nimport logging\n\nlogger = logging.getLogger('security')\n\nclass EnhancedHTTPSMiddleware:\n    \"\"\"Enhanced HTTPS enforcement with additional security features\"\"\"\n    \n    def __init__(self, get_response):\n        self.get_response = get_response\n        self.exempt_paths = getattr(settings, 'HTTPS_EXEMPT_PATHS', [])\n        self.force_https_paths = getattr(settings, 'FORCE_HTTPS_PATHS', [])\n    \n    def __call__(self, request):\n        # Check if HTTPS should be enforced\n        if self.should_enforce_https(request):\n            if not request.is_secure():\n                return self.redirect_to_https(request)\n        \n        response = self.get_response(request)\n        \n        # Add security headers for HTTPS responses\n        if request.is_secure():\n            self.add_security_headers(request, response)\n        \n        return response\n    \n    def should_enforce_https(self, request):\n        \"\"\"Determine if HTTPS should be enforced for this request\"\"\"\n        \n        # Always enforce for sensitive paths\n        if any(request.path.startswith(path) for path in self.force_https_paths):\n            return True\n        \n        # Skip enforcement for exempt paths\n        if any(request.path.startswith(path) for path in self.exempt_paths):\n            return False\n        \n        # Check global setting\n        return getattr(settings, 'SECURE_SSL_REDIRECT', False)\n    \n    def redirect_to_https(self, request):\n        \"\"\"Redirect HTTP request to HTTPS\"\"\"\n        \n        # Log HTTP access attempt\n        logger.info(f\"HTTP request redirected to HTTPS: {request.path}\", extra={\n            'ip_address': self.get_client_ip(request),\n            'user_agent': request.META.get('HTTP_USER_AGENT', ''),\n            'path': request.path,\n        })\n        \n        # Build HTTPS URL\n        https_url = f\"https://{request.get_host()}{request.get_full_path()}\"\n        \n        return HttpResponsePermanentRedirect(https_url)\n    \n    def add_security_headers(self, request, response):\n        \"\"\"Add security headers to HTTPS responses\"\"\"\n        \n        # HSTS header\n        if getattr(settings, 'SECURE_HSTS_SECONDS', 0):\n            hsts_header = f\"max-age={settings.SECURE_HSTS_SECONDS}\"\n            \n            if getattr(settings, 'SECURE_HSTS_INCLUDE_SUBDOMAINS', False):\n                hsts_header += \"; includeSubDomains\"\n            \n            if getattr(settings, 'SECURE_HSTS_PRELOAD', False):\n                hsts_header += \"; preload\"\n            \n            response['Strict-Transport-Security'] = hsts_header\n        \n        # Additional security headers\n        response['X-Content-Type-Options'] = 'nosniff'\n        response['X-Frame-Options'] = 'DENY'\n        response['X-XSS-Protection'] = '1; mode=block'\n        \n        # Referrer policy\n        if hasattr(settings, 'SECURE_REFERRER_POLICY'):\n            response['Referrer-Policy'] = settings.SECURE_REFERRER_POLICY\n    \n    def get_client_ip(self, request):\n        \"\"\"Get client IP address\"\"\"\n        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')\n        if x_forwarded_for:\n            ip = x_forwarded_for.split(',')[0]\n        else:\n            ip = request.META.get('REMOTE_ADDR')\n        return ip\n\n# settings.py - Configuration for custom middleware\nMIDDLEWARE = [\n    'myapp.middleware.EnhancedHTTPSMiddleware',\n    # ... other middleware\n]\n\n# Custom HTTPS settings\nHTTPS_EXEMPT_PATHS = [\n    '/health/',  # Health check endpoints\n    '/status/',  # Status endpoints\n]\n\nFORCE_HTTPS_PATHS = [\n    '/login/',\n    '/admin/',\n    '/api/auth/',\n    '/payment/',\n]\n",[1047,1837,1838,1843,1861,1877,1893,1900,1904,1933,1937,1950,1960,1965,1989,2005,2038,2068,2072,2090,2095,2115,2133,2151,2156,2175,2179,2184,2196,2217,2221,2229,2233,2251,2261,2266,2272,2318,2326,2331,2337,2376,2383,2388,2394,2420,2425,2443,2453,2458,2464,2508,2536,2577,2597,2603,2608,2614,2657,2662,2677,2682,2704,2714,2719,2725,2750,2775,2781,2806,2823,2828,2853,2867,2872,2896,2901,2907,2933,2958,2983,2988,2994,3016,3042,3047,3065,3075,3104,3114,3145,3153,3181,3189,3194,3200,3211,3224,3230,3235,3240,3246,3255,3270,3285,3290,3295,3304,3316,3328,3340,3352],{"__ignoreMap":1045},[1050,1839,1840],{"class":1052,"line":1053},[1050,1841,1842],{"class":1056},"# middleware.py - Custom HTTPS enforcement middleware\n",[1050,1844,1845,1847,1850,1853,1856,1858],{"class":1052,"line":1060},[1050,1846,1604],{"class":1348},[1050,1848,1849],{"class":1352}," django",[1050,1851,1852],{"class":1371},".",[1050,1854,1855],{"class":1352},"http ",[1050,1857,1349],{"class":1348},[1050,1859,1860],{"class":1352}," HttpResponsePermanentRedirect\n",[1050,1862,1863,1865,1867,1869,1872,1874],{"class":1052,"line":1067},[1050,1864,1604],{"class":1348},[1050,1866,1849],{"class":1352},[1050,1868,1852],{"class":1371},[1050,1870,1871],{"class":1352},"conf ",[1050,1873,1349],{"class":1348},[1050,1875,1876],{"class":1352}," settings\n",[1050,1878,1879,1881,1883,1885,1888,1890],{"class":1052,"line":1073},[1050,1880,1604],{"class":1348},[1050,1882,1849],{"class":1352},[1050,1884,1852],{"class":1371},[1050,1886,1887],{"class":1352},"urls ",[1050,1889,1349],{"class":1348},[1050,1891,1892],{"class":1352}," reverse\n",[1050,1894,1895,1897],{"class":1052,"line":1080},[1050,1896,1349],{"class":1348},[1050,1898,1899],{"class":1352}," logging\n",[1050,1901,1902],{"class":1052,"line":1087},[1050,1903,1064],{"emptyLinePlaceholder":1063},[1050,1905,1906,1909,1912,1915,1917,1921,1924,1926,1929,1931],{"class":1052,"line":1093},[1050,1907,1908],{"class":1352},"logger ",[1050,1910,1911],{"class":1371},"=",[1050,1913,1914],{"class":1352}," logging",[1050,1916,1852],{"class":1371},[1050,1918,1920],{"class":1919},"siWMO","getLogger",[1050,1922,1923],{"class":1371},"(",[1050,1925,1504],{"class":1503},[1050,1927,1928],{"class":1507},"security",[1050,1930,1504],{"class":1503},[1050,1932,1524],{"class":1371},[1050,1934,1935],{"class":1052,"line":1099},[1050,1936,1064],{"emptyLinePlaceholder":1063},[1050,1938,1939,1943,1947],{"class":1052,"line":1104},[1050,1940,1942],{"class":1941},"s5Kfy","class",[1050,1944,1946],{"class":1945},"sD-vU"," EnhancedHTTPSMiddleware",[1050,1948,1949],{"class":1371},":\n",[1050,1951,1952,1955,1958],{"class":1052,"line":1110},[1050,1953,1954],{"class":1076},"    \"\"\"",[1050,1956,1957],{"class":1083},"Enhanced HTTPS enforcement with additional security features",[1050,1959,1077],{"class":1076},[1050,1961,1962],{"class":1052,"line":1115},[1050,1963,1964],{"class":1352},"    \n",[1050,1966,1967,1970,1974,1976,1980,1982,1986],{"class":1052,"line":1120},[1050,1968,1969],{"class":1941},"    def",[1050,1971,1973],{"class":1972},"sJdAF"," __init__",[1050,1975,1923],{"class":1371},[1050,1977,1979],{"class":1978},"sRjD_","self",[1050,1981,1513],{"class":1371},[1050,1983,1985],{"class":1984},"sCyAa"," get_response",[1050,1987,1988],{"class":1371},"):\n",[1050,1990,1991,1994,1996,2000,2002],{"class":1052,"line":1126},[1050,1992,1993],{"class":1367},"        self",[1050,1995,1852],{"class":1371},[1050,1997,1999],{"class":1998},"sBPpx","get_response",[1050,2001,1372],{"class":1371},[1050,2003,2004],{"class":1352}," get_response\n",[1050,2006,2007,2009,2011,2014,2016,2019,2021,2024,2026,2028,2031,2033,2035],{"class":1052,"line":1131},[1050,2008,1993],{"class":1367},[1050,2010,1852],{"class":1371},[1050,2012,2013],{"class":1998},"exempt_paths",[1050,2015,1372],{"class":1371},[1050,2017,2018],{"class":1972}," getattr",[1050,2020,1923],{"class":1371},[1050,2022,2023],{"class":1919},"settings",[1050,2025,1513],{"class":1371},[1050,2027,1516],{"class":1503},[1050,2029,2030],{"class":1507},"HTTPS_EXEMPT_PATHS",[1050,2032,1504],{"class":1503},[1050,2034,1513],{"class":1371},[1050,2036,2037],{"class":1371}," [])\n",[1050,2039,2040,2042,2044,2047,2049,2051,2053,2055,2057,2059,2062,2064,2066],{"class":1052,"line":1136},[1050,2041,1993],{"class":1367},[1050,2043,1852],{"class":1371},[1050,2045,2046],{"class":1998},"force_https_paths",[1050,2048,1372],{"class":1371},[1050,2050,2018],{"class":1972},[1050,2052,1923],{"class":1371},[1050,2054,2023],{"class":1919},[1050,2056,1513],{"class":1371},[1050,2058,1516],{"class":1503},[1050,2060,2061],{"class":1507},"FORCE_HTTPS_PATHS",[1050,2063,1504],{"class":1503},[1050,2065,1513],{"class":1371},[1050,2067,2037],{"class":1371},[1050,2069,2070],{"class":1052,"line":1141},[1050,2071,1964],{"class":1352},[1050,2073,2074,2076,2079,2081,2083,2085,2088],{"class":1052,"line":1146},[1050,2075,1969],{"class":1941},[1050,2077,2078],{"class":1972}," __call__",[1050,2080,1923],{"class":1371},[1050,2082,1979],{"class":1978},[1050,2084,1513],{"class":1371},[1050,2086,2087],{"class":1984}," request",[1050,2089,1988],{"class":1371},[1050,2091,2092],{"class":1052,"line":1152},[1050,2093,2094],{"class":1056},"        # Check if HTTPS should be enforced\n",[1050,2096,2097,2100,2103,2105,2108,2110,2113],{"class":1052,"line":1157},[1050,2098,2099],{"class":1348},"        if",[1050,2101,2102],{"class":1367}," self",[1050,2104,1852],{"class":1371},[1050,2106,2107],{"class":1919},"should_enforce_https",[1050,2109,1923],{"class":1371},[1050,2111,2112],{"class":1919},"request",[1050,2114,1988],{"class":1371},[1050,2116,2117,2120,2123,2125,2127,2130],{"class":1052,"line":1162},[1050,2118,2119],{"class":1348},"            if",[1050,2121,2122],{"class":1615}," not",[1050,2124,2087],{"class":1352},[1050,2126,1852],{"class":1371},[1050,2128,2129],{"class":1919},"is_secure",[1050,2131,2132],{"class":1371},"():\n",[1050,2134,2135,2138,2140,2142,2145,2147,2149],{"class":1052,"line":1168},[1050,2136,2137],{"class":1348},"                return",[1050,2139,2102],{"class":1367},[1050,2141,1852],{"class":1371},[1050,2143,2144],{"class":1919},"redirect_to_https",[1050,2146,1923],{"class":1371},[1050,2148,2112],{"class":1919},[1050,2150,1524],{"class":1371},[1050,2152,2153],{"class":1052,"line":1174},[1050,2154,2155],{"class":1352},"        \n",[1050,2157,2158,2161,2163,2165,2167,2169,2171,2173],{"class":1052,"line":1180},[1050,2159,2160],{"class":1352},"        response ",[1050,2162,1911],{"class":1371},[1050,2164,2102],{"class":1367},[1050,2166,1852],{"class":1371},[1050,2168,1999],{"class":1919},[1050,2170,1923],{"class":1371},[1050,2172,2112],{"class":1919},[1050,2174,1524],{"class":1371},[1050,2176,2177],{"class":1052,"line":1186},[1050,2178,2155],{"class":1352},[1050,2180,2181],{"class":1052,"line":1316},[1050,2182,2183],{"class":1056},"        # Add security headers for HTTPS responses\n",[1050,2185,2186,2188,2190,2192,2194],{"class":1052,"line":1322},[1050,2187,2099],{"class":1348},[1050,2189,2087],{"class":1352},[1050,2191,1852],{"class":1371},[1050,2193,2129],{"class":1919},[1050,2195,2132],{"class":1371},[1050,2197,2198,2201,2203,2206,2208,2210,2212,2215],{"class":1052,"line":1754},[1050,2199,2200],{"class":1367},"            self",[1050,2202,1852],{"class":1371},[1050,2204,2205],{"class":1919},"add_security_headers",[1050,2207,1923],{"class":1371},[1050,2209,2112],{"class":1919},[1050,2211,1513],{"class":1371},[1050,2213,2214],{"class":1919}," response",[1050,2216,1524],{"class":1371},[1050,2218,2219],{"class":1052,"line":1759},[1050,2220,2155],{"class":1352},[1050,2222,2223,2226],{"class":1052,"line":1765},[1050,2224,2225],{"class":1348},"        return",[1050,2227,2228],{"class":1352}," response\n",[1050,2230,2231],{"class":1052,"line":1790},[1050,2232,1964],{"class":1352},[1050,2234,2235,2237,2241,2243,2245,2247,2249],{"class":1052,"line":1795},[1050,2236,1969],{"class":1941},[1050,2238,2240],{"class":2239},"sljsM"," should_enforce_https",[1050,2242,1923],{"class":1371},[1050,2244,1979],{"class":1978},[1050,2246,1513],{"class":1371},[1050,2248,2087],{"class":1984},[1050,2250,1988],{"class":1371},[1050,2252,2253,2256,2259],{"class":1052,"line":1801},[1050,2254,2255],{"class":1076},"        \"\"\"",[1050,2257,2258],{"class":1083},"Determine if HTTPS should be enforced for this request",[1050,2260,1077],{"class":1076},[1050,2262,2264],{"class":1052,"line":2263},33,[1050,2265,2155],{"class":1352},[1050,2267,2269],{"class":1052,"line":2268},34,[1050,2270,2271],{"class":1056},"        # Always enforce for sensitive paths\n",[1050,2273,2275,2277,2280,2282,2284,2286,2289,2291,2294,2296,2298,2301,2304,2307,2310,2312,2314,2316],{"class":1052,"line":2274},35,[1050,2276,2099],{"class":1348},[1050,2278,2279],{"class":1972}," any",[1050,2281,1923],{"class":1371},[1050,2283,2112],{"class":1919},[1050,2285,1852],{"class":1371},[1050,2287,2288],{"class":1998},"path",[1050,2290,1852],{"class":1371},[1050,2292,2293],{"class":1919},"startswith",[1050,2295,1923],{"class":1371},[1050,2297,2288],{"class":1919},[1050,2299,2300],{"class":1371},")",[1050,2302,2303],{"class":1348}," for",[1050,2305,2306],{"class":1919}," path ",[1050,2308,2309],{"class":1348},"in",[1050,2311,2102],{"class":1367},[1050,2313,1852],{"class":1371},[1050,2315,2046],{"class":1998},[1050,2317,1988],{"class":1371},[1050,2319,2321,2324],{"class":1052,"line":2320},36,[1050,2322,2323],{"class":1348},"            return",[1050,2325,1431],{"class":1375},[1050,2327,2329],{"class":1052,"line":2328},37,[1050,2330,2155],{"class":1352},[1050,2332,2334],{"class":1052,"line":2333},38,[1050,2335,2336],{"class":1056},"        # Skip enforcement for exempt paths\n",[1050,2338,2340,2342,2344,2346,2348,2350,2352,2354,2356,2358,2360,2362,2364,2366,2368,2370,2372,2374],{"class":1052,"line":2339},39,[1050,2341,2099],{"class":1348},[1050,2343,2279],{"class":1972},[1050,2345,1923],{"class":1371},[1050,2347,2112],{"class":1919},[1050,2349,1852],{"class":1371},[1050,2351,2288],{"class":1998},[1050,2353,1852],{"class":1371},[1050,2355,2293],{"class":1919},[1050,2357,1923],{"class":1371},[1050,2359,2288],{"class":1919},[1050,2361,2300],{"class":1371},[1050,2363,2303],{"class":1348},[1050,2365,2306],{"class":1919},[1050,2367,2309],{"class":1348},[1050,2369,2102],{"class":1367},[1050,2371,1852],{"class":1371},[1050,2373,2013],{"class":1998},[1050,2375,1988],{"class":1371},[1050,2377,2379,2381],{"class":1052,"line":2378},40,[1050,2380,2323],{"class":1348},[1050,2382,1634],{"class":1375},[1050,2384,2386],{"class":1052,"line":2385},41,[1050,2387,2155],{"class":1352},[1050,2389,2391],{"class":1052,"line":2390},42,[1050,2392,2393],{"class":1056},"        # Check global setting\n",[1050,2395,2397,2399,2401,2403,2405,2407,2409,2411,2413,2415,2418],{"class":1052,"line":2396},43,[1050,2398,2225],{"class":1348},[1050,2400,2018],{"class":1972},[1050,2402,1923],{"class":1371},[1050,2404,2023],{"class":1919},[1050,2406,1513],{"class":1371},[1050,2408,1516],{"class":1503},[1050,2410,1368],{"class":1507},[1050,2412,1504],{"class":1503},[1050,2414,1513],{"class":1371},[1050,2416,2417],{"class":1375}," False",[1050,2419,1524],{"class":1371},[1050,2421,2423],{"class":1052,"line":2422},44,[1050,2424,1964],{"class":1352},[1050,2426,2428,2430,2433,2435,2437,2439,2441],{"class":1052,"line":2427},45,[1050,2429,1969],{"class":1941},[1050,2431,2432],{"class":2239}," redirect_to_https",[1050,2434,1923],{"class":1371},[1050,2436,1979],{"class":1978},[1050,2438,1513],{"class":1371},[1050,2440,2087],{"class":1984},[1050,2442,1988],{"class":1371},[1050,2444,2446,2448,2451],{"class":1052,"line":2445},46,[1050,2447,2255],{"class":1076},[1050,2449,2450],{"class":1083},"Redirect HTTP request to HTTPS",[1050,2452,1077],{"class":1076},[1050,2454,2456],{"class":1052,"line":2455},47,[1050,2457,2155],{"class":1352},[1050,2459,2461],{"class":1052,"line":2460},48,[1050,2462,2463],{"class":1056},"        # Log HTTP access attempt\n",[1050,2465,2467,2470,2472,2475,2477,2480,2483,2487,2489,2491,2493,2496,2499,2501,2505],{"class":1052,"line":2466},49,[1050,2468,2469],{"class":1352},"        logger",[1050,2471,1852],{"class":1371},[1050,2473,2474],{"class":1919},"info",[1050,2476,1923],{"class":1371},[1050,2478,2479],{"class":1941},"f",[1050,2481,2482],{"class":1507},"\"HTTP request redirected to HTTPS: ",[1050,2484,2486],{"class":2485},"s3h35","{",[1050,2488,2112],{"class":1919},[1050,2490,1852],{"class":1371},[1050,2492,2288],{"class":1998},[1050,2494,2495],{"class":2485},"}",[1050,2497,2498],{"class":1507},"\"",[1050,2500,1513],{"class":1371},[1050,2502,2504],{"class":2503},"sqOPj"," extra",[1050,2506,2507],{"class":1371},"={\n",[1050,2509,2511,2514,2517,2519,2522,2524,2526,2529,2531,2533],{"class":1052,"line":2510},50,[1050,2512,2513],{"class":1503},"            '",[1050,2515,2516],{"class":1507},"ip_address",[1050,2518,1504],{"class":1503},[1050,2520,2521],{"class":1371},":",[1050,2523,2102],{"class":1367},[1050,2525,1852],{"class":1371},[1050,2527,2528],{"class":1919},"get_client_ip",[1050,2530,1923],{"class":1371},[1050,2532,2112],{"class":1919},[1050,2534,2535],{"class":1371},"),\n",[1050,2537,2539,2541,2544,2546,2548,2550,2552,2556,2558,2561,2563,2565,2568,2570,2572,2575],{"class":1052,"line":2538},51,[1050,2540,2513],{"class":1503},[1050,2542,2543],{"class":1507},"user_agent",[1050,2545,1504],{"class":1503},[1050,2547,2521],{"class":1371},[1050,2549,2087],{"class":1919},[1050,2551,1852],{"class":1371},[1050,2553,2555],{"class":2554},"sFGJz","META",[1050,2557,1852],{"class":1371},[1050,2559,2560],{"class":1919},"get",[1050,2562,1923],{"class":1371},[1050,2564,1504],{"class":1503},[1050,2566,2567],{"class":1507},"HTTP_USER_AGENT",[1050,2569,1504],{"class":1503},[1050,2571,1513],{"class":1371},[1050,2573,2574],{"class":1503}," ''",[1050,2576,2535],{"class":1371},[1050,2578,2580,2582,2584,2586,2588,2590,2592,2594],{"class":1052,"line":2579},52,[1050,2581,2513],{"class":1503},[1050,2583,2288],{"class":1507},[1050,2585,1504],{"class":1503},[1050,2587,2521],{"class":1371},[1050,2589,2087],{"class":1919},[1050,2591,1852],{"class":1371},[1050,2593,2288],{"class":1998},[1050,2595,2596],{"class":1371},",\n",[1050,2598,2600],{"class":1052,"line":2599},53,[1050,2601,2602],{"class":1371},"        })\n",[1050,2604,2606],{"class":1052,"line":2605},54,[1050,2607,2155],{"class":1352},[1050,2609,2611],{"class":1052,"line":2610},55,[1050,2612,2613],{"class":1056},"        # Build HTTPS URL\n",[1050,2615,2617,2620,2622,2625,2628,2630,2632,2634,2637,2640,2643,2645,2647,2650,2652,2654],{"class":1052,"line":2616},56,[1050,2618,2619],{"class":1352},"        https_url ",[1050,2621,1911],{"class":1371},[1050,2623,2624],{"class":1941}," f",[1050,2626,2627],{"class":1507},"\"https://",[1050,2629,2486],{"class":2485},[1050,2631,2112],{"class":1352},[1050,2633,1852],{"class":1371},[1050,2635,2636],{"class":1919},"get_host",[1050,2638,2639],{"class":1371},"()",[1050,2641,2642],{"class":2485},"}{",[1050,2644,2112],{"class":1352},[1050,2646,1852],{"class":1371},[1050,2648,2649],{"class":1919},"get_full_path",[1050,2651,2639],{"class":1371},[1050,2653,2495],{"class":2485},[1050,2655,2656],{"class":1507},"\"\n",[1050,2658,2660],{"class":1052,"line":2659},57,[1050,2661,2155],{"class":1352},[1050,2663,2665,2667,2670,2672,2675],{"class":1052,"line":2664},58,[1050,2666,2225],{"class":1348},[1050,2668,2669],{"class":1919}," HttpResponsePermanentRedirect",[1050,2671,1923],{"class":1371},[1050,2673,2674],{"class":1919},"https_url",[1050,2676,1524],{"class":1371},[1050,2678,2680],{"class":1052,"line":2679},59,[1050,2681,1964],{"class":1352},[1050,2683,2685,2687,2690,2692,2694,2696,2698,2700,2702],{"class":1052,"line":2684},60,[1050,2686,1969],{"class":1941},[1050,2688,2689],{"class":2239}," add_security_headers",[1050,2691,1923],{"class":1371},[1050,2693,1979],{"class":1978},[1050,2695,1513],{"class":1371},[1050,2697,2087],{"class":1984},[1050,2699,1513],{"class":1371},[1050,2701,2214],{"class":1984},[1050,2703,1988],{"class":1371},[1050,2705,2707,2709,2712],{"class":1052,"line":2706},61,[1050,2708,2255],{"class":1076},[1050,2710,2711],{"class":1083},"Add security headers to HTTPS responses",[1050,2713,1077],{"class":1076},[1050,2715,2717],{"class":1052,"line":2716},62,[1050,2718,2155],{"class":1352},[1050,2720,2722],{"class":1052,"line":2721},63,[1050,2723,2724],{"class":1056},"        # HSTS header\n",[1050,2726,2728,2730,2732,2734,2736,2738,2740,2742,2744,2746,2748],{"class":1052,"line":2727},64,[1050,2729,2099],{"class":1348},[1050,2731,2018],{"class":1972},[1050,2733,1923],{"class":1371},[1050,2735,2023],{"class":1919},[1050,2737,1513],{"class":1371},[1050,2739,1516],{"class":1503},[1050,2741,1454],{"class":1507},[1050,2743,1504],{"class":1503},[1050,2745,1513],{"class":1371},[1050,2747,1659],{"class":1459},[1050,2749,1988],{"class":1371},[1050,2751,2753,2756,2758,2760,2763,2765,2767,2769,2771,2773],{"class":1052,"line":2752},65,[1050,2754,2755],{"class":1352},"            hsts_header ",[1050,2757,1911],{"class":1371},[1050,2759,2624],{"class":1941},[1050,2761,2762],{"class":1507},"\"max-age=",[1050,2764,2486],{"class":2485},[1050,2766,2023],{"class":1352},[1050,2768,1852],{"class":1371},[1050,2770,1454],{"class":2554},[1050,2772,2495],{"class":2485},[1050,2774,2656],{"class":1507},[1050,2776,2778],{"class":1052,"line":2777},66,[1050,2779,2780],{"class":1352},"            \n",[1050,2782,2784,2786,2788,2790,2792,2794,2796,2798,2800,2802,2804],{"class":1052,"line":2783},67,[1050,2785,2119],{"class":1348},[1050,2787,2018],{"class":1972},[1050,2789,1923],{"class":1371},[1050,2791,2023],{"class":1919},[1050,2793,1513],{"class":1371},[1050,2795,1516],{"class":1503},[1050,2797,1468],{"class":1507},[1050,2799,1504],{"class":1503},[1050,2801,1513],{"class":1371},[1050,2803,2417],{"class":1375},[1050,2805,1988],{"class":1371},[1050,2807,2809,2812,2815,2818,2821],{"class":1052,"line":2808},68,[1050,2810,2811],{"class":1352},"                hsts_header ",[1050,2813,2814],{"class":1371},"+=",[1050,2816,2817],{"class":1503}," \"",[1050,2819,2820],{"class":1507},"; includeSubDomains",[1050,2822,2656],{"class":1503},[1050,2824,2826],{"class":1052,"line":2825},69,[1050,2827,2780],{"class":1352},[1050,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849,2851],{"class":1052,"line":2830},70,[1050,2832,2119],{"class":1348},[1050,2834,2018],{"class":1972},[1050,2836,1923],{"class":1371},[1050,2838,2023],{"class":1919},[1050,2840,1513],{"class":1371},[1050,2842,1516],{"class":1503},[1050,2844,1477],{"class":1507},[1050,2846,1504],{"class":1503},[1050,2848,1513],{"class":1371},[1050,2850,2417],{"class":1375},[1050,2852,1988],{"class":1371},[1050,2854,2856,2858,2860,2862,2865],{"class":1052,"line":2855},71,[1050,2857,2811],{"class":1352},[1050,2859,2814],{"class":1371},[1050,2861,2817],{"class":1503},[1050,2863,2864],{"class":1507},"; preload",[1050,2866,2656],{"class":1503},[1050,2868,2870],{"class":1052,"line":2869},72,[1050,2871,2780],{"class":1352},[1050,2873,2875,2878,2881,2883,2886,2888,2891,2893],{"class":1052,"line":2874},73,[1050,2876,2877],{"class":1352},"            response",[1050,2879,2880],{"class":1371},"[",[1050,2882,1504],{"class":1503},[1050,2884,2885],{"class":1507},"Strict-Transport-Security",[1050,2887,1504],{"class":1503},[1050,2889,2890],{"class":1371},"]",[1050,2892,1372],{"class":1371},[1050,2894,2895],{"class":1352}," hsts_header\n",[1050,2897,2899],{"class":1052,"line":2898},74,[1050,2900,2155],{"class":1352},[1050,2902,2904],{"class":1052,"line":2903},75,[1050,2905,2906],{"class":1056},"        # Additional security headers\n",[1050,2908,2910,2913,2915,2917,2920,2922,2924,2926,2928,2931],{"class":1052,"line":2909},76,[1050,2911,2912],{"class":1352},"        response",[1050,2914,2880],{"class":1371},[1050,2916,1504],{"class":1503},[1050,2918,2919],{"class":1507},"X-Content-Type-Options",[1050,2921,1504],{"class":1503},[1050,2923,2890],{"class":1371},[1050,2925,1372],{"class":1371},[1050,2927,1516],{"class":1503},[1050,2929,2930],{"class":1507},"nosniff",[1050,2932,1548],{"class":1503},[1050,2934,2936,2938,2940,2942,2945,2947,2949,2951,2953,2956],{"class":1052,"line":2935},77,[1050,2937,2912],{"class":1352},[1050,2939,2880],{"class":1371},[1050,2941,1504],{"class":1503},[1050,2943,2944],{"class":1507},"X-Frame-Options",[1050,2946,1504],{"class":1503},[1050,2948,2890],{"class":1371},[1050,2950,1372],{"class":1371},[1050,2952,1516],{"class":1503},[1050,2954,2955],{"class":1507},"DENY",[1050,2957,1548],{"class":1503},[1050,2959,2961,2963,2965,2967,2970,2972,2974,2976,2978,2981],{"class":1052,"line":2960},78,[1050,2962,2912],{"class":1352},[1050,2964,2880],{"class":1371},[1050,2966,1504],{"class":1503},[1050,2968,2969],{"class":1507},"X-XSS-Protection",[1050,2971,1504],{"class":1503},[1050,2973,2890],{"class":1371},[1050,2975,1372],{"class":1371},[1050,2977,1516],{"class":1503},[1050,2979,2980],{"class":1507},"1; mode=block",[1050,2982,1548],{"class":1503},[1050,2984,2986],{"class":1052,"line":2985},79,[1050,2987,2155],{"class":1352},[1050,2989,2991],{"class":1052,"line":2990},80,[1050,2992,2993],{"class":1056},"        # Referrer policy\n",[1050,2995,2997,2999,3002,3004,3006,3008,3010,3012,3014],{"class":1052,"line":2996},81,[1050,2998,2099],{"class":1348},[1050,3000,3001],{"class":1972}," hasattr",[1050,3003,1923],{"class":1371},[1050,3005,2023],{"class":1919},[1050,3007,1513],{"class":1371},[1050,3009,1516],{"class":1503},[1050,3011,1538],{"class":1507},[1050,3013,1504],{"class":1503},[1050,3015,1988],{"class":1371},[1050,3017,3019,3021,3023,3025,3028,3030,3032,3034,3037,3039],{"class":1052,"line":3018},82,[1050,3020,2877],{"class":1352},[1050,3022,2880],{"class":1371},[1050,3024,1504],{"class":1503},[1050,3026,3027],{"class":1507},"Referrer-Policy",[1050,3029,1504],{"class":1503},[1050,3031,2890],{"class":1371},[1050,3033,1372],{"class":1371},[1050,3035,3036],{"class":1352}," settings",[1050,3038,1852],{"class":1371},[1050,3040,3041],{"class":2554},"SECURE_REFERRER_POLICY\n",[1050,3043,3045],{"class":1052,"line":3044},83,[1050,3046,1964],{"class":1352},[1050,3048,3050,3052,3055,3057,3059,3061,3063],{"class":1052,"line":3049},84,[1050,3051,1969],{"class":1941},[1050,3053,3054],{"class":2239}," get_client_ip",[1050,3056,1923],{"class":1371},[1050,3058,1979],{"class":1978},[1050,3060,1513],{"class":1371},[1050,3062,2087],{"class":1984},[1050,3064,1988],{"class":1371},[1050,3066,3068,3070,3073],{"class":1052,"line":3067},85,[1050,3069,2255],{"class":1076},[1050,3071,3072],{"class":1083},"Get client IP address",[1050,3074,1077],{"class":1076},[1050,3076,3078,3081,3083,3085,3087,3089,3091,3093,3095,3097,3100,3102],{"class":1052,"line":3077},86,[1050,3079,3080],{"class":1352},"        x_forwarded_for ",[1050,3082,1911],{"class":1371},[1050,3084,2087],{"class":1352},[1050,3086,1852],{"class":1371},[1050,3088,2555],{"class":2554},[1050,3090,1852],{"class":1371},[1050,3092,2560],{"class":1919},[1050,3094,1923],{"class":1371},[1050,3096,1504],{"class":1503},[1050,3098,3099],{"class":1507},"HTTP_X_FORWARDED_FOR",[1050,3101,1504],{"class":1503},[1050,3103,1524],{"class":1371},[1050,3105,3107,3109,3112],{"class":1052,"line":3106},87,[1050,3108,2099],{"class":1348},[1050,3110,3111],{"class":1352}," x_forwarded_for",[1050,3113,1949],{"class":1371},[1050,3115,3117,3120,3122,3124,3126,3129,3131,3133,3135,3137,3140,3143],{"class":1052,"line":3116},88,[1050,3118,3119],{"class":1352},"            ip ",[1050,3121,1911],{"class":1371},[1050,3123,3111],{"class":1352},[1050,3125,1852],{"class":1371},[1050,3127,3128],{"class":1919},"split",[1050,3130,1923],{"class":1371},[1050,3132,1504],{"class":1503},[1050,3134,1513],{"class":1507},[1050,3136,1504],{"class":1503},[1050,3138,3139],{"class":1371},")[",[1050,3141,3142],{"class":1459},"0",[1050,3144,1828],{"class":1371},[1050,3146,3148,3151],{"class":1052,"line":3147},89,[1050,3149,3150],{"class":1348},"        else",[1050,3152,1949],{"class":1371},[1050,3154,3156,3158,3160,3162,3164,3166,3168,3170,3172,3174,3177,3179],{"class":1052,"line":3155},90,[1050,3157,3119],{"class":1352},[1050,3159,1911],{"class":1371},[1050,3161,2087],{"class":1352},[1050,3163,1852],{"class":1371},[1050,3165,2555],{"class":2554},[1050,3167,1852],{"class":1371},[1050,3169,2560],{"class":1919},[1050,3171,1923],{"class":1371},[1050,3173,1504],{"class":1503},[1050,3175,3176],{"class":1507},"REMOTE_ADDR",[1050,3178,1504],{"class":1503},[1050,3180,1524],{"class":1371},[1050,3182,3184,3186],{"class":1052,"line":3183},91,[1050,3185,2225],{"class":1348},[1050,3187,3188],{"class":1352}," ip\n",[1050,3190,3192],{"class":1052,"line":3191},92,[1050,3193,1064],{"emptyLinePlaceholder":1063},[1050,3195,3197],{"class":1052,"line":3196},93,[1050,3198,3199],{"class":1056},"# settings.py - Configuration for custom middleware\n",[1050,3201,3203,3206,3208],{"class":1052,"line":3202},94,[1050,3204,3205],{"class":1367},"MIDDLEWARE",[1050,3207,1372],{"class":1371},[1050,3209,3210],{"class":1371}," [\n",[1050,3212,3214,3217,3220,3222],{"class":1052,"line":3213},95,[1050,3215,3216],{"class":1503},"    '",[1050,3218,3219],{"class":1507},"myapp.middleware.EnhancedHTTPSMiddleware",[1050,3221,1504],{"class":1503},[1050,3223,2596],{"class":1371},[1050,3225,3227],{"class":1052,"line":3226},96,[1050,3228,3229],{"class":1056},"    # ... other middleware\n",[1050,3231,3233],{"class":1052,"line":3232},97,[1050,3234,1828],{"class":1371},[1050,3236,3238],{"class":1052,"line":3237},98,[1050,3239,1064],{"emptyLinePlaceholder":1063},[1050,3241,3243],{"class":1052,"line":3242},99,[1050,3244,3245],{"class":1056},"# Custom HTTPS settings\n",[1050,3247,3249,3251,3253],{"class":1052,"line":3248},100,[1050,3250,2030],{"class":1367},[1050,3252,1372],{"class":1371},[1050,3254,3210],{"class":1371},[1050,3256,3258,3260,3263,3265,3267],{"class":1052,"line":3257},101,[1050,3259,3216],{"class":1503},[1050,3261,3262],{"class":1507},"/health/",[1050,3264,1504],{"class":1503},[1050,3266,1513],{"class":1371},[1050,3268,3269],{"class":1056},"  # Health check endpoints\n",[1050,3271,3273,3275,3278,3280,3282],{"class":1052,"line":3272},102,[1050,3274,3216],{"class":1503},[1050,3276,3277],{"class":1507},"/status/",[1050,3279,1504],{"class":1503},[1050,3281,1513],{"class":1371},[1050,3283,3284],{"class":1056},"  # Status endpoints\n",[1050,3286,3288],{"class":1052,"line":3287},103,[1050,3289,1828],{"class":1371},[1050,3291,3293],{"class":1052,"line":3292},104,[1050,3294,1064],{"emptyLinePlaceholder":1063},[1050,3296,3298,3300,3302],{"class":1052,"line":3297},105,[1050,3299,2061],{"class":1367},[1050,3301,1372],{"class":1371},[1050,3303,3210],{"class":1371},[1050,3305,3307,3309,3312,3314],{"class":1052,"line":3306},106,[1050,3308,3216],{"class":1503},[1050,3310,3311],{"class":1507},"/login/",[1050,3313,1504],{"class":1503},[1050,3315,2596],{"class":1371},[1050,3317,3319,3321,3324,3326],{"class":1052,"line":3318},107,[1050,3320,3216],{"class":1503},[1050,3322,3323],{"class":1507},"/admin/",[1050,3325,1504],{"class":1503},[1050,3327,2596],{"class":1371},[1050,3329,3331,3333,3336,3338],{"class":1052,"line":3330},108,[1050,3332,3216],{"class":1503},[1050,3334,3335],{"class":1507},"/api/auth/",[1050,3337,1504],{"class":1503},[1050,3339,2596],{"class":1371},[1050,3341,3343,3345,3348,3350],{"class":1052,"line":3342},109,[1050,3344,3216],{"class":1503},[1050,3346,3347],{"class":1507},"/payment/",[1050,3349,1504],{"class":1503},[1050,3351,2596],{"class":1371},[1050,3353,3355],{"class":1052,"line":3354},110,[1050,3356,1828],{"class":1371},[1030,3358,3360],{"id":3359},"ssltls-certificate-management","SSL/TLS Certificate Management",[1035,3362,3364],{"id":3363},"lets-encrypt-integration","Let's Encrypt Integration",[1040,3366,3368],{"className":1042,"code":3367,"language":1044,"meta":1045,"style":1045},"# Certificate management with Let's Encrypt\n# Using certbot for automatic certificate management\n\n# Install certbot\n# pip install certbot certbot-nginx  # or certbot-apache\n\n# Automatic certificate generation and renewal\n\"\"\"\n# Generate certificate\nsudo certbot --nginx -d yourdomain.com -d www.yourdomain.com\n\n# Test renewal\nsudo certbot renew --dry-run\n\n# Automatic renewal (add to crontab)\n0 12 * * * /usr/bin/certbot renew --quiet\n\"\"\"\n\n# Django settings for Let's Encrypt\n# settings.py\nALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']\n\n# ACME challenge handling (for certificate validation)\nACME_CHALLENGE_PATH = '/.well-known/acme-challenge/'\n\n# URL configuration for ACME challenges\n# urls.py\nfrom django.urls import path\nfrom django.views.static import serve\nfrom django.conf import settings\nimport os\n\nurlpatterns = [\n    # ... your URL patterns\n]\n\n# Serve ACME challenge files\nif not settings.DEBUG:\n    urlpatterns += [\n        path('.well-known/acme-challenge/\u003Cpath:path>', \n             serve, \n             {'document_root': '/var/www/html/.well-known/acme-challenge/'}),\n    ]\n",[1047,3369,3370,3375,3380,3384,3389,3394,3398,3403,3407,3412,3417,3421,3426,3431,3435,3440,3445,3449,3453,3458,3463,3487,3491,3496,3510,3514,3519,3524,3539,3560,3574,3580,3584,3593,3598,3602,3606,3611,3627,3636,3655,3664,3688],{"__ignoreMap":1045},[1050,3371,3372],{"class":1052,"line":1053},[1050,3373,3374],{"class":1056},"# Certificate management with Let's Encrypt\n",[1050,3376,3377],{"class":1052,"line":1060},[1050,3378,3379],{"class":1056},"# Using certbot for automatic certificate management\n",[1050,3381,3382],{"class":1052,"line":1067},[1050,3383,1064],{"emptyLinePlaceholder":1063},[1050,3385,3386],{"class":1052,"line":1073},[1050,3387,3388],{"class":1056},"# Install certbot\n",[1050,3390,3391],{"class":1052,"line":1080},[1050,3392,3393],{"class":1056},"# pip install certbot certbot-nginx  # or certbot-apache\n",[1050,3395,3396],{"class":1052,"line":1087},[1050,3397,1064],{"emptyLinePlaceholder":1063},[1050,3399,3400],{"class":1052,"line":1093},[1050,3401,3402],{"class":1056},"# Automatic certificate generation and renewal\n",[1050,3404,3405],{"class":1052,"line":1099},[1050,3406,1077],{"class":1076},[1050,3408,3409],{"class":1052,"line":1104},[1050,3410,3411],{"class":1083},"# Generate certificate\n",[1050,3413,3414],{"class":1052,"line":1110},[1050,3415,3416],{"class":1083},"sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com\n",[1050,3418,3419],{"class":1052,"line":1115},[1050,3420,1064],{"emptyLinePlaceholder":1063},[1050,3422,3423],{"class":1052,"line":1120},[1050,3424,3425],{"class":1083},"# Test renewal\n",[1050,3427,3428],{"class":1052,"line":1126},[1050,3429,3430],{"class":1083},"sudo certbot renew --dry-run\n",[1050,3432,3433],{"class":1052,"line":1131},[1050,3434,1064],{"emptyLinePlaceholder":1063},[1050,3436,3437],{"class":1052,"line":1136},[1050,3438,3439],{"class":1083},"# Automatic renewal (add to crontab)\n",[1050,3441,3442],{"class":1052,"line":1141},[1050,3443,3444],{"class":1083},"0 12 * * * /usr/bin/certbot renew --quiet\n",[1050,3446,3447],{"class":1052,"line":1146},[1050,3448,1077],{"class":1076},[1050,3450,3451],{"class":1052,"line":1152},[1050,3452,1064],{"emptyLinePlaceholder":1063},[1050,3454,3455],{"class":1052,"line":1157},[1050,3456,3457],{"class":1056},"# Django settings for Let's Encrypt\n",[1050,3459,3460],{"class":1052,"line":1162},[1050,3461,3462],{"class":1056},"# settings.py\n",[1050,3464,3465,3467,3469,3471,3473,3475,3477,3479,3481,3483,3485],{"class":1052,"line":1168},[1050,3466,1804],{"class":1367},[1050,3468,1372],{"class":1371},[1050,3470,1809],{"class":1371},[1050,3472,1504],{"class":1503},[1050,3474,1814],{"class":1507},[1050,3476,1504],{"class":1503},[1050,3478,1513],{"class":1371},[1050,3480,1516],{"class":1503},[1050,3482,1823],{"class":1507},[1050,3484,1504],{"class":1503},[1050,3486,1828],{"class":1371},[1050,3488,3489],{"class":1052,"line":1174},[1050,3490,1064],{"emptyLinePlaceholder":1063},[1050,3492,3493],{"class":1052,"line":1180},[1050,3494,3495],{"class":1056},"# ACME challenge handling (for certificate validation)\n",[1050,3497,3498,3501,3503,3505,3508],{"class":1052,"line":1186},[1050,3499,3500],{"class":1367},"ACME_CHALLENGE_PATH",[1050,3502,1372],{"class":1371},[1050,3504,1516],{"class":1503},[1050,3506,3507],{"class":1507},"/.well-known/acme-challenge/",[1050,3509,1548],{"class":1503},[1050,3511,3512],{"class":1052,"line":1316},[1050,3513,1064],{"emptyLinePlaceholder":1063},[1050,3515,3516],{"class":1052,"line":1322},[1050,3517,3518],{"class":1056},"# URL configuration for ACME challenges\n",[1050,3520,3521],{"class":1052,"line":1754},[1050,3522,3523],{"class":1056},"# urls.py\n",[1050,3525,3526,3528,3530,3532,3534,3536],{"class":1052,"line":1759},[1050,3527,1604],{"class":1348},[1050,3529,1849],{"class":1352},[1050,3531,1852],{"class":1371},[1050,3533,1887],{"class":1352},[1050,3535,1349],{"class":1348},[1050,3537,3538],{"class":1352}," path\n",[1050,3540,3541,3543,3545,3547,3550,3552,3555,3557],{"class":1052,"line":1765},[1050,3542,1604],{"class":1348},[1050,3544,1849],{"class":1352},[1050,3546,1852],{"class":1371},[1050,3548,3549],{"class":1352},"views",[1050,3551,1852],{"class":1371},[1050,3553,3554],{"class":1352},"static ",[1050,3556,1349],{"class":1348},[1050,3558,3559],{"class":1352}," serve\n",[1050,3561,3562,3564,3566,3568,3570,3572],{"class":1052,"line":1790},[1050,3563,1604],{"class":1348},[1050,3565,1849],{"class":1352},[1050,3567,1852],{"class":1371},[1050,3569,1871],{"class":1352},[1050,3571,1349],{"class":1348},[1050,3573,1876],{"class":1352},[1050,3575,3576,3578],{"class":1052,"line":1795},[1050,3577,1349],{"class":1348},[1050,3579,1353],{"class":1352},[1050,3581,3582],{"class":1052,"line":1801},[1050,3583,1064],{"emptyLinePlaceholder":1063},[1050,3585,3586,3589,3591],{"class":1052,"line":2263},[1050,3587,3588],{"class":1352},"urlpatterns ",[1050,3590,1911],{"class":1371},[1050,3592,3210],{"class":1371},[1050,3594,3595],{"class":1052,"line":2268},[1050,3596,3597],{"class":1056},"    # ... your URL patterns\n",[1050,3599,3600],{"class":1052,"line":2274},[1050,3601,1828],{"class":1371},[1050,3603,3604],{"class":1052,"line":2320},[1050,3605,1064],{"emptyLinePlaceholder":1063},[1050,3607,3608],{"class":1052,"line":2328},[1050,3609,3610],{"class":1056},"# Serve ACME challenge files\n",[1050,3612,3613,3616,3618,3620,3622,3625],{"class":1052,"line":2333},[1050,3614,3615],{"class":1348},"if",[1050,3617,2122],{"class":1615},[1050,3619,3036],{"class":1352},[1050,3621,1852],{"class":1371},[1050,3623,3624],{"class":2554},"DEBUG",[1050,3626,1949],{"class":1371},[1050,3628,3629,3632,3634],{"class":1052,"line":2339},[1050,3630,3631],{"class":1352},"    urlpatterns ",[1050,3633,2814],{"class":1371},[1050,3635,3210],{"class":1371},[1050,3637,3638,3641,3643,3645,3648,3650,3652],{"class":1052,"line":2378},[1050,3639,3640],{"class":1919},"        path",[1050,3642,1923],{"class":1371},[1050,3644,1504],{"class":1503},[1050,3646,3647],{"class":1507},".well-known/acme-challenge/\u003Cpath:path>",[1050,3649,1504],{"class":1503},[1050,3651,1513],{"class":1371},[1050,3653,3654],{"class":1919}," \n",[1050,3656,3657,3660,3662],{"class":1052,"line":2385},[1050,3658,3659],{"class":1919},"             serve",[1050,3661,1513],{"class":1371},[1050,3663,3654],{"class":1919},[1050,3665,3666,3669,3671,3674,3676,3678,3680,3683,3685],{"class":1052,"line":2390},[1050,3667,3668],{"class":1371},"             {",[1050,3670,1504],{"class":1503},[1050,3672,3673],{"class":1507},"document_root",[1050,3675,1504],{"class":1503},[1050,3677,2521],{"class":1371},[1050,3679,1516],{"class":1503},[1050,3681,3682],{"class":1507},"/var/www/html/.well-known/acme-challenge/",[1050,3684,1504],{"class":1503},[1050,3686,3687],{"class":1371},"}),\n",[1050,3689,3690],{"class":1052,"line":2396},[1050,3691,3692],{"class":1371},"    ]\n",[1035,3694,3696],{"id":3695},"certificate-monitoring","Certificate Monitoring",[1040,3698,3700],{"className":1042,"code":3699,"language":1044,"meta":1045,"style":1045},"# Certificate monitoring and alerting\nimport ssl\nimport socket\nfrom datetime import datetime, timedelta\nfrom django.core.management.base import BaseCommand\nfrom django.core.mail import send_mail\n\nclass Command(BaseCommand):\n    \"\"\"Monitor SSL certificate expiration\"\"\"\n    \n    help = 'Check SSL certificate expiration and send alerts'\n    \n    def add_arguments(self, parser):\n        parser.add_argument('--domain', type=str, help='Domain to check')\n        parser.add_argument('--port', type=int, default=443, help='Port to check')\n        parser.add_argument('--days', type=int, default=30, help='Days before expiration to alert')\n    \n    def handle(self, *args, **options):\n        domain = options['domain'] or 'yourdomain.com'\n        port = options['port']\n        alert_days = options['days']\n        \n        try:\n            # Get certificate information\n            cert_info = self.get_certificate_info(domain, port)\n            \n            # Check expiration\n            expires_in_days = self.check_expiration(cert_info)\n            \n            if expires_in_days \u003C= alert_days:\n                self.send_expiration_alert(domain, expires_in_days, cert_info)\n                self.stdout.write(\n                    self.style.WARNING(\n                        f'Certificate for {domain} expires in {expires_in_days} days'\n                    )\n                )\n            else:\n                self.stdout.write(\n                    self.style.SUCCESS(\n                        f'Certificate for {domain} is valid for {expires_in_days} days'\n                    )\n                )\n        \n        except Exception as e:\n            self.stdout.write(\n                self.style.ERROR(f'Error checking certificate for {domain}: {e}')\n            )\n    \n    def get_certificate_info(self, domain, port):\n        \"\"\"Get SSL certificate information\"\"\"\n        \n        context = ssl.create_default_context()\n        \n        with socket.create_connection((domain, port), timeout=10) as sock:\n            with context.wrap_socket(sock, server_hostname=domain) as ssock:\n                cert = ssock.getpeercert()\n        \n        return cert\n    \n    def check_expiration(self, cert_info):\n        \"\"\"Check certificate expiration\"\"\"\n        \n        # Parse expiration date\n        not_after = cert_info['notAfter']\n        expiry_date = datetime.strptime(not_after, '%b %d %H:%M:%S %Y %Z')\n        \n        # Calculate days until expiration\n        days_until_expiry = (expiry_date - datetime.now()).days\n        \n        return days_until_expiry\n    \n    def send_expiration_alert(self, domain, days_remaining, cert_info):\n        \"\"\"Send certificate expiration alert\"\"\"\n        \n        subject = f'SSL Certificate Expiring Soon: {domain}'\n        \n        message = f\"\"\"\n        The SSL certificate for {domain} will expire in {days_remaining} days.\n        \n        Certificate Details:\n        - Subject: {cert_info.get('subject', 'Unknown')}\n        - Issuer: {cert_info.get('issuer', 'Unknown')}\n        - Expires: {cert_info.get('notAfter', 'Unknown')}\n        \n        Please renew the certificate before it expires to avoid service disruption.\n        \"\"\"\n        \n        send_mail(\n            subject,\n            message,\n            'ssl-monitor@yourdomain.com',\n            ['admin@yourdomain.com'],\n            fail_silently=False,\n        )\n\n# Run certificate monitoring\n# python manage.py check_ssl_certificate --domain yourdomain.com --days 30\n",[1047,3701,3702,3707,3714,3721,3738,3763,3783,3787,3802,3811,3815,3829,3833,3851,3897,3948,3997,4001,4030,4060,4080,4100,4104,4111,4116,4141,4145,4150,4171,4175,4190,4216,4233,4250,4277,4282,4287,4294,4308,4323,4346,4350,4354,4358,4374,4388,4428,4433,4437,4459,4468,4472,4490,4494,4536,4572,4588,4592,4599,4603,4620,4629,4633,4638,4658,4694,4698,4703,4731,4735,4742,4746,4772,4781,4785,4805,4809,4820,4844,4848,4853,4889,4923,4956,4960,4965,4970,4974,4981,4988,4995,5006,5021,5033,5038,5042,5047],{"__ignoreMap":1045},[1050,3703,3704],{"class":1052,"line":1053},[1050,3705,3706],{"class":1056},"# Certificate monitoring and alerting\n",[1050,3708,3709,3711],{"class":1052,"line":1060},[1050,3710,1349],{"class":1348},[1050,3712,3713],{"class":1352}," ssl\n",[1050,3715,3716,3718],{"class":1052,"line":1067},[1050,3717,1349],{"class":1348},[1050,3719,3720],{"class":1352}," socket\n",[1050,3722,3723,3725,3728,3730,3733,3735],{"class":1052,"line":1073},[1050,3724,1604],{"class":1348},[1050,3726,3727],{"class":1352}," datetime ",[1050,3729,1349],{"class":1348},[1050,3731,3732],{"class":1352}," datetime",[1050,3734,1513],{"class":1371},[1050,3736,3737],{"class":1352}," timedelta\n",[1050,3739,3740,3742,3744,3746,3749,3751,3754,3756,3758,3760],{"class":1052,"line":1080},[1050,3741,1604],{"class":1348},[1050,3743,1849],{"class":1352},[1050,3745,1852],{"class":1371},[1050,3747,3748],{"class":1352},"core",[1050,3750,1852],{"class":1371},[1050,3752,3753],{"class":1352},"management",[1050,3755,1852],{"class":1371},[1050,3757,1610],{"class":1352},[1050,3759,1349],{"class":1348},[1050,3761,3762],{"class":1352}," BaseCommand\n",[1050,3764,3765,3767,3769,3771,3773,3775,3778,3780],{"class":1052,"line":1087},[1050,3766,1604],{"class":1348},[1050,3768,1849],{"class":1352},[1050,3770,1852],{"class":1371},[1050,3772,3748],{"class":1352},[1050,3774,1852],{"class":1371},[1050,3776,3777],{"class":1352},"mail ",[1050,3779,1349],{"class":1348},[1050,3781,3782],{"class":1352}," send_mail\n",[1050,3784,3785],{"class":1052,"line":1093},[1050,3786,1064],{"emptyLinePlaceholder":1063},[1050,3788,3789,3791,3794,3796,3800],{"class":1052,"line":1099},[1050,3790,1942],{"class":1941},[1050,3792,3793],{"class":1945}," Command",[1050,3795,1923],{"class":1371},[1050,3797,3799],{"class":3798},"sYn-s","BaseCommand",[1050,3801,1988],{"class":1371},[1050,3803,3804,3806,3809],{"class":1052,"line":1104},[1050,3805,1954],{"class":1076},[1050,3807,3808],{"class":1083},"Monitor SSL certificate expiration",[1050,3810,1077],{"class":1076},[1050,3812,3813],{"class":1052,"line":1110},[1050,3814,1964],{"class":1352},[1050,3816,3817,3820,3822,3824,3827],{"class":1052,"line":1115},[1050,3818,3819],{"class":1972},"    help",[1050,3821,1372],{"class":1371},[1050,3823,1516],{"class":1503},[1050,3825,3826],{"class":1507},"Check SSL certificate expiration and send alerts",[1050,3828,1548],{"class":1503},[1050,3830,3831],{"class":1052,"line":1120},[1050,3832,1964],{"class":1352},[1050,3834,3835,3837,3840,3842,3844,3846,3849],{"class":1052,"line":1126},[1050,3836,1969],{"class":1941},[1050,3838,3839],{"class":2239}," add_arguments",[1050,3841,1923],{"class":1371},[1050,3843,1979],{"class":1978},[1050,3845,1513],{"class":1371},[1050,3847,3848],{"class":1984}," parser",[1050,3850,1988],{"class":1371},[1050,3852,3853,3856,3858,3861,3863,3865,3868,3870,3872,3875,3877,3881,3883,3886,3888,3890,3893,3895],{"class":1052,"line":1131},[1050,3854,3855],{"class":1352},"        parser",[1050,3857,1852],{"class":1371},[1050,3859,3860],{"class":1919},"add_argument",[1050,3862,1923],{"class":1371},[1050,3864,1504],{"class":1503},[1050,3866,3867],{"class":1507},"--domain",[1050,3869,1504],{"class":1503},[1050,3871,1513],{"class":1371},[1050,3873,3874],{"class":2503}," type",[1050,3876,1911],{"class":1371},[1050,3878,3880],{"class":3879},"sa2tF","str",[1050,3882,1513],{"class":1371},[1050,3884,3885],{"class":2503}," help",[1050,3887,1911],{"class":1371},[1050,3889,1504],{"class":1503},[1050,3891,3892],{"class":1507},"Domain to check",[1050,3894,1504],{"class":1503},[1050,3896,1524],{"class":1371},[1050,3898,3899,3901,3903,3905,3907,3909,3912,3914,3916,3918,3920,3923,3925,3928,3930,3933,3935,3937,3939,3941,3944,3946],{"class":1052,"line":1136},[1050,3900,3855],{"class":1352},[1050,3902,1852],{"class":1371},[1050,3904,3860],{"class":1919},[1050,3906,1923],{"class":1371},[1050,3908,1504],{"class":1503},[1050,3910,3911],{"class":1507},"--port",[1050,3913,1504],{"class":1503},[1050,3915,1513],{"class":1371},[1050,3917,3874],{"class":2503},[1050,3919,1911],{"class":1371},[1050,3921,3922],{"class":3879},"int",[1050,3924,1513],{"class":1371},[1050,3926,3927],{"class":2503}," default",[1050,3929,1911],{"class":1371},[1050,3931,3932],{"class":1459},"443",[1050,3934,1513],{"class":1371},[1050,3936,3885],{"class":2503},[1050,3938,1911],{"class":1371},[1050,3940,1504],{"class":1503},[1050,3942,3943],{"class":1507},"Port to check",[1050,3945,1504],{"class":1503},[1050,3947,1524],{"class":1371},[1050,3949,3950,3952,3954,3956,3958,3960,3963,3965,3967,3969,3971,3973,3975,3977,3979,3982,3984,3986,3988,3990,3993,3995],{"class":1052,"line":1141},[1050,3951,3855],{"class":1352},[1050,3953,1852],{"class":1371},[1050,3955,3860],{"class":1919},[1050,3957,1923],{"class":1371},[1050,3959,1504],{"class":1503},[1050,3961,3962],{"class":1507},"--days",[1050,3964,1504],{"class":1503},[1050,3966,1513],{"class":1371},[1050,3968,3874],{"class":2503},[1050,3970,1911],{"class":1371},[1050,3972,3922],{"class":3879},[1050,3974,1513],{"class":1371},[1050,3976,3927],{"class":2503},[1050,3978,1911],{"class":1371},[1050,3980,3981],{"class":1459},"30",[1050,3983,1513],{"class":1371},[1050,3985,3885],{"class":2503},[1050,3987,1911],{"class":1371},[1050,3989,1504],{"class":1503},[1050,3991,3992],{"class":1507},"Days before expiration to alert",[1050,3994,1504],{"class":1503},[1050,3996,1524],{"class":1371},[1050,3998,3999],{"class":1052,"line":1146},[1050,4000,1964],{"class":1352},[1050,4002,4003,4005,4008,4010,4012,4014,4017,4020,4022,4025,4028],{"class":1052,"line":1152},[1050,4004,1969],{"class":1941},[1050,4006,4007],{"class":2239}," handle",[1050,4009,1923],{"class":1371},[1050,4011,1979],{"class":1978},[1050,4013,1513],{"class":1371},[1050,4015,4016],{"class":1615}," *",[1050,4018,4019],{"class":1984},"args",[1050,4021,1513],{"class":1371},[1050,4023,4024],{"class":1615}," **",[1050,4026,4027],{"class":1984},"options",[1050,4029,1988],{"class":1371},[1050,4031,4032,4035,4037,4040,4042,4044,4047,4049,4051,4054,4056,4058],{"class":1052,"line":1157},[1050,4033,4034],{"class":1352},"        domain ",[1050,4036,1911],{"class":1371},[1050,4038,4039],{"class":1352}," options",[1050,4041,2880],{"class":1371},[1050,4043,1504],{"class":1503},[1050,4045,4046],{"class":1507},"domain",[1050,4048,1504],{"class":1503},[1050,4050,2890],{"class":1371},[1050,4052,4053],{"class":1615}," or",[1050,4055,1516],{"class":1503},[1050,4057,1814],{"class":1507},[1050,4059,1548],{"class":1503},[1050,4061,4062,4065,4067,4069,4071,4073,4076,4078],{"class":1052,"line":1162},[1050,4063,4064],{"class":1352},"        port ",[1050,4066,1911],{"class":1371},[1050,4068,4039],{"class":1352},[1050,4070,2880],{"class":1371},[1050,4072,1504],{"class":1503},[1050,4074,4075],{"class":1507},"port",[1050,4077,1504],{"class":1503},[1050,4079,1828],{"class":1371},[1050,4081,4082,4085,4087,4089,4091,4093,4096,4098],{"class":1052,"line":1168},[1050,4083,4084],{"class":1352},"        alert_days ",[1050,4086,1911],{"class":1371},[1050,4088,4039],{"class":1352},[1050,4090,2880],{"class":1371},[1050,4092,1504],{"class":1503},[1050,4094,4095],{"class":1507},"days",[1050,4097,1504],{"class":1503},[1050,4099,1828],{"class":1371},[1050,4101,4102],{"class":1052,"line":1174},[1050,4103,2155],{"class":1352},[1050,4105,4106,4109],{"class":1052,"line":1180},[1050,4107,4108],{"class":1348},"        try",[1050,4110,1949],{"class":1371},[1050,4112,4113],{"class":1052,"line":1186},[1050,4114,4115],{"class":1056},"            # Get certificate information\n",[1050,4117,4118,4121,4123,4125,4127,4130,4132,4134,4136,4139],{"class":1052,"line":1316},[1050,4119,4120],{"class":1352},"            cert_info ",[1050,4122,1911],{"class":1371},[1050,4124,2102],{"class":1367},[1050,4126,1852],{"class":1371},[1050,4128,4129],{"class":1919},"get_certificate_info",[1050,4131,1923],{"class":1371},[1050,4133,4046],{"class":1919},[1050,4135,1513],{"class":1371},[1050,4137,4138],{"class":1919}," port",[1050,4140,1524],{"class":1371},[1050,4142,4143],{"class":1052,"line":1322},[1050,4144,2780],{"class":1352},[1050,4146,4147],{"class":1052,"line":1754},[1050,4148,4149],{"class":1056},"            # Check expiration\n",[1050,4151,4152,4155,4157,4159,4161,4164,4166,4169],{"class":1052,"line":1759},[1050,4153,4154],{"class":1352},"            expires_in_days ",[1050,4156,1911],{"class":1371},[1050,4158,2102],{"class":1367},[1050,4160,1852],{"class":1371},[1050,4162,4163],{"class":1919},"check_expiration",[1050,4165,1923],{"class":1371},[1050,4167,4168],{"class":1919},"cert_info",[1050,4170,1524],{"class":1371},[1050,4172,4173],{"class":1052,"line":1765},[1050,4174,2780],{"class":1352},[1050,4176,4177,4179,4182,4185,4188],{"class":1052,"line":1790},[1050,4178,2119],{"class":1348},[1050,4180,4181],{"class":1352}," expires_in_days ",[1050,4183,4184],{"class":1615},"\u003C=",[1050,4186,4187],{"class":1352}," alert_days",[1050,4189,1949],{"class":1371},[1050,4191,4192,4195,4197,4200,4202,4204,4206,4209,4211,4214],{"class":1052,"line":1795},[1050,4193,4194],{"class":1367},"                self",[1050,4196,1852],{"class":1371},[1050,4198,4199],{"class":1919},"send_expiration_alert",[1050,4201,1923],{"class":1371},[1050,4203,4046],{"class":1919},[1050,4205,1513],{"class":1371},[1050,4207,4208],{"class":1919}," expires_in_days",[1050,4210,1513],{"class":1371},[1050,4212,4213],{"class":1919}," cert_info",[1050,4215,1524],{"class":1371},[1050,4217,4218,4220,4222,4225,4227,4230],{"class":1052,"line":1801},[1050,4219,4194],{"class":1367},[1050,4221,1852],{"class":1371},[1050,4223,4224],{"class":1998},"stdout",[1050,4226,1852],{"class":1371},[1050,4228,4229],{"class":1919},"write",[1050,4231,4232],{"class":1371},"(\n",[1050,4234,4235,4238,4240,4243,4245,4248],{"class":1052,"line":2263},[1050,4236,4237],{"class":1367},"                    self",[1050,4239,1852],{"class":1371},[1050,4241,4242],{"class":1998},"style",[1050,4244,1852],{"class":1371},[1050,4246,4247],{"class":1919},"WARNING",[1050,4249,4232],{"class":1371},[1050,4251,4252,4255,4258,4260,4262,4264,4267,4269,4272,4274],{"class":1052,"line":2268},[1050,4253,4254],{"class":1941},"                        f",[1050,4256,4257],{"class":1507},"'Certificate for ",[1050,4259,2486],{"class":2485},[1050,4261,4046],{"class":1919},[1050,4263,2495],{"class":2485},[1050,4265,4266],{"class":1507}," expires in ",[1050,4268,2486],{"class":2485},[1050,4270,4271],{"class":1919},"expires_in_days",[1050,4273,2495],{"class":2485},[1050,4275,4276],{"class":1507}," days'\n",[1050,4278,4279],{"class":1052,"line":2274},[1050,4280,4281],{"class":1371},"                    )\n",[1050,4283,4284],{"class":1052,"line":2320},[1050,4285,4286],{"class":1371},"                )\n",[1050,4288,4289,4292],{"class":1052,"line":2328},[1050,4290,4291],{"class":1348},"            else",[1050,4293,1949],{"class":1371},[1050,4295,4296,4298,4300,4302,4304,4306],{"class":1052,"line":2333},[1050,4297,4194],{"class":1367},[1050,4299,1852],{"class":1371},[1050,4301,4224],{"class":1998},[1050,4303,1852],{"class":1371},[1050,4305,4229],{"class":1919},[1050,4307,4232],{"class":1371},[1050,4309,4310,4312,4314,4316,4318,4321],{"class":1052,"line":2339},[1050,4311,4237],{"class":1367},[1050,4313,1852],{"class":1371},[1050,4315,4242],{"class":1998},[1050,4317,1852],{"class":1371},[1050,4319,4320],{"class":1919},"SUCCESS",[1050,4322,4232],{"class":1371},[1050,4324,4325,4327,4329,4331,4333,4335,4338,4340,4342,4344],{"class":1052,"line":2378},[1050,4326,4254],{"class":1941},[1050,4328,4257],{"class":1507},[1050,4330,2486],{"class":2485},[1050,4332,4046],{"class":1919},[1050,4334,2495],{"class":2485},[1050,4336,4337],{"class":1507}," is valid for ",[1050,4339,2486],{"class":2485},[1050,4341,4271],{"class":1919},[1050,4343,2495],{"class":2485},[1050,4345,4276],{"class":1507},[1050,4347,4348],{"class":1052,"line":2385},[1050,4349,4281],{"class":1371},[1050,4351,4352],{"class":1052,"line":2390},[1050,4353,4286],{"class":1371},[1050,4355,4356],{"class":1052,"line":2396},[1050,4357,2155],{"class":1352},[1050,4359,4360,4363,4366,4369,4372],{"class":1052,"line":2422},[1050,4361,4362],{"class":1348},"        except",[1050,4364,4365],{"class":3879}," Exception",[1050,4367,4368],{"class":1348}," as",[1050,4370,4371],{"class":1352}," e",[1050,4373,1949],{"class":1371},[1050,4375,4376,4378,4380,4382,4384,4386],{"class":1052,"line":2427},[1050,4377,2200],{"class":1367},[1050,4379,1852],{"class":1371},[1050,4381,4224],{"class":1998},[1050,4383,1852],{"class":1371},[1050,4385,4229],{"class":1919},[1050,4387,4232],{"class":1371},[1050,4389,4390,4392,4394,4396,4398,4401,4403,4405,4408,4410,4412,4414,4417,4419,4422,4424,4426],{"class":1052,"line":2445},[1050,4391,4194],{"class":1367},[1050,4393,1852],{"class":1371},[1050,4395,4242],{"class":1998},[1050,4397,1852],{"class":1371},[1050,4399,4400],{"class":1919},"ERROR",[1050,4402,1923],{"class":1371},[1050,4404,2479],{"class":1941},[1050,4406,4407],{"class":1507},"'Error checking certificate for ",[1050,4409,2486],{"class":2485},[1050,4411,4046],{"class":1919},[1050,4413,2495],{"class":2485},[1050,4415,4416],{"class":1507},": ",[1050,4418,2486],{"class":2485},[1050,4420,4421],{"class":1919},"e",[1050,4423,2495],{"class":2485},[1050,4425,1504],{"class":1507},[1050,4427,1524],{"class":1371},[1050,4429,4430],{"class":1052,"line":2455},[1050,4431,4432],{"class":1371},"            )\n",[1050,4434,4435],{"class":1052,"line":2460},[1050,4436,1964],{"class":1352},[1050,4438,4439,4441,4444,4446,4448,4450,4453,4455,4457],{"class":1052,"line":2466},[1050,4440,1969],{"class":1941},[1050,4442,4443],{"class":2239}," get_certificate_info",[1050,4445,1923],{"class":1371},[1050,4447,1979],{"class":1978},[1050,4449,1513],{"class":1371},[1050,4451,4452],{"class":1984}," domain",[1050,4454,1513],{"class":1371},[1050,4456,4138],{"class":1984},[1050,4458,1988],{"class":1371},[1050,4460,4461,4463,4466],{"class":1052,"line":2510},[1050,4462,2255],{"class":1076},[1050,4464,4465],{"class":1083},"Get SSL certificate information",[1050,4467,1077],{"class":1076},[1050,4469,4470],{"class":1052,"line":2538},[1050,4471,2155],{"class":1352},[1050,4473,4474,4477,4479,4482,4484,4487],{"class":1052,"line":2579},[1050,4475,4476],{"class":1352},"        context ",[1050,4478,1911],{"class":1371},[1050,4480,4481],{"class":1352}," ssl",[1050,4483,1852],{"class":1371},[1050,4485,4486],{"class":1919},"create_default_context",[1050,4488,4489],{"class":1371},"()\n",[1050,4491,4492],{"class":1052,"line":2599},[1050,4493,2155],{"class":1352},[1050,4495,4496,4499,4502,4504,4507,4510,4512,4514,4516,4519,4522,4524,4527,4529,4531,4534],{"class":1052,"line":2605},[1050,4497,4498],{"class":1348},"        with",[1050,4500,4501],{"class":1352}," socket",[1050,4503,1852],{"class":1371},[1050,4505,4506],{"class":1919},"create_connection",[1050,4508,4509],{"class":1371},"((",[1050,4511,4046],{"class":1919},[1050,4513,1513],{"class":1371},[1050,4515,4138],{"class":1919},[1050,4517,4518],{"class":1371},"),",[1050,4520,4521],{"class":2503}," timeout",[1050,4523,1911],{"class":1371},[1050,4525,4526],{"class":1459},"10",[1050,4528,2300],{"class":1371},[1050,4530,4368],{"class":1348},[1050,4532,4533],{"class":1352}," sock",[1050,4535,1949],{"class":1371},[1050,4537,4538,4541,4544,4546,4549,4551,4554,4556,4559,4561,4563,4565,4567,4570],{"class":1052,"line":2610},[1050,4539,4540],{"class":1348},"            with",[1050,4542,4543],{"class":1352}," context",[1050,4545,1852],{"class":1371},[1050,4547,4548],{"class":1919},"wrap_socket",[1050,4550,1923],{"class":1371},[1050,4552,4553],{"class":1919},"sock",[1050,4555,1513],{"class":1371},[1050,4557,4558],{"class":2503}," server_hostname",[1050,4560,1911],{"class":1371},[1050,4562,4046],{"class":1919},[1050,4564,2300],{"class":1371},[1050,4566,4368],{"class":1348},[1050,4568,4569],{"class":1352}," ssock",[1050,4571,1949],{"class":1371},[1050,4573,4574,4577,4579,4581,4583,4586],{"class":1052,"line":2616},[1050,4575,4576],{"class":1352},"                cert ",[1050,4578,1911],{"class":1371},[1050,4580,4569],{"class":1352},[1050,4582,1852],{"class":1371},[1050,4584,4585],{"class":1919},"getpeercert",[1050,4587,4489],{"class":1371},[1050,4589,4590],{"class":1052,"line":2659},[1050,4591,2155],{"class":1352},[1050,4593,4594,4596],{"class":1052,"line":2664},[1050,4595,2225],{"class":1348},[1050,4597,4598],{"class":1352}," cert\n",[1050,4600,4601],{"class":1052,"line":2679},[1050,4602,1964],{"class":1352},[1050,4604,4605,4607,4610,4612,4614,4616,4618],{"class":1052,"line":2684},[1050,4606,1969],{"class":1941},[1050,4608,4609],{"class":2239}," check_expiration",[1050,4611,1923],{"class":1371},[1050,4613,1979],{"class":1978},[1050,4615,1513],{"class":1371},[1050,4617,4213],{"class":1984},[1050,4619,1988],{"class":1371},[1050,4621,4622,4624,4627],{"class":1052,"line":2706},[1050,4623,2255],{"class":1076},[1050,4625,4626],{"class":1083},"Check certificate expiration",[1050,4628,1077],{"class":1076},[1050,4630,4631],{"class":1052,"line":2716},[1050,4632,2155],{"class":1352},[1050,4634,4635],{"class":1052,"line":2721},[1050,4636,4637],{"class":1056},"        # Parse expiration date\n",[1050,4639,4640,4643,4645,4647,4649,4651,4654,4656],{"class":1052,"line":2727},[1050,4641,4642],{"class":1352},"        not_after ",[1050,4644,1911],{"class":1371},[1050,4646,4213],{"class":1352},[1050,4648,2880],{"class":1371},[1050,4650,1504],{"class":1503},[1050,4652,4653],{"class":1507},"notAfter",[1050,4655,1504],{"class":1503},[1050,4657,1828],{"class":1371},[1050,4659,4660,4663,4665,4667,4669,4672,4674,4677,4679,4681,4684,4687,4690,4692],{"class":1052,"line":2752},[1050,4661,4662],{"class":1352},"        expiry_date ",[1050,4664,1911],{"class":1371},[1050,4666,3732],{"class":1352},[1050,4668,1852],{"class":1371},[1050,4670,4671],{"class":1919},"strptime",[1050,4673,1923],{"class":1371},[1050,4675,4676],{"class":1919},"not_after",[1050,4678,1513],{"class":1371},[1050,4680,1516],{"class":1503},[1050,4682,4683],{"class":2485},"%b",[1050,4685,4686],{"class":2485}," %d",[1050,4688,4689],{"class":1507}," %H:%M:%S %Y %Z",[1050,4691,1504],{"class":1503},[1050,4693,1524],{"class":1371},[1050,4695,4696],{"class":1052,"line":2777},[1050,4697,2155],{"class":1352},[1050,4699,4700],{"class":1052,"line":2783},[1050,4701,4702],{"class":1056},"        # Calculate days until expiration\n",[1050,4704,4705,4708,4710,4712,4715,4718,4720,4722,4725,4728],{"class":1052,"line":2808},[1050,4706,4707],{"class":1352},"        days_until_expiry ",[1050,4709,1911],{"class":1371},[1050,4711,1500],{"class":1371},[1050,4713,4714],{"class":1352},"expiry_date ",[1050,4716,4717],{"class":1615},"-",[1050,4719,3732],{"class":1352},[1050,4721,1852],{"class":1371},[1050,4723,4724],{"class":1919},"now",[1050,4726,4727],{"class":1371},"()).",[1050,4729,4730],{"class":1998},"days\n",[1050,4732,4733],{"class":1052,"line":2825},[1050,4734,2155],{"class":1352},[1050,4736,4737,4739],{"class":1052,"line":2830},[1050,4738,2225],{"class":1348},[1050,4740,4741],{"class":1352}," days_until_expiry\n",[1050,4743,4744],{"class":1052,"line":2855},[1050,4745,1964],{"class":1352},[1050,4747,4748,4750,4753,4755,4757,4759,4761,4763,4766,4768,4770],{"class":1052,"line":2869},[1050,4749,1969],{"class":1941},[1050,4751,4752],{"class":2239}," send_expiration_alert",[1050,4754,1923],{"class":1371},[1050,4756,1979],{"class":1978},[1050,4758,1513],{"class":1371},[1050,4760,4452],{"class":1984},[1050,4762,1513],{"class":1371},[1050,4764,4765],{"class":1984}," days_remaining",[1050,4767,1513],{"class":1371},[1050,4769,4213],{"class":1984},[1050,4771,1988],{"class":1371},[1050,4773,4774,4776,4779],{"class":1052,"line":2874},[1050,4775,2255],{"class":1076},[1050,4777,4778],{"class":1083},"Send certificate expiration alert",[1050,4780,1077],{"class":1076},[1050,4782,4783],{"class":1052,"line":2898},[1050,4784,2155],{"class":1352},[1050,4786,4787,4790,4792,4794,4797,4799,4801,4803],{"class":1052,"line":2903},[1050,4788,4789],{"class":1352},"        subject ",[1050,4791,1911],{"class":1371},[1050,4793,2624],{"class":1941},[1050,4795,4796],{"class":1507},"'SSL Certificate Expiring Soon: ",[1050,4798,2486],{"class":2485},[1050,4800,4046],{"class":1352},[1050,4802,2495],{"class":2485},[1050,4804,1548],{"class":1507},[1050,4806,4807],{"class":1052,"line":2909},[1050,4808,2155],{"class":1352},[1050,4810,4811,4814,4816,4818],{"class":1052,"line":2935},[1050,4812,4813],{"class":1352},"        message ",[1050,4815,1911],{"class":1371},[1050,4817,2624],{"class":1941},[1050,4819,1077],{"class":1507},[1050,4821,4822,4825,4827,4829,4831,4834,4836,4839,4841],{"class":1052,"line":2960},[1050,4823,4824],{"class":1507},"        The SSL certificate for ",[1050,4826,2486],{"class":2485},[1050,4828,4046],{"class":1352},[1050,4830,2495],{"class":2485},[1050,4832,4833],{"class":1507}," will expire in ",[1050,4835,2486],{"class":2485},[1050,4837,4838],{"class":1352},"days_remaining",[1050,4840,2495],{"class":2485},[1050,4842,4843],{"class":1507}," days.\n",[1050,4845,4846],{"class":1052,"line":2985},[1050,4847,2155],{"class":1507},[1050,4849,4850],{"class":1052,"line":2990},[1050,4851,4852],{"class":1507},"        Certificate Details:\n",[1050,4854,4855,4858,4860,4862,4864,4866,4868,4870,4873,4875,4877,4879,4882,4884,4886],{"class":1052,"line":2996},[1050,4856,4857],{"class":1507},"        - Subject: ",[1050,4859,2486],{"class":2485},[1050,4861,4168],{"class":1352},[1050,4863,1852],{"class":1371},[1050,4865,2560],{"class":1919},[1050,4867,1923],{"class":1371},[1050,4869,1504],{"class":1503},[1050,4871,4872],{"class":1507},"subject",[1050,4874,1504],{"class":1503},[1050,4876,1513],{"class":1371},[1050,4878,1516],{"class":1503},[1050,4880,4881],{"class":1507},"Unknown",[1050,4883,1504],{"class":1503},[1050,4885,2300],{"class":1371},[1050,4887,4888],{"class":2485},"}\n",[1050,4890,4891,4894,4896,4898,4900,4902,4904,4906,4909,4911,4913,4915,4917,4919,4921],{"class":1052,"line":3018},[1050,4892,4893],{"class":1507},"        - Issuer: ",[1050,4895,2486],{"class":2485},[1050,4897,4168],{"class":1352},[1050,4899,1852],{"class":1371},[1050,4901,2560],{"class":1919},[1050,4903,1923],{"class":1371},[1050,4905,1504],{"class":1503},[1050,4907,4908],{"class":1507},"issuer",[1050,4910,1504],{"class":1503},[1050,4912,1513],{"class":1371},[1050,4914,1516],{"class":1503},[1050,4916,4881],{"class":1507},[1050,4918,1504],{"class":1503},[1050,4920,2300],{"class":1371},[1050,4922,4888],{"class":2485},[1050,4924,4925,4928,4930,4932,4934,4936,4938,4940,4942,4944,4946,4948,4950,4952,4954],{"class":1052,"line":3044},[1050,4926,4927],{"class":1507},"        - Expires: ",[1050,4929,2486],{"class":2485},[1050,4931,4168],{"class":1352},[1050,4933,1852],{"class":1371},[1050,4935,2560],{"class":1919},[1050,4937,1923],{"class":1371},[1050,4939,1504],{"class":1503},[1050,4941,4653],{"class":1507},[1050,4943,1504],{"class":1503},[1050,4945,1513],{"class":1371},[1050,4947,1516],{"class":1503},[1050,4949,4881],{"class":1507},[1050,4951,1504],{"class":1503},[1050,4953,2300],{"class":1371},[1050,4955,4888],{"class":2485},[1050,4957,4958],{"class":1052,"line":3049},[1050,4959,2155],{"class":1507},[1050,4961,4962],{"class":1052,"line":3067},[1050,4963,4964],{"class":1507},"        Please renew the certificate before it expires to avoid service disruption.\n",[1050,4966,4967],{"class":1052,"line":3077},[1050,4968,4969],{"class":1507},"        \"\"\"\n",[1050,4971,4972],{"class":1052,"line":3106},[1050,4973,2155],{"class":1352},[1050,4975,4976,4979],{"class":1052,"line":3116},[1050,4977,4978],{"class":1919},"        send_mail",[1050,4980,4232],{"class":1371},[1050,4982,4983,4986],{"class":1052,"line":3147},[1050,4984,4985],{"class":1919},"            subject",[1050,4987,2596],{"class":1371},[1050,4989,4990,4993],{"class":1052,"line":3155},[1050,4991,4992],{"class":1919},"            message",[1050,4994,2596],{"class":1371},[1050,4996,4997,4999,5002,5004],{"class":1052,"line":3183},[1050,4998,2513],{"class":1503},[1050,5000,5001],{"class":1507},"ssl-monitor@yourdomain.com",[1050,5003,1504],{"class":1503},[1050,5005,2596],{"class":1371},[1050,5007,5008,5011,5013,5016,5018],{"class":1052,"line":3191},[1050,5009,5010],{"class":1371},"            [",[1050,5012,1504],{"class":1503},[1050,5014,5015],{"class":1507},"admin@yourdomain.com",[1050,5017,1504],{"class":1503},[1050,5019,5020],{"class":1371},"],\n",[1050,5022,5023,5026,5028,5031],{"class":1052,"line":3196},[1050,5024,5025],{"class":2503},"            fail_silently",[1050,5027,1911],{"class":1371},[1050,5029,5030],{"class":1375},"False",[1050,5032,2596],{"class":1371},[1050,5034,5035],{"class":1052,"line":3202},[1050,5036,5037],{"class":1371},"        )\n",[1050,5039,5040],{"class":1052,"line":3213},[1050,5041,1064],{"emptyLinePlaceholder":1063},[1050,5043,5044],{"class":1052,"line":3226},[1050,5045,5046],{"class":1056},"# Run certificate monitoring\n",[1050,5048,5049],{"class":1052,"line":3232},[1050,5050,5051],{"class":1056},"# python manage.py check_ssl_certificate --domain yourdomain.com --days 30\n",[1030,5053,5055],{"id":5054},"http-strict-transport-security-hsts","HTTP Strict Transport Security (HSTS)",[1035,5057,5059],{"id":5058},"hsts-configuration","HSTS Configuration",[1040,5061,5063],{"className":1042,"code":5062,"language":1044,"meta":1045,"style":1045},"# settings.py - HSTS configuration\n# HSTS tells browsers to only connect via HTTPS\n\n# Basic HSTS configuration\nSECURE_HSTS_SECONDS = 31536000  # 1 year (recommended minimum)\n\n# Include subdomains in HSTS policy\nSECURE_HSTS_INCLUDE_SUBDOMAINS = True\n\n# Enable HSTS preloading (submit to browser preload lists)\nSECURE_HSTS_PRELOAD = True\n\n# Progressive HSTS deployment\n# Start with shorter duration, then increase\nif DEBUG:\n    SECURE_HSTS_SECONDS = 0  # Disable in development\nelse:\n    # Production HSTS progression:\n    # Week 1: 300 (5 minutes) - for testing\n    # Week 2: 86400 (1 day) - short term\n    # Week 3: 604800 (1 week) - medium term\n    # Week 4+: 31536000 (1 year) - long term\n    SECURE_HSTS_SECONDS = 31536000\n",[1047,5064,5065,5070,5075,5079,5084,5095,5099,5104,5112,5116,5121,5129,5133,5138,5143,5152,5164,5171,5176,5181,5186,5191,5196],{"__ignoreMap":1045},[1050,5066,5067],{"class":1052,"line":1053},[1050,5068,5069],{"class":1056},"# settings.py - HSTS configuration\n",[1050,5071,5072],{"class":1052,"line":1060},[1050,5073,5074],{"class":1056},"# HSTS tells browsers to only connect via HTTPS\n",[1050,5076,5077],{"class":1052,"line":1067},[1050,5078,1064],{"emptyLinePlaceholder":1063},[1050,5080,5081],{"class":1052,"line":1073},[1050,5082,5083],{"class":1056},"# Basic HSTS configuration\n",[1050,5085,5086,5088,5090,5092],{"class":1052,"line":1080},[1050,5087,1454],{"class":1367},[1050,5089,1372],{"class":1371},[1050,5091,1460],{"class":1459},[1050,5093,5094],{"class":1056},"  # 1 year (recommended minimum)\n",[1050,5096,5097],{"class":1052,"line":1087},[1050,5098,1064],{"emptyLinePlaceholder":1063},[1050,5100,5101],{"class":1052,"line":1093},[1050,5102,5103],{"class":1056},"# Include subdomains in HSTS policy\n",[1050,5105,5106,5108,5110],{"class":1052,"line":1099},[1050,5107,1468],{"class":1367},[1050,5109,1372],{"class":1371},[1050,5111,1431],{"class":1375},[1050,5113,5114],{"class":1052,"line":1104},[1050,5115,1064],{"emptyLinePlaceholder":1063},[1050,5117,5118],{"class":1052,"line":1110},[1050,5119,5120],{"class":1056},"# Enable HSTS preloading (submit to browser preload lists)\n",[1050,5122,5123,5125,5127],{"class":1052,"line":1115},[1050,5124,1477],{"class":1367},[1050,5126,1372],{"class":1371},[1050,5128,1431],{"class":1375},[1050,5130,5131],{"class":1052,"line":1120},[1050,5132,1064],{"emptyLinePlaceholder":1063},[1050,5134,5135],{"class":1052,"line":1126},[1050,5136,5137],{"class":1056},"# Progressive HSTS deployment\n",[1050,5139,5140],{"class":1052,"line":1131},[1050,5141,5142],{"class":1056},"# Start with shorter duration, then increase\n",[1050,5144,5145,5147,5150],{"class":1052,"line":1136},[1050,5146,3615],{"class":1348},[1050,5148,5149],{"class":1367}," DEBUG",[1050,5151,1949],{"class":1371},[1050,5153,5154,5157,5159,5161],{"class":1052,"line":1141},[1050,5155,5156],{"class":1367},"    SECURE_HSTS_SECONDS",[1050,5158,1372],{"class":1371},[1050,5160,1659],{"class":1459},[1050,5162,5163],{"class":1056},"  # Disable in development\n",[1050,5165,5166,5169],{"class":1052,"line":1146},[1050,5167,5168],{"class":1348},"else",[1050,5170,1949],{"class":1371},[1050,5172,5173],{"class":1052,"line":1152},[1050,5174,5175],{"class":1056},"    # Production HSTS progression:\n",[1050,5177,5178],{"class":1052,"line":1157},[1050,5179,5180],{"class":1056},"    # Week 1: 300 (5 minutes) - for testing\n",[1050,5182,5183],{"class":1052,"line":1162},[1050,5184,5185],{"class":1056},"    # Week 2: 86400 (1 day) - short term\n",[1050,5187,5188],{"class":1052,"line":1168},[1050,5189,5190],{"class":1056},"    # Week 3: 604800 (1 week) - medium term\n",[1050,5192,5193],{"class":1052,"line":1174},[1050,5194,5195],{"class":1056},"    # Week 4+: 31536000 (1 year) - long term\n",[1050,5197,5198,5200,5202],{"class":1052,"line":1180},[1050,5199,5156],{"class":1367},[1050,5201,1372],{"class":1371},[1050,5203,5204],{"class":1459}," 31536000\n",[1035,5206,5208],{"id":5207},"custom-hsts-implementation","Custom HSTS Implementation",[1040,5210,5212],{"className":1042,"code":5211,"language":1044,"meta":1045,"style":1045},"# middleware.py - Custom HSTS middleware with advanced features\nclass AdvancedHSTSMiddleware:\n    \"\"\"Advanced HSTS middleware with conditional policies\"\"\"\n    \n    def __init__(self, get_response):\n        self.get_response = get_response\n        \n        # HSTS configuration\n        self.hsts_config = {\n            'default': {\n                'max_age': 31536000,  # 1 year\n                'include_subdomains': True,\n                'preload': True\n            },\n            'api': {\n                'max_age': 63072000,  # 2 years (stricter for API)\n                'include_subdomains': True,\n                'preload': True\n            },\n            'admin': {\n                'max_age': 63072000,  # 2 years (stricter for admin)\n                'include_subdomains': True,\n                'preload': True\n            }\n        }\n    \n    def __call__(self, request):\n        response = self.get_response(request)\n        \n        # Only add HSTS header for HTTPS requests\n        if request.is_secure():\n            hsts_header = self.build_hsts_header(request)\n            if hsts_header:\n                response['Strict-Transport-Security'] = hsts_header\n        \n        return response\n    \n    def build_hsts_header(self, request):\n        \"\"\"Build HSTS header based on request path\"\"\"\n        \n        # Determine HSTS policy based on path\n        if request.path.startswith('/api/'):\n            config = self.hsts_config['api']\n        elif request.path.startswith('/admin/'):\n            config = self.hsts_config['admin']\n        else:\n            config = self.hsts_config['default']\n        \n        # Build header\n        header_parts = [f\"max-age={config['max_age']}\"]\n        \n        if config.get('include_subdomains'):\n            header_parts.append('includeSubDomains')\n        \n        if config.get('preload'):\n            header_parts.append('preload')\n        \n        return '; '.join(header_parts)\n\n# HSTS preload list submission\n\"\"\"\nTo submit your domain to HSTS preload lists:\n\n1. Ensure HSTS is properly configured with preload directive\n2. Visit https://hstspreload.org/\n3. Submit your domain\n4. Wait for inclusion in browser preload lists\n\nRequirements for preload:\n- Serve a valid certificate\n- Redirect all HTTP traffic to HTTPS\n- Serve HSTS header with:\n  - max-age of at least 31536000 (1 year)\n  - includeSubDomains directive\n  - preload directive\n\"\"\"\n",[1047,5213,5214,5219,5228,5237,5241,5257,5269,5273,5278,5292,5305,5323,5338,5351,5356,5369,5387,5401,5413,5417,5430,5447,5461,5473,5478,5483,5487,5503,5521,5525,5530,5542,5561,5570,5589,5593,5599,5603,5620,5629,5633,5638,5663,5686,5711,5733,5739,5761,5765,5770,5804,5808,5829,5850,5854,5874,5892,5896,5919,5923,5928,5932,5937,5941,5946,5951,5956,5961,5965,5970,5975,5980,5985,5990,5995,6000],{"__ignoreMap":1045},[1050,5215,5216],{"class":1052,"line":1053},[1050,5217,5218],{"class":1056},"# middleware.py - Custom HSTS middleware with advanced features\n",[1050,5220,5221,5223,5226],{"class":1052,"line":1060},[1050,5222,1942],{"class":1941},[1050,5224,5225],{"class":1945}," AdvancedHSTSMiddleware",[1050,5227,1949],{"class":1371},[1050,5229,5230,5232,5235],{"class":1052,"line":1067},[1050,5231,1954],{"class":1076},[1050,5233,5234],{"class":1083},"Advanced HSTS middleware with conditional policies",[1050,5236,1077],{"class":1076},[1050,5238,5239],{"class":1052,"line":1073},[1050,5240,1964],{"class":1352},[1050,5242,5243,5245,5247,5249,5251,5253,5255],{"class":1052,"line":1080},[1050,5244,1969],{"class":1941},[1050,5246,1973],{"class":1972},[1050,5248,1923],{"class":1371},[1050,5250,1979],{"class":1978},[1050,5252,1513],{"class":1371},[1050,5254,1985],{"class":1984},[1050,5256,1988],{"class":1371},[1050,5258,5259,5261,5263,5265,5267],{"class":1052,"line":1087},[1050,5260,1993],{"class":1367},[1050,5262,1852],{"class":1371},[1050,5264,1999],{"class":1998},[1050,5266,1372],{"class":1371},[1050,5268,2004],{"class":1352},[1050,5270,5271],{"class":1052,"line":1093},[1050,5272,2155],{"class":1352},[1050,5274,5275],{"class":1052,"line":1099},[1050,5276,5277],{"class":1056},"        # HSTS configuration\n",[1050,5279,5280,5282,5284,5287,5289],{"class":1052,"line":1104},[1050,5281,1993],{"class":1367},[1050,5283,1852],{"class":1371},[1050,5285,5286],{"class":1998},"hsts_config",[1050,5288,1372],{"class":1371},[1050,5290,5291],{"class":1371}," {\n",[1050,5293,5294,5296,5299,5301,5303],{"class":1052,"line":1110},[1050,5295,2513],{"class":1503},[1050,5297,5298],{"class":1507},"default",[1050,5300,1504],{"class":1503},[1050,5302,2521],{"class":1371},[1050,5304,5291],{"class":1371},[1050,5306,5307,5310,5313,5315,5317,5319,5321],{"class":1052,"line":1115},[1050,5308,5309],{"class":1503},"                '",[1050,5311,5312],{"class":1507},"max_age",[1050,5314,1504],{"class":1503},[1050,5316,2521],{"class":1371},[1050,5318,1460],{"class":1459},[1050,5320,1513],{"class":1371},[1050,5322,1463],{"class":1056},[1050,5324,5325,5327,5330,5332,5334,5336],{"class":1052,"line":1120},[1050,5326,5309],{"class":1503},[1050,5328,5329],{"class":1507},"include_subdomains",[1050,5331,1504],{"class":1503},[1050,5333,2521],{"class":1371},[1050,5335,1376],{"class":1375},[1050,5337,2596],{"class":1371},[1050,5339,5340,5342,5345,5347,5349],{"class":1052,"line":1126},[1050,5341,5309],{"class":1503},[1050,5343,5344],{"class":1507},"preload",[1050,5346,1504],{"class":1503},[1050,5348,2521],{"class":1371},[1050,5350,1431],{"class":1375},[1050,5352,5353],{"class":1052,"line":1131},[1050,5354,5355],{"class":1371},"            },\n",[1050,5357,5358,5360,5363,5365,5367],{"class":1052,"line":1136},[1050,5359,2513],{"class":1503},[1050,5361,5362],{"class":1507},"api",[1050,5364,1504],{"class":1503},[1050,5366,2521],{"class":1371},[1050,5368,5291],{"class":1371},[1050,5370,5371,5373,5375,5377,5379,5382,5384],{"class":1052,"line":1141},[1050,5372,5309],{"class":1503},[1050,5374,5312],{"class":1507},[1050,5376,1504],{"class":1503},[1050,5378,2521],{"class":1371},[1050,5380,5381],{"class":1459}," 63072000",[1050,5383,1513],{"class":1371},[1050,5385,5386],{"class":1056},"  # 2 years (stricter for API)\n",[1050,5388,5389,5391,5393,5395,5397,5399],{"class":1052,"line":1146},[1050,5390,5309],{"class":1503},[1050,5392,5329],{"class":1507},[1050,5394,1504],{"class":1503},[1050,5396,2521],{"class":1371},[1050,5398,1376],{"class":1375},[1050,5400,2596],{"class":1371},[1050,5402,5403,5405,5407,5409,5411],{"class":1052,"line":1152},[1050,5404,5309],{"class":1503},[1050,5406,5344],{"class":1507},[1050,5408,1504],{"class":1503},[1050,5410,2521],{"class":1371},[1050,5412,1431],{"class":1375},[1050,5414,5415],{"class":1052,"line":1157},[1050,5416,5355],{"class":1371},[1050,5418,5419,5421,5424,5426,5428],{"class":1052,"line":1162},[1050,5420,2513],{"class":1503},[1050,5422,5423],{"class":1507},"admin",[1050,5425,1504],{"class":1503},[1050,5427,2521],{"class":1371},[1050,5429,5291],{"class":1371},[1050,5431,5432,5434,5436,5438,5440,5442,5444],{"class":1052,"line":1168},[1050,5433,5309],{"class":1503},[1050,5435,5312],{"class":1507},[1050,5437,1504],{"class":1503},[1050,5439,2521],{"class":1371},[1050,5441,5381],{"class":1459},[1050,5443,1513],{"class":1371},[1050,5445,5446],{"class":1056},"  # 2 years (stricter for admin)\n",[1050,5448,5449,5451,5453,5455,5457,5459],{"class":1052,"line":1174},[1050,5450,5309],{"class":1503},[1050,5452,5329],{"class":1507},[1050,5454,1504],{"class":1503},[1050,5456,2521],{"class":1371},[1050,5458,1376],{"class":1375},[1050,5460,2596],{"class":1371},[1050,5462,5463,5465,5467,5469,5471],{"class":1052,"line":1180},[1050,5464,5309],{"class":1503},[1050,5466,5344],{"class":1507},[1050,5468,1504],{"class":1503},[1050,5470,2521],{"class":1371},[1050,5472,1431],{"class":1375},[1050,5474,5475],{"class":1052,"line":1186},[1050,5476,5477],{"class":1371},"            }\n",[1050,5479,5480],{"class":1052,"line":1316},[1050,5481,5482],{"class":1371},"        }\n",[1050,5484,5485],{"class":1052,"line":1322},[1050,5486,1964],{"class":1352},[1050,5488,5489,5491,5493,5495,5497,5499,5501],{"class":1052,"line":1754},[1050,5490,1969],{"class":1941},[1050,5492,2078],{"class":1972},[1050,5494,1923],{"class":1371},[1050,5496,1979],{"class":1978},[1050,5498,1513],{"class":1371},[1050,5500,2087],{"class":1984},[1050,5502,1988],{"class":1371},[1050,5504,5505,5507,5509,5511,5513,5515,5517,5519],{"class":1052,"line":1759},[1050,5506,2160],{"class":1352},[1050,5508,1911],{"class":1371},[1050,5510,2102],{"class":1367},[1050,5512,1852],{"class":1371},[1050,5514,1999],{"class":1919},[1050,5516,1923],{"class":1371},[1050,5518,2112],{"class":1919},[1050,5520,1524],{"class":1371},[1050,5522,5523],{"class":1052,"line":1765},[1050,5524,2155],{"class":1352},[1050,5526,5527],{"class":1052,"line":1790},[1050,5528,5529],{"class":1056},"        # Only add HSTS header for HTTPS requests\n",[1050,5531,5532,5534,5536,5538,5540],{"class":1052,"line":1795},[1050,5533,2099],{"class":1348},[1050,5535,2087],{"class":1352},[1050,5537,1852],{"class":1371},[1050,5539,2129],{"class":1919},[1050,5541,2132],{"class":1371},[1050,5543,5544,5546,5548,5550,5552,5555,5557,5559],{"class":1052,"line":1801},[1050,5545,2755],{"class":1352},[1050,5547,1911],{"class":1371},[1050,5549,2102],{"class":1367},[1050,5551,1852],{"class":1371},[1050,5553,5554],{"class":1919},"build_hsts_header",[1050,5556,1923],{"class":1371},[1050,5558,2112],{"class":1919},[1050,5560,1524],{"class":1371},[1050,5562,5563,5565,5568],{"class":1052,"line":2263},[1050,5564,2119],{"class":1348},[1050,5566,5567],{"class":1352}," hsts_header",[1050,5569,1949],{"class":1371},[1050,5571,5572,5575,5577,5579,5581,5583,5585,5587],{"class":1052,"line":2268},[1050,5573,5574],{"class":1352},"                response",[1050,5576,2880],{"class":1371},[1050,5578,1504],{"class":1503},[1050,5580,2885],{"class":1507},[1050,5582,1504],{"class":1503},[1050,5584,2890],{"class":1371},[1050,5586,1372],{"class":1371},[1050,5588,2895],{"class":1352},[1050,5590,5591],{"class":1052,"line":2274},[1050,5592,2155],{"class":1352},[1050,5594,5595,5597],{"class":1052,"line":2320},[1050,5596,2225],{"class":1348},[1050,5598,2228],{"class":1352},[1050,5600,5601],{"class":1052,"line":2328},[1050,5602,1964],{"class":1352},[1050,5604,5605,5607,5610,5612,5614,5616,5618],{"class":1052,"line":2333},[1050,5606,1969],{"class":1941},[1050,5608,5609],{"class":2239}," build_hsts_header",[1050,5611,1923],{"class":1371},[1050,5613,1979],{"class":1978},[1050,5615,1513],{"class":1371},[1050,5617,2087],{"class":1984},[1050,5619,1988],{"class":1371},[1050,5621,5622,5624,5627],{"class":1052,"line":2339},[1050,5623,2255],{"class":1076},[1050,5625,5626],{"class":1083},"Build HSTS header based on request path",[1050,5628,1077],{"class":1076},[1050,5630,5631],{"class":1052,"line":2378},[1050,5632,2155],{"class":1352},[1050,5634,5635],{"class":1052,"line":2385},[1050,5636,5637],{"class":1056},"        # Determine HSTS policy based on path\n",[1050,5639,5640,5642,5644,5646,5648,5650,5652,5654,5656,5659,5661],{"class":1052,"line":2390},[1050,5641,2099],{"class":1348},[1050,5643,2087],{"class":1352},[1050,5645,1852],{"class":1371},[1050,5647,2288],{"class":1998},[1050,5649,1852],{"class":1371},[1050,5651,2293],{"class":1919},[1050,5653,1923],{"class":1371},[1050,5655,1504],{"class":1503},[1050,5657,5658],{"class":1507},"/api/",[1050,5660,1504],{"class":1503},[1050,5662,1988],{"class":1371},[1050,5664,5665,5668,5670,5672,5674,5676,5678,5680,5682,5684],{"class":1052,"line":2396},[1050,5666,5667],{"class":1352},"            config ",[1050,5669,1911],{"class":1371},[1050,5671,2102],{"class":1367},[1050,5673,1852],{"class":1371},[1050,5675,5286],{"class":1998},[1050,5677,2880],{"class":1371},[1050,5679,1504],{"class":1503},[1050,5681,5362],{"class":1507},[1050,5683,1504],{"class":1503},[1050,5685,1828],{"class":1371},[1050,5687,5688,5691,5693,5695,5697,5699,5701,5703,5705,5707,5709],{"class":1052,"line":2422},[1050,5689,5690],{"class":1348},"        elif",[1050,5692,2087],{"class":1352},[1050,5694,1852],{"class":1371},[1050,5696,2288],{"class":1998},[1050,5698,1852],{"class":1371},[1050,5700,2293],{"class":1919},[1050,5702,1923],{"class":1371},[1050,5704,1504],{"class":1503},[1050,5706,3323],{"class":1507},[1050,5708,1504],{"class":1503},[1050,5710,1988],{"class":1371},[1050,5712,5713,5715,5717,5719,5721,5723,5725,5727,5729,5731],{"class":1052,"line":2427},[1050,5714,5667],{"class":1352},[1050,5716,1911],{"class":1371},[1050,5718,2102],{"class":1367},[1050,5720,1852],{"class":1371},[1050,5722,5286],{"class":1998},[1050,5724,2880],{"class":1371},[1050,5726,1504],{"class":1503},[1050,5728,5423],{"class":1507},[1050,5730,1504],{"class":1503},[1050,5732,1828],{"class":1371},[1050,5734,5735,5737],{"class":1052,"line":2445},[1050,5736,3150],{"class":1348},[1050,5738,1949],{"class":1371},[1050,5740,5741,5743,5745,5747,5749,5751,5753,5755,5757,5759],{"class":1052,"line":2455},[1050,5742,5667],{"class":1352},[1050,5744,1911],{"class":1371},[1050,5746,2102],{"class":1367},[1050,5748,1852],{"class":1371},[1050,5750,5286],{"class":1998},[1050,5752,2880],{"class":1371},[1050,5754,1504],{"class":1503},[1050,5756,5298],{"class":1507},[1050,5758,1504],{"class":1503},[1050,5760,1828],{"class":1371},[1050,5762,5763],{"class":1052,"line":2460},[1050,5764,2155],{"class":1352},[1050,5766,5767],{"class":1052,"line":2466},[1050,5768,5769],{"class":1056},"        # Build header\n",[1050,5771,5772,5775,5777,5779,5781,5783,5785,5788,5790,5792,5794,5796,5798,5800,5802],{"class":1052,"line":2510},[1050,5773,5774],{"class":1352},"        header_parts ",[1050,5776,1911],{"class":1371},[1050,5778,1809],{"class":1371},[1050,5780,2479],{"class":1941},[1050,5782,2762],{"class":1507},[1050,5784,2486],{"class":2485},[1050,5786,5787],{"class":1352},"config",[1050,5789,2880],{"class":1371},[1050,5791,1504],{"class":1503},[1050,5793,5312],{"class":1507},[1050,5795,1504],{"class":1503},[1050,5797,2890],{"class":1371},[1050,5799,2495],{"class":2485},[1050,5801,2498],{"class":1507},[1050,5803,1828],{"class":1371},[1050,5805,5806],{"class":1052,"line":2538},[1050,5807,2155],{"class":1352},[1050,5809,5810,5812,5815,5817,5819,5821,5823,5825,5827],{"class":1052,"line":2579},[1050,5811,2099],{"class":1348},[1050,5813,5814],{"class":1352}," config",[1050,5816,1852],{"class":1371},[1050,5818,2560],{"class":1919},[1050,5820,1923],{"class":1371},[1050,5822,1504],{"class":1503},[1050,5824,5329],{"class":1507},[1050,5826,1504],{"class":1503},[1050,5828,1988],{"class":1371},[1050,5830,5831,5834,5836,5839,5841,5843,5846,5848],{"class":1052,"line":2599},[1050,5832,5833],{"class":1352},"            header_parts",[1050,5835,1852],{"class":1371},[1050,5837,5838],{"class":1919},"append",[1050,5840,1923],{"class":1371},[1050,5842,1504],{"class":1503},[1050,5844,5845],{"class":1507},"includeSubDomains",[1050,5847,1504],{"class":1503},[1050,5849,1524],{"class":1371},[1050,5851,5852],{"class":1052,"line":2605},[1050,5853,2155],{"class":1352},[1050,5855,5856,5858,5860,5862,5864,5866,5868,5870,5872],{"class":1052,"line":2610},[1050,5857,2099],{"class":1348},[1050,5859,5814],{"class":1352},[1050,5861,1852],{"class":1371},[1050,5863,2560],{"class":1919},[1050,5865,1923],{"class":1371},[1050,5867,1504],{"class":1503},[1050,5869,5344],{"class":1507},[1050,5871,1504],{"class":1503},[1050,5873,1988],{"class":1371},[1050,5875,5876,5878,5880,5882,5884,5886,5888,5890],{"class":1052,"line":2616},[1050,5877,5833],{"class":1352},[1050,5879,1852],{"class":1371},[1050,5881,5838],{"class":1919},[1050,5883,1923],{"class":1371},[1050,5885,1504],{"class":1503},[1050,5887,5344],{"class":1507},[1050,5889,1504],{"class":1503},[1050,5891,1524],{"class":1371},[1050,5893,5894],{"class":1052,"line":2659},[1050,5895,2155],{"class":1352},[1050,5897,5898,5900,5902,5905,5907,5909,5912,5914,5917],{"class":1052,"line":2664},[1050,5899,2225],{"class":1348},[1050,5901,1516],{"class":1503},[1050,5903,5904],{"class":1507},"; ",[1050,5906,1504],{"class":1503},[1050,5908,1852],{"class":1371},[1050,5910,5911],{"class":1919},"join",[1050,5913,1923],{"class":1371},[1050,5915,5916],{"class":1919},"header_parts",[1050,5918,1524],{"class":1371},[1050,5920,5921],{"class":1052,"line":2679},[1050,5922,1064],{"emptyLinePlaceholder":1063},[1050,5924,5925],{"class":1052,"line":2684},[1050,5926,5927],{"class":1056},"# HSTS preload list submission\n",[1050,5929,5930],{"class":1052,"line":2706},[1050,5931,1077],{"class":1076},[1050,5933,5934],{"class":1052,"line":2716},[1050,5935,5936],{"class":1083},"To submit your domain to HSTS preload lists:\n",[1050,5938,5939],{"class":1052,"line":2721},[1050,5940,1064],{"emptyLinePlaceholder":1063},[1050,5942,5943],{"class":1052,"line":2727},[1050,5944,5945],{"class":1083},"1. Ensure HSTS is properly configured with preload directive\n",[1050,5947,5948],{"class":1052,"line":2752},[1050,5949,5950],{"class":1083},"2. Visit https://hstspreload.org/\n",[1050,5952,5953],{"class":1052,"line":2777},[1050,5954,5955],{"class":1083},"3. Submit your domain\n",[1050,5957,5958],{"class":1052,"line":2783},[1050,5959,5960],{"class":1083},"4. Wait for inclusion in browser preload lists\n",[1050,5962,5963],{"class":1052,"line":2808},[1050,5964,1064],{"emptyLinePlaceholder":1063},[1050,5966,5967],{"class":1052,"line":2825},[1050,5968,5969],{"class":1083},"Requirements for preload:\n",[1050,5971,5972],{"class":1052,"line":2830},[1050,5973,5974],{"class":1083},"- Serve a valid certificate\n",[1050,5976,5977],{"class":1052,"line":2855},[1050,5978,5979],{"class":1083},"- Redirect all HTTP traffic to HTTPS\n",[1050,5981,5982],{"class":1052,"line":2869},[1050,5983,5984],{"class":1083},"- Serve HSTS header with:\n",[1050,5986,5987],{"class":1052,"line":2874},[1050,5988,5989],{"class":1083},"  - max-age of at least 31536000 (1 year)\n",[1050,5991,5992],{"class":1052,"line":2898},[1050,5993,5994],{"class":1083},"  - includeSubDomains directive\n",[1050,5996,5997],{"class":1052,"line":2903},[1050,5998,5999],{"class":1083},"  - preload directive\n",[1050,6001,6002],{"class":1052,"line":2909},[1050,6003,1077],{"class":1076},[1035,6005,6007],{"id":6006},"hsts-monitoring-and-reporting","HSTS Monitoring and Reporting",[1040,6009,6011],{"className":1042,"code":6010,"language":1044,"meta":1045,"style":1045},"# HSTS monitoring and compliance checking\nimport requests\nfrom django.core.management.base import BaseCommand\n\nclass Command(BaseCommand):\n    \"\"\"Check HSTS compliance and configuration\"\"\"\n    \n    help = 'Check HSTS header configuration and compliance'\n    \n    def add_arguments(self, parser):\n        parser.add_argument('--url', type=str, help='URL to check')\n    \n    def handle(self, *args, **options):\n        url = options['url'] or 'https://yourdomain.com'\n        \n        try:\n            # Make HTTPS request\n            response = requests.get(url, timeout=10)\n            \n            # Check HSTS header\n            hsts_header = response.headers.get('Strict-Transport-Security')\n            \n            if hsts_header:\n                self.analyze_hsts_header(hsts_header)\n            else:\n                self.stdout.write(\n                    self.style.ERROR('HSTS header not found')\n                )\n            \n            # Check other security headers\n            self.check_security_headers(response.headers)\n            \n        except Exception as e:\n            self.stdout.write(\n                self.style.ERROR(f'Error checking HSTS: {e}')\n            )\n    \n    def analyze_hsts_header(self, hsts_header):\n        \"\"\"Analyze HSTS header configuration\"\"\"\n        \n        self.stdout.write(f'HSTS Header: {hsts_header}')\n        \n        # Parse header components\n        components = [comp.strip() for comp in hsts_header.split(';')]\n        \n        max_age = None\n        include_subdomains = False\n        preload = False\n        \n        for component in components:\n            if component.startswith('max-age='):\n                max_age = int(component.split('=')[1])\n            elif component == 'includeSubDomains':\n                include_subdomains = True\n            elif component == 'preload':\n                preload = True\n        \n        # Analyze configuration\n        if max_age:\n            if max_age >= 31536000:  # 1 year\n                self.stdout.write(\n                    self.style.SUCCESS(f'✓ Max-age is sufficient: {max_age} seconds')\n                )\n            else:\n                self.stdout.write(\n                    self.style.WARNING(f'⚠ Max-age is low: {max_age} seconds (recommend 31536000+)')\n                )\n        \n        if include_subdomains:\n            self.stdout.write(\n                self.style.SUCCESS('✓ includeSubDomains directive present')\n            )\n        else:\n            self.stdout.write(\n                self.style.WARNING('⚠ includeSubDomains directive missing')\n            )\n        \n        if preload:\n            self.stdout.write(\n                self.style.SUCCESS('✓ preload directive present')\n            )\n        else:\n            self.stdout.write(\n                self.style.WARNING('⚠ preload directive missing')\n            )\n    \n    def check_security_headers(self, headers):\n        \"\"\"Check other security headers\"\"\"\n        \n        security_headers = {\n            'X-Content-Type-Options': 'nosniff',\n            'X-Frame-Options': ['DENY', 'SAMEORIGIN'],\n            'X-XSS-Protection': '1; mode=block',\n            'Referrer-Policy': 'strict-origin-when-cross-origin'\n        }\n        \n        for header, expected in security_headers.items():\n            value = headers.get(header)\n            \n            if value:\n                if isinstance(expected, list):\n                    if value in expected:\n                        self.stdout.write(\n                            self.style.SUCCESS(f'✓ {header}: {value}')\n                        )\n                    else:\n                        self.stdout.write(\n                            self.style.WARNING(f'⚠ {header}: {value} (expected one of {expected})')\n                        )\n                else:\n                    if value == expected:\n                        self.stdout.write(\n                            self.style.SUCCESS(f'✓ {header}: {value}')\n                        )\n                    else:\n                        self.stdout.write(\n                            self.style.WARNING(f'⚠ {header}: {value} (expected {expected})')\n                        )\n            else:\n                self.stdout.write(\n                    self.style.ERROR(f'✗ {header}: Missing')\n                )\n",[1047,6012,6013,6018,6025,6047,6051,6063,6072,6076,6089,6093,6109,6149,6153,6177,6206,6210,6216,6221,6249,6253,6258,6285,6289,6297,6313,6319,6333,6356,6360,6364,6369,6389,6393,6405,6419,6448,6452,6456,6473,6482,6486,6515,6519,6524,6568,6572,6582,6591,6600,6604,6619,6641,6676,6694,6703,6719,6728,6732,6737,6746,6762,6776,6806,6810,6816,6830,6860,6864,6868,6877,6891,6914,6918,6924,6938,6961,6965,6969,6978,6992,7015,7019,7025,7039,7062,7066,7070,7088,7097,7101,7110,7128,7157,7175,7191,7195,7199,7223,7243,7247,7256,7276,7291,7306,7345,7350,7357,7371,7418,7422,7429,7442,7457,7494,7499,7506,7521,7567,7572,7579,7594,7625],{"__ignoreMap":1045},[1050,6014,6015],{"class":1052,"line":1053},[1050,6016,6017],{"class":1056},"# HSTS monitoring and compliance checking\n",[1050,6019,6020,6022],{"class":1052,"line":1060},[1050,6021,1349],{"class":1348},[1050,6023,6024],{"class":1352}," requests\n",[1050,6026,6027,6029,6031,6033,6035,6037,6039,6041,6043,6045],{"class":1052,"line":1067},[1050,6028,1604],{"class":1348},[1050,6030,1849],{"class":1352},[1050,6032,1852],{"class":1371},[1050,6034,3748],{"class":1352},[1050,6036,1852],{"class":1371},[1050,6038,3753],{"class":1352},[1050,6040,1852],{"class":1371},[1050,6042,1610],{"class":1352},[1050,6044,1349],{"class":1348},[1050,6046,3762],{"class":1352},[1050,6048,6049],{"class":1052,"line":1073},[1050,6050,1064],{"emptyLinePlaceholder":1063},[1050,6052,6053,6055,6057,6059,6061],{"class":1052,"line":1080},[1050,6054,1942],{"class":1941},[1050,6056,3793],{"class":1945},[1050,6058,1923],{"class":1371},[1050,6060,3799],{"class":3798},[1050,6062,1988],{"class":1371},[1050,6064,6065,6067,6070],{"class":1052,"line":1087},[1050,6066,1954],{"class":1076},[1050,6068,6069],{"class":1083},"Check HSTS compliance and configuration",[1050,6071,1077],{"class":1076},[1050,6073,6074],{"class":1052,"line":1093},[1050,6075,1964],{"class":1352},[1050,6077,6078,6080,6082,6084,6087],{"class":1052,"line":1099},[1050,6079,3819],{"class":1972},[1050,6081,1372],{"class":1371},[1050,6083,1516],{"class":1503},[1050,6085,6086],{"class":1507},"Check HSTS header configuration and compliance",[1050,6088,1548],{"class":1503},[1050,6090,6091],{"class":1052,"line":1104},[1050,6092,1964],{"class":1352},[1050,6094,6095,6097,6099,6101,6103,6105,6107],{"class":1052,"line":1110},[1050,6096,1969],{"class":1941},[1050,6098,3839],{"class":2239},[1050,6100,1923],{"class":1371},[1050,6102,1979],{"class":1978},[1050,6104,1513],{"class":1371},[1050,6106,3848],{"class":1984},[1050,6108,1988],{"class":1371},[1050,6110,6111,6113,6115,6117,6119,6121,6124,6126,6128,6130,6132,6134,6136,6138,6140,6142,6145,6147],{"class":1052,"line":1115},[1050,6112,3855],{"class":1352},[1050,6114,1852],{"class":1371},[1050,6116,3860],{"class":1919},[1050,6118,1923],{"class":1371},[1050,6120,1504],{"class":1503},[1050,6122,6123],{"class":1507},"--url",[1050,6125,1504],{"class":1503},[1050,6127,1513],{"class":1371},[1050,6129,3874],{"class":2503},[1050,6131,1911],{"class":1371},[1050,6133,3880],{"class":3879},[1050,6135,1513],{"class":1371},[1050,6137,3885],{"class":2503},[1050,6139,1911],{"class":1371},[1050,6141,1504],{"class":1503},[1050,6143,6144],{"class":1507},"URL to check",[1050,6146,1504],{"class":1503},[1050,6148,1524],{"class":1371},[1050,6150,6151],{"class":1052,"line":1120},[1050,6152,1964],{"class":1352},[1050,6154,6155,6157,6159,6161,6163,6165,6167,6169,6171,6173,6175],{"class":1052,"line":1126},[1050,6156,1969],{"class":1941},[1050,6158,4007],{"class":2239},[1050,6160,1923],{"class":1371},[1050,6162,1979],{"class":1978},[1050,6164,1513],{"class":1371},[1050,6166,4016],{"class":1615},[1050,6168,4019],{"class":1984},[1050,6170,1513],{"class":1371},[1050,6172,4024],{"class":1615},[1050,6174,4027],{"class":1984},[1050,6176,1988],{"class":1371},[1050,6178,6179,6182,6184,6186,6188,6190,6193,6195,6197,6199,6201,6204],{"class":1052,"line":1131},[1050,6180,6181],{"class":1352},"        url ",[1050,6183,1911],{"class":1371},[1050,6185,4039],{"class":1352},[1050,6187,2880],{"class":1371},[1050,6189,1504],{"class":1503},[1050,6191,6192],{"class":1507},"url",[1050,6194,1504],{"class":1503},[1050,6196,2890],{"class":1371},[1050,6198,4053],{"class":1615},[1050,6200,1516],{"class":1503},[1050,6202,6203],{"class":1507},"https://yourdomain.com",[1050,6205,1548],{"class":1503},[1050,6207,6208],{"class":1052,"line":1136},[1050,6209,2155],{"class":1352},[1050,6211,6212,6214],{"class":1052,"line":1141},[1050,6213,4108],{"class":1348},[1050,6215,1949],{"class":1371},[1050,6217,6218],{"class":1052,"line":1146},[1050,6219,6220],{"class":1056},"            # Make HTTPS request\n",[1050,6222,6223,6226,6228,6231,6233,6235,6237,6239,6241,6243,6245,6247],{"class":1052,"line":1152},[1050,6224,6225],{"class":1352},"            response ",[1050,6227,1911],{"class":1371},[1050,6229,6230],{"class":1352}," requests",[1050,6232,1852],{"class":1371},[1050,6234,2560],{"class":1919},[1050,6236,1923],{"class":1371},[1050,6238,6192],{"class":1919},[1050,6240,1513],{"class":1371},[1050,6242,4521],{"class":2503},[1050,6244,1911],{"class":1371},[1050,6246,4526],{"class":1459},[1050,6248,1524],{"class":1371},[1050,6250,6251],{"class":1052,"line":1157},[1050,6252,2780],{"class":1352},[1050,6254,6255],{"class":1052,"line":1162},[1050,6256,6257],{"class":1056},"            # Check HSTS header\n",[1050,6259,6260,6262,6264,6266,6268,6271,6273,6275,6277,6279,6281,6283],{"class":1052,"line":1168},[1050,6261,2755],{"class":1352},[1050,6263,1911],{"class":1371},[1050,6265,2214],{"class":1352},[1050,6267,1852],{"class":1371},[1050,6269,6270],{"class":1998},"headers",[1050,6272,1852],{"class":1371},[1050,6274,2560],{"class":1919},[1050,6276,1923],{"class":1371},[1050,6278,1504],{"class":1503},[1050,6280,2885],{"class":1507},[1050,6282,1504],{"class":1503},[1050,6284,1524],{"class":1371},[1050,6286,6287],{"class":1052,"line":1174},[1050,6288,2780],{"class":1352},[1050,6290,6291,6293,6295],{"class":1052,"line":1180},[1050,6292,2119],{"class":1348},[1050,6294,5567],{"class":1352},[1050,6296,1949],{"class":1371},[1050,6298,6299,6301,6303,6306,6308,6311],{"class":1052,"line":1186},[1050,6300,4194],{"class":1367},[1050,6302,1852],{"class":1371},[1050,6304,6305],{"class":1919},"analyze_hsts_header",[1050,6307,1923],{"class":1371},[1050,6309,6310],{"class":1919},"hsts_header",[1050,6312,1524],{"class":1371},[1050,6314,6315,6317],{"class":1052,"line":1316},[1050,6316,4291],{"class":1348},[1050,6318,1949],{"class":1371},[1050,6320,6321,6323,6325,6327,6329,6331],{"class":1052,"line":1322},[1050,6322,4194],{"class":1367},[1050,6324,1852],{"class":1371},[1050,6326,4224],{"class":1998},[1050,6328,1852],{"class":1371},[1050,6330,4229],{"class":1919},[1050,6332,4232],{"class":1371},[1050,6334,6335,6337,6339,6341,6343,6345,6347,6349,6352,6354],{"class":1052,"line":1754},[1050,6336,4237],{"class":1367},[1050,6338,1852],{"class":1371},[1050,6340,4242],{"class":1998},[1050,6342,1852],{"class":1371},[1050,6344,4400],{"class":1919},[1050,6346,1923],{"class":1371},[1050,6348,1504],{"class":1503},[1050,6350,6351],{"class":1507},"HSTS header not found",[1050,6353,1504],{"class":1503},[1050,6355,1524],{"class":1371},[1050,6357,6358],{"class":1052,"line":1759},[1050,6359,4286],{"class":1371},[1050,6361,6362],{"class":1052,"line":1765},[1050,6363,2780],{"class":1352},[1050,6365,6366],{"class":1052,"line":1790},[1050,6367,6368],{"class":1056},"            # Check other security headers\n",[1050,6370,6371,6373,6375,6378,6380,6383,6385,6387],{"class":1052,"line":1795},[1050,6372,2200],{"class":1367},[1050,6374,1852],{"class":1371},[1050,6376,6377],{"class":1919},"check_security_headers",[1050,6379,1923],{"class":1371},[1050,6381,6382],{"class":1919},"response",[1050,6384,1852],{"class":1371},[1050,6386,6270],{"class":1998},[1050,6388,1524],{"class":1371},[1050,6390,6391],{"class":1052,"line":1801},[1050,6392,2780],{"class":1352},[1050,6394,6395,6397,6399,6401,6403],{"class":1052,"line":2263},[1050,6396,4362],{"class":1348},[1050,6398,4365],{"class":3879},[1050,6400,4368],{"class":1348},[1050,6402,4371],{"class":1352},[1050,6404,1949],{"class":1371},[1050,6406,6407,6409,6411,6413,6415,6417],{"class":1052,"line":2268},[1050,6408,2200],{"class":1367},[1050,6410,1852],{"class":1371},[1050,6412,4224],{"class":1998},[1050,6414,1852],{"class":1371},[1050,6416,4229],{"class":1919},[1050,6418,4232],{"class":1371},[1050,6420,6421,6423,6425,6427,6429,6431,6433,6435,6438,6440,6442,6444,6446],{"class":1052,"line":2274},[1050,6422,4194],{"class":1367},[1050,6424,1852],{"class":1371},[1050,6426,4242],{"class":1998},[1050,6428,1852],{"class":1371},[1050,6430,4400],{"class":1919},[1050,6432,1923],{"class":1371},[1050,6434,2479],{"class":1941},[1050,6436,6437],{"class":1507},"'Error checking HSTS: ",[1050,6439,2486],{"class":2485},[1050,6441,4421],{"class":1919},[1050,6443,2495],{"class":2485},[1050,6445,1504],{"class":1507},[1050,6447,1524],{"class":1371},[1050,6449,6450],{"class":1052,"line":2320},[1050,6451,4432],{"class":1371},[1050,6453,6454],{"class":1052,"line":2328},[1050,6455,1964],{"class":1352},[1050,6457,6458,6460,6463,6465,6467,6469,6471],{"class":1052,"line":2333},[1050,6459,1969],{"class":1941},[1050,6461,6462],{"class":2239}," analyze_hsts_header",[1050,6464,1923],{"class":1371},[1050,6466,1979],{"class":1978},[1050,6468,1513],{"class":1371},[1050,6470,5567],{"class":1984},[1050,6472,1988],{"class":1371},[1050,6474,6475,6477,6480],{"class":1052,"line":2339},[1050,6476,2255],{"class":1076},[1050,6478,6479],{"class":1083},"Analyze HSTS header configuration",[1050,6481,1077],{"class":1076},[1050,6483,6484],{"class":1052,"line":2378},[1050,6485,2155],{"class":1352},[1050,6487,6488,6490,6492,6494,6496,6498,6500,6502,6505,6507,6509,6511,6513],{"class":1052,"line":2385},[1050,6489,1993],{"class":1367},[1050,6491,1852],{"class":1371},[1050,6493,4224],{"class":1998},[1050,6495,1852],{"class":1371},[1050,6497,4229],{"class":1919},[1050,6499,1923],{"class":1371},[1050,6501,2479],{"class":1941},[1050,6503,6504],{"class":1507},"'HSTS Header: ",[1050,6506,2486],{"class":2485},[1050,6508,6310],{"class":1919},[1050,6510,2495],{"class":2485},[1050,6512,1504],{"class":1507},[1050,6514,1524],{"class":1371},[1050,6516,6517],{"class":1052,"line":2390},[1050,6518,2155],{"class":1352},[1050,6520,6521],{"class":1052,"line":2396},[1050,6522,6523],{"class":1056},"        # Parse header components\n",[1050,6525,6526,6529,6531,6533,6536,6538,6541,6543,6545,6548,6550,6552,6554,6556,6558,6560,6563,6565],{"class":1052,"line":2422},[1050,6527,6528],{"class":1352},"        components ",[1050,6530,1911],{"class":1371},[1050,6532,1809],{"class":1371},[1050,6534,6535],{"class":1352},"comp",[1050,6537,1852],{"class":1371},[1050,6539,6540],{"class":1919},"strip",[1050,6542,2639],{"class":1371},[1050,6544,2303],{"class":1348},[1050,6546,6547],{"class":1352}," comp ",[1050,6549,2309],{"class":1348},[1050,6551,5567],{"class":1352},[1050,6553,1852],{"class":1371},[1050,6555,3128],{"class":1919},[1050,6557,1923],{"class":1371},[1050,6559,1504],{"class":1503},[1050,6561,6562],{"class":1507},";",[1050,6564,1504],{"class":1503},[1050,6566,6567],{"class":1371},")]\n",[1050,6569,6570],{"class":1052,"line":2427},[1050,6571,2155],{"class":1352},[1050,6573,6574,6577,6579],{"class":1052,"line":2445},[1050,6575,6576],{"class":1352},"        max_age ",[1050,6578,1911],{"class":1371},[1050,6580,6581],{"class":1375}," None\n",[1050,6583,6584,6587,6589],{"class":1052,"line":2455},[1050,6585,6586],{"class":1352},"        include_subdomains ",[1050,6588,1911],{"class":1371},[1050,6590,1634],{"class":1375},[1050,6592,6593,6596,6598],{"class":1052,"line":2460},[1050,6594,6595],{"class":1352},"        preload ",[1050,6597,1911],{"class":1371},[1050,6599,1634],{"class":1375},[1050,6601,6602],{"class":1052,"line":2466},[1050,6603,2155],{"class":1352},[1050,6605,6606,6609,6612,6614,6617],{"class":1052,"line":2510},[1050,6607,6608],{"class":1348},"        for",[1050,6610,6611],{"class":1352}," component ",[1050,6613,2309],{"class":1348},[1050,6615,6616],{"class":1352}," components",[1050,6618,1949],{"class":1371},[1050,6620,6621,6623,6626,6628,6630,6632,6634,6637,6639],{"class":1052,"line":2538},[1050,6622,2119],{"class":1348},[1050,6624,6625],{"class":1352}," component",[1050,6627,1852],{"class":1371},[1050,6629,2293],{"class":1919},[1050,6631,1923],{"class":1371},[1050,6633,1504],{"class":1503},[1050,6635,6636],{"class":1507},"max-age=",[1050,6638,1504],{"class":1503},[1050,6640,1988],{"class":1371},[1050,6642,6643,6646,6648,6651,6653,6656,6658,6660,6662,6664,6666,6668,6670,6673],{"class":1052,"line":2579},[1050,6644,6645],{"class":1352},"                max_age ",[1050,6647,1911],{"class":1371},[1050,6649,6650],{"class":3879}," int",[1050,6652,1923],{"class":1371},[1050,6654,6655],{"class":1919},"component",[1050,6657,1852],{"class":1371},[1050,6659,3128],{"class":1919},[1050,6661,1923],{"class":1371},[1050,6663,1504],{"class":1503},[1050,6665,1911],{"class":1507},[1050,6667,1504],{"class":1503},[1050,6669,3139],{"class":1371},[1050,6671,6672],{"class":1459},"1",[1050,6674,6675],{"class":1371},"])\n",[1050,6677,6678,6681,6683,6686,6688,6690,6692],{"class":1052,"line":2599},[1050,6679,6680],{"class":1348},"            elif",[1050,6682,6611],{"class":1352},[1050,6684,6685],{"class":1615},"==",[1050,6687,1516],{"class":1503},[1050,6689,5845],{"class":1507},[1050,6691,1504],{"class":1503},[1050,6693,1949],{"class":1371},[1050,6695,6696,6699,6701],{"class":1052,"line":2605},[1050,6697,6698],{"class":1352},"                include_subdomains ",[1050,6700,1911],{"class":1371},[1050,6702,1431],{"class":1375},[1050,6704,6705,6707,6709,6711,6713,6715,6717],{"class":1052,"line":2610},[1050,6706,6680],{"class":1348},[1050,6708,6611],{"class":1352},[1050,6710,6685],{"class":1615},[1050,6712,1516],{"class":1503},[1050,6714,5344],{"class":1507},[1050,6716,1504],{"class":1503},[1050,6718,1949],{"class":1371},[1050,6720,6721,6724,6726],{"class":1052,"line":2616},[1050,6722,6723],{"class":1352},"                preload ",[1050,6725,1911],{"class":1371},[1050,6727,1431],{"class":1375},[1050,6729,6730],{"class":1052,"line":2659},[1050,6731,2155],{"class":1352},[1050,6733,6734],{"class":1052,"line":2664},[1050,6735,6736],{"class":1056},"        # Analyze configuration\n",[1050,6738,6739,6741,6744],{"class":1052,"line":2679},[1050,6740,2099],{"class":1348},[1050,6742,6743],{"class":1352}," max_age",[1050,6745,1949],{"class":1371},[1050,6747,6748,6750,6753,6756,6758,6760],{"class":1052,"line":2684},[1050,6749,2119],{"class":1348},[1050,6751,6752],{"class":1352}," max_age ",[1050,6754,6755],{"class":1615},">=",[1050,6757,1460],{"class":1459},[1050,6759,2521],{"class":1371},[1050,6761,1463],{"class":1056},[1050,6763,6764,6766,6768,6770,6772,6774],{"class":1052,"line":2706},[1050,6765,4194],{"class":1367},[1050,6767,1852],{"class":1371},[1050,6769,4224],{"class":1998},[1050,6771,1852],{"class":1371},[1050,6773,4229],{"class":1919},[1050,6775,4232],{"class":1371},[1050,6777,6778,6780,6782,6784,6786,6788,6790,6792,6795,6797,6799,6801,6804],{"class":1052,"line":2716},[1050,6779,4237],{"class":1367},[1050,6781,1852],{"class":1371},[1050,6783,4242],{"class":1998},[1050,6785,1852],{"class":1371},[1050,6787,4320],{"class":1919},[1050,6789,1923],{"class":1371},[1050,6791,2479],{"class":1941},[1050,6793,6794],{"class":1507},"'✓ Max-age is sufficient: ",[1050,6796,2486],{"class":2485},[1050,6798,5312],{"class":1919},[1050,6800,2495],{"class":2485},[1050,6802,6803],{"class":1507}," seconds'",[1050,6805,1524],{"class":1371},[1050,6807,6808],{"class":1052,"line":2721},[1050,6809,4286],{"class":1371},[1050,6811,6812,6814],{"class":1052,"line":2727},[1050,6813,4291],{"class":1348},[1050,6815,1949],{"class":1371},[1050,6817,6818,6820,6822,6824,6826,6828],{"class":1052,"line":2752},[1050,6819,4194],{"class":1367},[1050,6821,1852],{"class":1371},[1050,6823,4224],{"class":1998},[1050,6825,1852],{"class":1371},[1050,6827,4229],{"class":1919},[1050,6829,4232],{"class":1371},[1050,6831,6832,6834,6836,6838,6840,6842,6844,6846,6849,6851,6853,6855,6858],{"class":1052,"line":2777},[1050,6833,4237],{"class":1367},[1050,6835,1852],{"class":1371},[1050,6837,4242],{"class":1998},[1050,6839,1852],{"class":1371},[1050,6841,4247],{"class":1919},[1050,6843,1923],{"class":1371},[1050,6845,2479],{"class":1941},[1050,6847,6848],{"class":1507},"'⚠ Max-age is low: ",[1050,6850,2486],{"class":2485},[1050,6852,5312],{"class":1919},[1050,6854,2495],{"class":2485},[1050,6856,6857],{"class":1507}," seconds (recommend 31536000+)'",[1050,6859,1524],{"class":1371},[1050,6861,6862],{"class":1052,"line":2783},[1050,6863,4286],{"class":1371},[1050,6865,6866],{"class":1052,"line":2808},[1050,6867,2155],{"class":1352},[1050,6869,6870,6872,6875],{"class":1052,"line":2825},[1050,6871,2099],{"class":1348},[1050,6873,6874],{"class":1352}," include_subdomains",[1050,6876,1949],{"class":1371},[1050,6878,6879,6881,6883,6885,6887,6889],{"class":1052,"line":2830},[1050,6880,2200],{"class":1367},[1050,6882,1852],{"class":1371},[1050,6884,4224],{"class":1998},[1050,6886,1852],{"class":1371},[1050,6888,4229],{"class":1919},[1050,6890,4232],{"class":1371},[1050,6892,6893,6895,6897,6899,6901,6903,6905,6907,6910,6912],{"class":1052,"line":2855},[1050,6894,4194],{"class":1367},[1050,6896,1852],{"class":1371},[1050,6898,4242],{"class":1998},[1050,6900,1852],{"class":1371},[1050,6902,4320],{"class":1919},[1050,6904,1923],{"class":1371},[1050,6906,1504],{"class":1503},[1050,6908,6909],{"class":1507},"✓ includeSubDomains directive present",[1050,6911,1504],{"class":1503},[1050,6913,1524],{"class":1371},[1050,6915,6916],{"class":1052,"line":2869},[1050,6917,4432],{"class":1371},[1050,6919,6920,6922],{"class":1052,"line":2874},[1050,6921,3150],{"class":1348},[1050,6923,1949],{"class":1371},[1050,6925,6926,6928,6930,6932,6934,6936],{"class":1052,"line":2898},[1050,6927,2200],{"class":1367},[1050,6929,1852],{"class":1371},[1050,6931,4224],{"class":1998},[1050,6933,1852],{"class":1371},[1050,6935,4229],{"class":1919},[1050,6937,4232],{"class":1371},[1050,6939,6940,6942,6944,6946,6948,6950,6952,6954,6957,6959],{"class":1052,"line":2903},[1050,6941,4194],{"class":1367},[1050,6943,1852],{"class":1371},[1050,6945,4242],{"class":1998},[1050,6947,1852],{"class":1371},[1050,6949,4247],{"class":1919},[1050,6951,1923],{"class":1371},[1050,6953,1504],{"class":1503},[1050,6955,6956],{"class":1507},"⚠ includeSubDomains directive missing",[1050,6958,1504],{"class":1503},[1050,6960,1524],{"class":1371},[1050,6962,6963],{"class":1052,"line":2909},[1050,6964,4432],{"class":1371},[1050,6966,6967],{"class":1052,"line":2935},[1050,6968,2155],{"class":1352},[1050,6970,6971,6973,6976],{"class":1052,"line":2960},[1050,6972,2099],{"class":1348},[1050,6974,6975],{"class":1352}," preload",[1050,6977,1949],{"class":1371},[1050,6979,6980,6982,6984,6986,6988,6990],{"class":1052,"line":2985},[1050,6981,2200],{"class":1367},[1050,6983,1852],{"class":1371},[1050,6985,4224],{"class":1998},[1050,6987,1852],{"class":1371},[1050,6989,4229],{"class":1919},[1050,6991,4232],{"class":1371},[1050,6993,6994,6996,6998,7000,7002,7004,7006,7008,7011,7013],{"class":1052,"line":2990},[1050,6995,4194],{"class":1367},[1050,6997,1852],{"class":1371},[1050,6999,4242],{"class":1998},[1050,7001,1852],{"class":1371},[1050,7003,4320],{"class":1919},[1050,7005,1923],{"class":1371},[1050,7007,1504],{"class":1503},[1050,7009,7010],{"class":1507},"✓ preload directive present",[1050,7012,1504],{"class":1503},[1050,7014,1524],{"class":1371},[1050,7016,7017],{"class":1052,"line":2996},[1050,7018,4432],{"class":1371},[1050,7020,7021,7023],{"class":1052,"line":3018},[1050,7022,3150],{"class":1348},[1050,7024,1949],{"class":1371},[1050,7026,7027,7029,7031,7033,7035,7037],{"class":1052,"line":3044},[1050,7028,2200],{"class":1367},[1050,7030,1852],{"class":1371},[1050,7032,4224],{"class":1998},[1050,7034,1852],{"class":1371},[1050,7036,4229],{"class":1919},[1050,7038,4232],{"class":1371},[1050,7040,7041,7043,7045,7047,7049,7051,7053,7055,7058,7060],{"class":1052,"line":3049},[1050,7042,4194],{"class":1367},[1050,7044,1852],{"class":1371},[1050,7046,4242],{"class":1998},[1050,7048,1852],{"class":1371},[1050,7050,4247],{"class":1919},[1050,7052,1923],{"class":1371},[1050,7054,1504],{"class":1503},[1050,7056,7057],{"class":1507},"⚠ preload directive missing",[1050,7059,1504],{"class":1503},[1050,7061,1524],{"class":1371},[1050,7063,7064],{"class":1052,"line":3067},[1050,7065,4432],{"class":1371},[1050,7067,7068],{"class":1052,"line":3077},[1050,7069,1964],{"class":1352},[1050,7071,7072,7074,7077,7079,7081,7083,7086],{"class":1052,"line":3106},[1050,7073,1969],{"class":1941},[1050,7075,7076],{"class":2239}," check_security_headers",[1050,7078,1923],{"class":1371},[1050,7080,1979],{"class":1978},[1050,7082,1513],{"class":1371},[1050,7084,7085],{"class":1984}," headers",[1050,7087,1988],{"class":1371},[1050,7089,7090,7092,7095],{"class":1052,"line":3116},[1050,7091,2255],{"class":1076},[1050,7093,7094],{"class":1083},"Check other security headers",[1050,7096,1077],{"class":1076},[1050,7098,7099],{"class":1052,"line":3147},[1050,7100,2155],{"class":1352},[1050,7102,7103,7106,7108],{"class":1052,"line":3155},[1050,7104,7105],{"class":1352},"        security_headers ",[1050,7107,1911],{"class":1371},[1050,7109,5291],{"class":1371},[1050,7111,7112,7114,7116,7118,7120,7122,7124,7126],{"class":1052,"line":3183},[1050,7113,2513],{"class":1503},[1050,7115,2919],{"class":1507},[1050,7117,1504],{"class":1503},[1050,7119,2521],{"class":1371},[1050,7121,1516],{"class":1503},[1050,7123,2930],{"class":1507},[1050,7125,1504],{"class":1503},[1050,7127,2596],{"class":1371},[1050,7129,7130,7132,7134,7136,7138,7140,7142,7144,7146,7148,7150,7153,7155],{"class":1052,"line":3191},[1050,7131,2513],{"class":1503},[1050,7133,2944],{"class":1507},[1050,7135,1504],{"class":1503},[1050,7137,2521],{"class":1371},[1050,7139,1809],{"class":1371},[1050,7141,1504],{"class":1503},[1050,7143,2955],{"class":1507},[1050,7145,1504],{"class":1503},[1050,7147,1513],{"class":1371},[1050,7149,1516],{"class":1503},[1050,7151,7152],{"class":1507},"SAMEORIGIN",[1050,7154,1504],{"class":1503},[1050,7156,5020],{"class":1371},[1050,7158,7159,7161,7163,7165,7167,7169,7171,7173],{"class":1052,"line":3196},[1050,7160,2513],{"class":1503},[1050,7162,2969],{"class":1507},[1050,7164,1504],{"class":1503},[1050,7166,2521],{"class":1371},[1050,7168,1516],{"class":1503},[1050,7170,2980],{"class":1507},[1050,7172,1504],{"class":1503},[1050,7174,2596],{"class":1371},[1050,7176,7177,7179,7181,7183,7185,7187,7189],{"class":1052,"line":3202},[1050,7178,2513],{"class":1503},[1050,7180,3027],{"class":1507},[1050,7182,1504],{"class":1503},[1050,7184,2521],{"class":1371},[1050,7186,1516],{"class":1503},[1050,7188,1545],{"class":1507},[1050,7190,1548],{"class":1503},[1050,7192,7193],{"class":1052,"line":3213},[1050,7194,5482],{"class":1371},[1050,7196,7197],{"class":1052,"line":3226},[1050,7198,2155],{"class":1352},[1050,7200,7201,7203,7206,7208,7211,7213,7216,7218,7221],{"class":1052,"line":3232},[1050,7202,6608],{"class":1348},[1050,7204,7205],{"class":1352}," header",[1050,7207,1513],{"class":1371},[1050,7209,7210],{"class":1352}," expected ",[1050,7212,2309],{"class":1348},[1050,7214,7215],{"class":1352}," security_headers",[1050,7217,1852],{"class":1371},[1050,7219,7220],{"class":1919},"items",[1050,7222,2132],{"class":1371},[1050,7224,7225,7228,7230,7232,7234,7236,7238,7241],{"class":1052,"line":3237},[1050,7226,7227],{"class":1352},"            value ",[1050,7229,1911],{"class":1371},[1050,7231,7085],{"class":1352},[1050,7233,1852],{"class":1371},[1050,7235,2560],{"class":1919},[1050,7237,1923],{"class":1371},[1050,7239,7240],{"class":1919},"header",[1050,7242,1524],{"class":1371},[1050,7244,7245],{"class":1052,"line":3242},[1050,7246,2780],{"class":1352},[1050,7248,7249,7251,7254],{"class":1052,"line":3248},[1050,7250,2119],{"class":1348},[1050,7252,7253],{"class":1352}," value",[1050,7255,1949],{"class":1371},[1050,7257,7258,7261,7264,7266,7269,7271,7274],{"class":1052,"line":3257},[1050,7259,7260],{"class":1348},"                if",[1050,7262,7263],{"class":1972}," isinstance",[1050,7265,1923],{"class":1371},[1050,7267,7268],{"class":1919},"expected",[1050,7270,1513],{"class":1371},[1050,7272,7273],{"class":3879}," list",[1050,7275,1988],{"class":1371},[1050,7277,7278,7281,7284,7286,7289],{"class":1052,"line":3272},[1050,7279,7280],{"class":1348},"                    if",[1050,7282,7283],{"class":1352}," value ",[1050,7285,2309],{"class":1615},[1050,7287,7288],{"class":1352}," expected",[1050,7290,1949],{"class":1371},[1050,7292,7293,7296,7298,7300,7302,7304],{"class":1052,"line":3287},[1050,7294,7295],{"class":1367},"                        self",[1050,7297,1852],{"class":1371},[1050,7299,4224],{"class":1998},[1050,7301,1852],{"class":1371},[1050,7303,4229],{"class":1919},[1050,7305,4232],{"class":1371},[1050,7307,7308,7311,7313,7315,7317,7319,7321,7323,7326,7328,7330,7332,7334,7336,7339,7341,7343],{"class":1052,"line":3292},[1050,7309,7310],{"class":1367},"                            self",[1050,7312,1852],{"class":1371},[1050,7314,4242],{"class":1998},[1050,7316,1852],{"class":1371},[1050,7318,4320],{"class":1919},[1050,7320,1923],{"class":1371},[1050,7322,2479],{"class":1941},[1050,7324,7325],{"class":1507},"'✓ ",[1050,7327,2486],{"class":2485},[1050,7329,7240],{"class":1919},[1050,7331,2495],{"class":2485},[1050,7333,4416],{"class":1507},[1050,7335,2486],{"class":2485},[1050,7337,7338],{"class":1919},"value",[1050,7340,2495],{"class":2485},[1050,7342,1504],{"class":1507},[1050,7344,1524],{"class":1371},[1050,7346,7347],{"class":1052,"line":3297},[1050,7348,7349],{"class":1371},"                        )\n",[1050,7351,7352,7355],{"class":1052,"line":3306},[1050,7353,7354],{"class":1348},"                    else",[1050,7356,1949],{"class":1371},[1050,7358,7359,7361,7363,7365,7367,7369],{"class":1052,"line":3318},[1050,7360,7295],{"class":1367},[1050,7362,1852],{"class":1371},[1050,7364,4224],{"class":1998},[1050,7366,1852],{"class":1371},[1050,7368,4229],{"class":1919},[1050,7370,4232],{"class":1371},[1050,7372,7373,7375,7377,7379,7381,7383,7385,7387,7390,7392,7394,7396,7398,7400,7402,7404,7407,7409,7411,7413,7416],{"class":1052,"line":3330},[1050,7374,7310],{"class":1367},[1050,7376,1852],{"class":1371},[1050,7378,4242],{"class":1998},[1050,7380,1852],{"class":1371},[1050,7382,4247],{"class":1919},[1050,7384,1923],{"class":1371},[1050,7386,2479],{"class":1941},[1050,7388,7389],{"class":1507},"'⚠ ",[1050,7391,2486],{"class":2485},[1050,7393,7240],{"class":1919},[1050,7395,2495],{"class":2485},[1050,7397,4416],{"class":1507},[1050,7399,2486],{"class":2485},[1050,7401,7338],{"class":1919},[1050,7403,2495],{"class":2485},[1050,7405,7406],{"class":1507}," (expected one of ",[1050,7408,2486],{"class":2485},[1050,7410,7268],{"class":1919},[1050,7412,2495],{"class":2485},[1050,7414,7415],{"class":1507},")'",[1050,7417,1524],{"class":1371},[1050,7419,7420],{"class":1052,"line":3342},[1050,7421,7349],{"class":1371},[1050,7423,7424,7427],{"class":1052,"line":3354},[1050,7425,7426],{"class":1348},"                else",[1050,7428,1949],{"class":1371},[1050,7430,7432,7434,7436,7438,7440],{"class":1052,"line":7431},111,[1050,7433,7280],{"class":1348},[1050,7435,7283],{"class":1352},[1050,7437,6685],{"class":1615},[1050,7439,7288],{"class":1352},[1050,7441,1949],{"class":1371},[1050,7443,7445,7447,7449,7451,7453,7455],{"class":1052,"line":7444},112,[1050,7446,7295],{"class":1367},[1050,7448,1852],{"class":1371},[1050,7450,4224],{"class":1998},[1050,7452,1852],{"class":1371},[1050,7454,4229],{"class":1919},[1050,7456,4232],{"class":1371},[1050,7458,7460,7462,7464,7466,7468,7470,7472,7474,7476,7478,7480,7482,7484,7486,7488,7490,7492],{"class":1052,"line":7459},113,[1050,7461,7310],{"class":1367},[1050,7463,1852],{"class":1371},[1050,7465,4242],{"class":1998},[1050,7467,1852],{"class":1371},[1050,7469,4320],{"class":1919},[1050,7471,1923],{"class":1371},[1050,7473,2479],{"class":1941},[1050,7475,7325],{"class":1507},[1050,7477,2486],{"class":2485},[1050,7479,7240],{"class":1919},[1050,7481,2495],{"class":2485},[1050,7483,4416],{"class":1507},[1050,7485,2486],{"class":2485},[1050,7487,7338],{"class":1919},[1050,7489,2495],{"class":2485},[1050,7491,1504],{"class":1507},[1050,7493,1524],{"class":1371},[1050,7495,7497],{"class":1052,"line":7496},114,[1050,7498,7349],{"class":1371},[1050,7500,7502,7504],{"class":1052,"line":7501},115,[1050,7503,7354],{"class":1348},[1050,7505,1949],{"class":1371},[1050,7507,7509,7511,7513,7515,7517,7519],{"class":1052,"line":7508},116,[1050,7510,7295],{"class":1367},[1050,7512,1852],{"class":1371},[1050,7514,4224],{"class":1998},[1050,7516,1852],{"class":1371},[1050,7518,4229],{"class":1919},[1050,7520,4232],{"class":1371},[1050,7522,7524,7526,7528,7530,7532,7534,7536,7538,7540,7542,7544,7546,7548,7550,7552,7554,7557,7559,7561,7563,7565],{"class":1052,"line":7523},117,[1050,7525,7310],{"class":1367},[1050,7527,1852],{"class":1371},[1050,7529,4242],{"class":1998},[1050,7531,1852],{"class":1371},[1050,7533,4247],{"class":1919},[1050,7535,1923],{"class":1371},[1050,7537,2479],{"class":1941},[1050,7539,7389],{"class":1507},[1050,7541,2486],{"class":2485},[1050,7543,7240],{"class":1919},[1050,7545,2495],{"class":2485},[1050,7547,4416],{"class":1507},[1050,7549,2486],{"class":2485},[1050,7551,7338],{"class":1919},[1050,7553,2495],{"class":2485},[1050,7555,7556],{"class":1507}," (expected ",[1050,7558,2486],{"class":2485},[1050,7560,7268],{"class":1919},[1050,7562,2495],{"class":2485},[1050,7564,7415],{"class":1507},[1050,7566,1524],{"class":1371},[1050,7568,7570],{"class":1052,"line":7569},118,[1050,7571,7349],{"class":1371},[1050,7573,7575,7577],{"class":1052,"line":7574},119,[1050,7576,4291],{"class":1348},[1050,7578,1949],{"class":1371},[1050,7580,7582,7584,7586,7588,7590,7592],{"class":1052,"line":7581},120,[1050,7583,4194],{"class":1367},[1050,7585,1852],{"class":1371},[1050,7587,4224],{"class":1998},[1050,7589,1852],{"class":1371},[1050,7591,4229],{"class":1919},[1050,7593,4232],{"class":1371},[1050,7595,7597,7599,7601,7603,7605,7607,7609,7611,7614,7616,7618,7620,7623],{"class":1052,"line":7596},121,[1050,7598,4237],{"class":1367},[1050,7600,1852],{"class":1371},[1050,7602,4242],{"class":1998},[1050,7604,1852],{"class":1371},[1050,7606,4400],{"class":1919},[1050,7608,1923],{"class":1371},[1050,7610,2479],{"class":1941},[1050,7612,7613],{"class":1507},"'✗ ",[1050,7615,2486],{"class":2485},[1050,7617,7240],{"class":1919},[1050,7619,2495],{"class":2485},[1050,7621,7622],{"class":1507},": Missing'",[1050,7624,1524],{"class":1371},[1050,7626,7628],{"class":1052,"line":7627},122,[1050,7629,4286],{"class":1371},[1030,7631,7633],{"id":7632},"load-balancer-and-proxy-configuration","Load Balancer and Proxy Configuration",[1035,7635,7637],{"id":7636},"nginx-configuration","Nginx Configuration",[1040,7639,7643],{"className":7640,"code":7641,"language":7642,"meta":1045,"style":1045},"language-nginx shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# nginx.conf - HTTPS configuration with Django\nserver {\n    listen 80;\n    server_name yourdomain.com www.yourdomain.com;\n    \n    # Redirect all HTTP to HTTPS\n    return 301 https://$server_name$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name yourdomain.com www.yourdomain.com;\n    \n    # SSL certificate configuration\n    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;\n    \n    # SSL security configuration\n    ssl_protocols TLSv1.2 TLSv1.3;\n    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;\n    ssl_prefer_server_ciphers off;\n    ssl_session_cache shared:SSL:10m;\n    ssl_session_timeout 10m;\n    \n    # HSTS header (let Django handle this, or configure here)\n    # add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\" always;\n    \n    # Security headers\n    add_header X-Content-Type-Options nosniff always;\n    add_header X-Frame-Options DENY always;\n    add_header X-XSS-Protection \"1; mode=block\" always;\n    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n    \n    # Pass real IP to Django\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_set_header Host $http_host;\n    \n    # Django application\n    location / {\n        proxy_pass http://127.0.0.1:8000;\n        proxy_redirect off;\n    }\n    \n    # Static files (optional - serve directly from nginx)\n    location /static/ {\n        alias /path/to/static/files/;\n        expires 1y;\n        add_header Cache-Control \"public, immutable\";\n    }\n    \n    # Media files (optional - serve directly from nginx)\n    location /media/ {\n        alias /path/to/media/files/;\n        expires 1y;\n        add_header Cache-Control \"public\";\n    }\n}\n","nginx",[1047,7644,7645,7650,7655,7660,7665,7669,7674,7679,7683,7687,7691,7696,7700,7704,7709,7714,7719,7723,7728,7733,7738,7743,7748,7753,7757,7762,7767,7771,7776,7781,7786,7791,7796,7800,7805,7810,7815,7820,7825,7829,7834,7839,7844,7849,7854,7858,7863,7868,7873,7878,7883,7887,7891,7896,7901,7906,7910,7915,7919],{"__ignoreMap":1045},[1050,7646,7647],{"class":1052,"line":1053},[1050,7648,7649],{},"# nginx.conf - HTTPS configuration with Django\n",[1050,7651,7652],{"class":1052,"line":1060},[1050,7653,7654],{},"server {\n",[1050,7656,7657],{"class":1052,"line":1067},[1050,7658,7659],{},"    listen 80;\n",[1050,7661,7662],{"class":1052,"line":1073},[1050,7663,7664],{},"    server_name yourdomain.com www.yourdomain.com;\n",[1050,7666,7667],{"class":1052,"line":1080},[1050,7668,1964],{},[1050,7670,7671],{"class":1052,"line":1087},[1050,7672,7673],{},"    # Redirect all HTTP to HTTPS\n",[1050,7675,7676],{"class":1052,"line":1093},[1050,7677,7678],{},"    return 301 https://$server_name$request_uri;\n",[1050,7680,7681],{"class":1052,"line":1099},[1050,7682,4888],{},[1050,7684,7685],{"class":1052,"line":1104},[1050,7686,1064],{"emptyLinePlaceholder":1063},[1050,7688,7689],{"class":1052,"line":1110},[1050,7690,7654],{},[1050,7692,7693],{"class":1052,"line":1115},[1050,7694,7695],{},"    listen 443 ssl http2;\n",[1050,7697,7698],{"class":1052,"line":1120},[1050,7699,7664],{},[1050,7701,7702],{"class":1052,"line":1126},[1050,7703,1964],{},[1050,7705,7706],{"class":1052,"line":1131},[1050,7707,7708],{},"    # SSL certificate configuration\n",[1050,7710,7711],{"class":1052,"line":1136},[1050,7712,7713],{},"    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;\n",[1050,7715,7716],{"class":1052,"line":1141},[1050,7717,7718],{},"    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;\n",[1050,7720,7721],{"class":1052,"line":1146},[1050,7722,1964],{},[1050,7724,7725],{"class":1052,"line":1152},[1050,7726,7727],{},"    # SSL security configuration\n",[1050,7729,7730],{"class":1052,"line":1157},[1050,7731,7732],{},"    ssl_protocols TLSv1.2 TLSv1.3;\n",[1050,7734,7735],{"class":1052,"line":1162},[1050,7736,7737],{},"    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;\n",[1050,7739,7740],{"class":1052,"line":1168},[1050,7741,7742],{},"    ssl_prefer_server_ciphers off;\n",[1050,7744,7745],{"class":1052,"line":1174},[1050,7746,7747],{},"    ssl_session_cache shared:SSL:10m;\n",[1050,7749,7750],{"class":1052,"line":1180},[1050,7751,7752],{},"    ssl_session_timeout 10m;\n",[1050,7754,7755],{"class":1052,"line":1186},[1050,7756,1964],{},[1050,7758,7759],{"class":1052,"line":1316},[1050,7760,7761],{},"    # HSTS header (let Django handle this, or configure here)\n",[1050,7763,7764],{"class":1052,"line":1322},[1050,7765,7766],{},"    # add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\" always;\n",[1050,7768,7769],{"class":1052,"line":1754},[1050,7770,1964],{},[1050,7772,7773],{"class":1052,"line":1759},[1050,7774,7775],{},"    # Security headers\n",[1050,7777,7778],{"class":1052,"line":1765},[1050,7779,7780],{},"    add_header X-Content-Type-Options nosniff always;\n",[1050,7782,7783],{"class":1052,"line":1790},[1050,7784,7785],{},"    add_header X-Frame-Options DENY always;\n",[1050,7787,7788],{"class":1052,"line":1795},[1050,7789,7790],{},"    add_header X-XSS-Protection \"1; mode=block\" always;\n",[1050,7792,7793],{"class":1052,"line":1801},[1050,7794,7795],{},"    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n",[1050,7797,7798],{"class":1052,"line":2263},[1050,7799,1964],{},[1050,7801,7802],{"class":1052,"line":2268},[1050,7803,7804],{},"    # Pass real IP to Django\n",[1050,7806,7807],{"class":1052,"line":2274},[1050,7808,7809],{},"    proxy_set_header X-Real-IP $remote_addr;\n",[1050,7811,7812],{"class":1052,"line":2320},[1050,7813,7814],{},"    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n",[1050,7816,7817],{"class":1052,"line":2328},[1050,7818,7819],{},"    proxy_set_header X-Forwarded-Proto $scheme;\n",[1050,7821,7822],{"class":1052,"line":2333},[1050,7823,7824],{},"    proxy_set_header Host $http_host;\n",[1050,7826,7827],{"class":1052,"line":2339},[1050,7828,1964],{},[1050,7830,7831],{"class":1052,"line":2378},[1050,7832,7833],{},"    # Django application\n",[1050,7835,7836],{"class":1052,"line":2385},[1050,7837,7838],{},"    location / {\n",[1050,7840,7841],{"class":1052,"line":2390},[1050,7842,7843],{},"        proxy_pass http://127.0.0.1:8000;\n",[1050,7845,7846],{"class":1052,"line":2396},[1050,7847,7848],{},"        proxy_redirect off;\n",[1050,7850,7851],{"class":1052,"line":2422},[1050,7852,7853],{},"    }\n",[1050,7855,7856],{"class":1052,"line":2427},[1050,7857,1964],{},[1050,7859,7860],{"class":1052,"line":2445},[1050,7861,7862],{},"    # Static files (optional - serve directly from nginx)\n",[1050,7864,7865],{"class":1052,"line":2455},[1050,7866,7867],{},"    location /static/ {\n",[1050,7869,7870],{"class":1052,"line":2460},[1050,7871,7872],{},"        alias /path/to/static/files/;\n",[1050,7874,7875],{"class":1052,"line":2466},[1050,7876,7877],{},"        expires 1y;\n",[1050,7879,7880],{"class":1052,"line":2510},[1050,7881,7882],{},"        add_header Cache-Control \"public, immutable\";\n",[1050,7884,7885],{"class":1052,"line":2538},[1050,7886,7853],{},[1050,7888,7889],{"class":1052,"line":2579},[1050,7890,1964],{},[1050,7892,7893],{"class":1052,"line":2599},[1050,7894,7895],{},"    # Media files (optional - serve directly from nginx)\n",[1050,7897,7898],{"class":1052,"line":2605},[1050,7899,7900],{},"    location /media/ {\n",[1050,7902,7903],{"class":1052,"line":2610},[1050,7904,7905],{},"        alias /path/to/media/files/;\n",[1050,7907,7908],{"class":1052,"line":2616},[1050,7909,7877],{},[1050,7911,7912],{"class":1052,"line":2659},[1050,7913,7914],{},"        add_header Cache-Control \"public\";\n",[1050,7916,7917],{"class":1052,"line":2664},[1050,7918,7853],{},[1050,7920,7921],{"class":1052,"line":2679},[1050,7922,4888],{},[1035,7924,7926],{"id":7925},"apache-configuration","Apache Configuration",[1040,7928,7932],{"className":7929,"code":7930,"language":7931,"meta":1045,"style":1045},"language-apache shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# apache.conf - HTTPS configuration with Django\n\u003CVirtualHost *:80>\n    ServerName yourdomain.com\n    ServerAlias www.yourdomain.com\n    \n    # Redirect all HTTP to HTTPS\n    Redirect permanent / https://yourdomain.com/\n\u003C/VirtualHost>\n\n\u003CVirtualHost *:443>\n    ServerName yourdomain.com\n    ServerAlias www.yourdomain.com\n    \n    # SSL configuration\n    SSLEngine on\n    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem\n    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem\n    SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem\n    \n    # SSL security settings\n    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1\n    SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384\n    SSLHonorCipherOrder off\n    SSLSessionTickets off\n    \n    # Security headers\n    Header always set Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\"\n    Header always set X-Content-Type-Options nosniff\n    Header always set X-Frame-Options DENY\n    Header always set X-XSS-Protection \"1; mode=block\"\n    Header always set Referrer-Policy \"strict-origin-when-cross-origin\"\n    \n    # Pass headers to Django\n    SetEnvIf X-Forwarded-Proto https HTTPS=on\n    \n    # Django application (using mod_wsgi)\n    WSGIDaemonProcess yourdomain python-path=/path/to/your/project\n    WSGIProcessGroup yourdomain\n    WSGIScriptAlias / /path/to/your/project/wsgi.py\n    \n    \u003CDirectory /path/to/your/project>\n        WSGIApplicationGroup %{GLOBAL}\n        Require all granted\n    \u003C/Directory>\n    \n    # Static files\n    Alias /static /path/to/static/files\n    \u003CDirectory /path/to/static/files>\n        Require all granted\n    \u003C/Directory>\n    \n    # Media files\n    Alias /media /path/to/media/files\n    \u003CDirectory /path/to/media/files>\n        Require all granted\n    \u003C/Directory>\n\u003C/VirtualHost>\n","apache",[1047,7933,7934,7939,7944,7949,7954,7958,7962,7967,7972,7976,7981,7985,7989,7993,7998,8003,8008,8013,8018,8022,8027,8032,8037,8042,8047,8051,8055,8060,8065,8070,8075,8080,8084,8089,8094,8098,8103,8108,8113,8118,8122,8127,8132,8137,8142,8146,8151,8156,8161,8165,8169,8173,8178,8183,8188,8192,8196],{"__ignoreMap":1045},[1050,7935,7936],{"class":1052,"line":1053},[1050,7937,7938],{},"# apache.conf - HTTPS configuration with Django\n",[1050,7940,7941],{"class":1052,"line":1060},[1050,7942,7943],{},"\u003CVirtualHost *:80>\n",[1050,7945,7946],{"class":1052,"line":1067},[1050,7947,7948],{},"    ServerName yourdomain.com\n",[1050,7950,7951],{"class":1052,"line":1073},[1050,7952,7953],{},"    ServerAlias www.yourdomain.com\n",[1050,7955,7956],{"class":1052,"line":1080},[1050,7957,1964],{},[1050,7959,7960],{"class":1052,"line":1087},[1050,7961,7673],{},[1050,7963,7964],{"class":1052,"line":1093},[1050,7965,7966],{},"    Redirect permanent / https://yourdomain.com/\n",[1050,7968,7969],{"class":1052,"line":1099},[1050,7970,7971],{},"\u003C/VirtualHost>\n",[1050,7973,7974],{"class":1052,"line":1104},[1050,7975,1064],{"emptyLinePlaceholder":1063},[1050,7977,7978],{"class":1052,"line":1110},[1050,7979,7980],{},"\u003CVirtualHost *:443>\n",[1050,7982,7983],{"class":1052,"line":1115},[1050,7984,7948],{},[1050,7986,7987],{"class":1052,"line":1120},[1050,7988,7953],{},[1050,7990,7991],{"class":1052,"line":1126},[1050,7992,1964],{},[1050,7994,7995],{"class":1052,"line":1131},[1050,7996,7997],{},"    # SSL configuration\n",[1050,7999,8000],{"class":1052,"line":1136},[1050,8001,8002],{},"    SSLEngine on\n",[1050,8004,8005],{"class":1052,"line":1141},[1050,8006,8007],{},"    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem\n",[1050,8009,8010],{"class":1052,"line":1146},[1050,8011,8012],{},"    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem\n",[1050,8014,8015],{"class":1052,"line":1152},[1050,8016,8017],{},"    SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem\n",[1050,8019,8020],{"class":1052,"line":1157},[1050,8021,1964],{},[1050,8023,8024],{"class":1052,"line":1162},[1050,8025,8026],{},"    # SSL security settings\n",[1050,8028,8029],{"class":1052,"line":1168},[1050,8030,8031],{},"    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1\n",[1050,8033,8034],{"class":1052,"line":1174},[1050,8035,8036],{},"    SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384\n",[1050,8038,8039],{"class":1052,"line":1180},[1050,8040,8041],{},"    SSLHonorCipherOrder off\n",[1050,8043,8044],{"class":1052,"line":1186},[1050,8045,8046],{},"    SSLSessionTickets off\n",[1050,8048,8049],{"class":1052,"line":1316},[1050,8050,1964],{},[1050,8052,8053],{"class":1052,"line":1322},[1050,8054,7775],{},[1050,8056,8057],{"class":1052,"line":1754},[1050,8058,8059],{},"    Header always set Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\"\n",[1050,8061,8062],{"class":1052,"line":1759},[1050,8063,8064],{},"    Header always set X-Content-Type-Options nosniff\n",[1050,8066,8067],{"class":1052,"line":1765},[1050,8068,8069],{},"    Header always set X-Frame-Options DENY\n",[1050,8071,8072],{"class":1052,"line":1790},[1050,8073,8074],{},"    Header always set X-XSS-Protection \"1; mode=block\"\n",[1050,8076,8077],{"class":1052,"line":1795},[1050,8078,8079],{},"    Header always set Referrer-Policy \"strict-origin-when-cross-origin\"\n",[1050,8081,8082],{"class":1052,"line":1801},[1050,8083,1964],{},[1050,8085,8086],{"class":1052,"line":2263},[1050,8087,8088],{},"    # Pass headers to Django\n",[1050,8090,8091],{"class":1052,"line":2268},[1050,8092,8093],{},"    SetEnvIf X-Forwarded-Proto https HTTPS=on\n",[1050,8095,8096],{"class":1052,"line":2274},[1050,8097,1964],{},[1050,8099,8100],{"class":1052,"line":2320},[1050,8101,8102],{},"    # Django application (using mod_wsgi)\n",[1050,8104,8105],{"class":1052,"line":2328},[1050,8106,8107],{},"    WSGIDaemonProcess yourdomain python-path=/path/to/your/project\n",[1050,8109,8110],{"class":1052,"line":2333},[1050,8111,8112],{},"    WSGIProcessGroup yourdomain\n",[1050,8114,8115],{"class":1052,"line":2339},[1050,8116,8117],{},"    WSGIScriptAlias / /path/to/your/project/wsgi.py\n",[1050,8119,8120],{"class":1052,"line":2378},[1050,8121,1964],{},[1050,8123,8124],{"class":1052,"line":2385},[1050,8125,8126],{},"    \u003CDirectory /path/to/your/project>\n",[1050,8128,8129],{"class":1052,"line":2390},[1050,8130,8131],{},"        WSGIApplicationGroup %{GLOBAL}\n",[1050,8133,8134],{"class":1052,"line":2396},[1050,8135,8136],{},"        Require all granted\n",[1050,8138,8139],{"class":1052,"line":2422},[1050,8140,8141],{},"    \u003C/Directory>\n",[1050,8143,8144],{"class":1052,"line":2427},[1050,8145,1964],{},[1050,8147,8148],{"class":1052,"line":2445},[1050,8149,8150],{},"    # Static files\n",[1050,8152,8153],{"class":1052,"line":2455},[1050,8154,8155],{},"    Alias /static /path/to/static/files\n",[1050,8157,8158],{"class":1052,"line":2460},[1050,8159,8160],{},"    \u003CDirectory /path/to/static/files>\n",[1050,8162,8163],{"class":1052,"line":2466},[1050,8164,8136],{},[1050,8166,8167],{"class":1052,"line":2510},[1050,8168,8141],{},[1050,8170,8171],{"class":1052,"line":2538},[1050,8172,1964],{},[1050,8174,8175],{"class":1052,"line":2579},[1050,8176,8177],{},"    # Media files\n",[1050,8179,8180],{"class":1052,"line":2599},[1050,8181,8182],{},"    Alias /media /path/to/media/files\n",[1050,8184,8185],{"class":1052,"line":2605},[1050,8186,8187],{},"    \u003CDirectory /path/to/media/files>\n",[1050,8189,8190],{"class":1052,"line":2610},[1050,8191,8136],{},[1050,8193,8194],{"class":1052,"line":2616},[1050,8195,8141],{},[1050,8197,8198],{"class":1052,"line":2659},[1050,8199,7971],{},[1030,8201,8203],{"id":8202},"testing-https-configuration","Testing HTTPS Configuration",[1035,8205,8207],{"id":8206},"security-tests","Security Tests",[1040,8209,8211],{"className":1042,"code":8210,"language":1044,"meta":1045,"style":1045},"# tests.py - HTTPS configuration tests\nfrom django.test import TestCase, Client, override_settings\nfrom django.urls import reverse\n\nclass HTTPSConfigurationTests(TestCase):\n    \"\"\"Test HTTPS configuration and security headers\"\"\"\n    \n    def setUp(self):\n        self.client = Client()\n    \n    @override_settings(SECURE_SSL_REDIRECT=True)\n    def test_http_redirect_to_https(self):\n        \"\"\"Test that HTTP requests are redirected to HTTPS\"\"\"\n        \n        response = self.client.get('/', secure=False)\n        \n        self.assertEqual(response.status_code, 301)\n        self.assertTrue(response.url.startswith('https://'))\n    \n    @override_settings(\n        SECURE_HSTS_SECONDS=31536000,\n        SECURE_HSTS_INCLUDE_SUBDOMAINS=True,\n        SECURE_HSTS_PRELOAD=True\n    )\n    def test_hsts_header(self):\n        \"\"\"Test HSTS header configuration\"\"\"\n        \n        response = self.client.get('/', secure=True)\n        \n        hsts_header = response.get('Strict-Transport-Security')\n        self.assertIsNotNone(hsts_header)\n        self.assertIn('max-age=31536000', hsts_header)\n        self.assertIn('includeSubDomains', hsts_header)\n        self.assertIn('preload', hsts_header)\n    \n    @override_settings(\n        SESSION_COOKIE_SECURE=True,\n        CSRF_COOKIE_SECURE=True\n    )\n    def test_secure_cookies(self):\n        \"\"\"Test that cookies are marked as secure\"\"\"\n        \n        # Login to create session\n        from django.contrib.auth.models import User\n        user = User.objects.create_user('testuser', 'test@example.com', 'testpass')\n        \n        response = self.client.post(reverse('login'), {\n            'username': 'testuser',\n            'password': 'testpass'\n        }, secure=True)\n        \n        # Check session cookie\n        session_cookie = response.cookies.get('sessionid')\n        if session_cookie:\n            self.assertTrue(session_cookie['secure'])\n        \n        # Check CSRF cookie\n        csrf_cookie = response.cookies.get('csrftoken')\n        if csrf_cookie:\n            self.assertTrue(csrf_cookie['secure'])\n    \n    def test_security_headers(self):\n        \"\"\"Test security headers are present\"\"\"\n        \n        response = self.client.get('/', secure=True)\n        \n        # Check for security headers\n        self.assertEqual(response.get('X-Content-Type-Options'), 'nosniff')\n        self.assertEqual(response.get('X-Frame-Options'), 'DENY')\n        self.assertEqual(response.get('X-XSS-Protection'), '1; mode=block')\n        \n        referrer_policy = response.get('Referrer-Policy')\n        self.assertIsNotNone(referrer_policy)\n\nclass SSLCertificateTests(TestCase):\n    \"\"\"Test SSL certificate validation\"\"\"\n    \n    def test_certificate_validity(self):\n        \"\"\"Test SSL certificate is valid and properly configured\"\"\"\n        \n        import ssl\n        import socket\n        from datetime import datetime\n        \n        try:\n            # Test certificate for your domain\n            context = ssl.create_default_context()\n            \n            with socket.create_connection(('yourdomain.com', 443), timeout=10) as sock:\n                with context.wrap_socket(sock, server_hostname='yourdomain.com') as ssock:\n                    cert = ssock.getpeercert()\n            \n            # Check certificate expiration\n            not_after = cert['notAfter']\n            expiry_date = datetime.strptime(not_after, '%b %d %H:%M:%S %Y %Z')\n            days_until_expiry = (expiry_date - datetime.now()).days\n            \n            # Certificate should not expire within 30 days\n            self.assertGreater(days_until_expiry, 30, \n                             f\"Certificate expires in {days_until_expiry} days\")\n            \n            # Check subject matches domain\n            subject = dict(x[0] for x in cert['subject'])\n            self.assertIn('yourdomain.com', subject.get('commonName', ''))\n            \n        except Exception as e:\n            self.skipTest(f\"Could not test certificate: {e}\")\n",[1047,8212,8213,8218,8244,8258,8262,8276,8285,8289,8302,8317,8321,8340,8353,8362,8366,8402,8406,8431,8464,8468,8476,8488,8499,8509,8514,8527,8536,8540,8574,8578,8601,8616,8640,8662,8684,8688,8696,8707,8716,8720,8733,8742,8746,8751,8778,8827,8831,8866,8885,8902,8915,8919,8924,8953,8962,8986,8990,8995,9023,9032,9055,9059,9072,9081,9085,9119,9123,9128,9162,9196,9230,9234,9257,9272,9276,9289,9298,9302,9315,9324,9328,9335,9341,9352,9356,9362,9367,9382,9386,9425,9460,9475,9479,9484,9504,9535,9558,9562,9567,9590,9609,9613,9618,9658,9698,9702,9714],{"__ignoreMap":1045},[1050,8214,8215],{"class":1052,"line":1053},[1050,8216,8217],{"class":1056},"# tests.py - HTTPS configuration tests\n",[1050,8219,8220,8222,8224,8226,8229,8231,8234,8236,8239,8241],{"class":1052,"line":1060},[1050,8221,1604],{"class":1348},[1050,8223,1849],{"class":1352},[1050,8225,1852],{"class":1371},[1050,8227,8228],{"class":1352},"test ",[1050,8230,1349],{"class":1348},[1050,8232,8233],{"class":1352}," TestCase",[1050,8235,1513],{"class":1371},[1050,8237,8238],{"class":1352}," Client",[1050,8240,1513],{"class":1371},[1050,8242,8243],{"class":1352}," override_settings\n",[1050,8245,8246,8248,8250,8252,8254,8256],{"class":1052,"line":1067},[1050,8247,1604],{"class":1348},[1050,8249,1849],{"class":1352},[1050,8251,1852],{"class":1371},[1050,8253,1887],{"class":1352},[1050,8255,1349],{"class":1348},[1050,8257,1892],{"class":1352},[1050,8259,8260],{"class":1052,"line":1073},[1050,8261,1064],{"emptyLinePlaceholder":1063},[1050,8263,8264,8266,8269,8271,8274],{"class":1052,"line":1080},[1050,8265,1942],{"class":1941},[1050,8267,8268],{"class":1945}," HTTPSConfigurationTests",[1050,8270,1923],{"class":1371},[1050,8272,8273],{"class":3798},"TestCase",[1050,8275,1988],{"class":1371},[1050,8277,8278,8280,8283],{"class":1052,"line":1087},[1050,8279,1954],{"class":1076},[1050,8281,8282],{"class":1083},"Test HTTPS configuration and security headers",[1050,8284,1077],{"class":1076},[1050,8286,8287],{"class":1052,"line":1093},[1050,8288,1964],{"class":1352},[1050,8290,8291,8293,8296,8298,8300],{"class":1052,"line":1099},[1050,8292,1969],{"class":1941},[1050,8294,8295],{"class":2239}," setUp",[1050,8297,1923],{"class":1371},[1050,8299,1979],{"class":1978},[1050,8301,1988],{"class":1371},[1050,8303,8304,8306,8308,8311,8313,8315],{"class":1052,"line":1104},[1050,8305,1993],{"class":1367},[1050,8307,1852],{"class":1371},[1050,8309,8310],{"class":1998},"client",[1050,8312,1372],{"class":1371},[1050,8314,8238],{"class":1919},[1050,8316,4489],{"class":1371},[1050,8318,8319],{"class":1052,"line":1110},[1050,8320,1964],{"class":1352},[1050,8322,8323,8326,8329,8331,8333,8335,8338],{"class":1052,"line":1115},[1050,8324,8325],{"class":1371},"    @",[1050,8327,8328],{"class":2239},"override_settings",[1050,8330,1923],{"class":1371},[1050,8332,1368],{"class":2503},[1050,8334,1911],{"class":1371},[1050,8336,8337],{"class":1375},"True",[1050,8339,1524],{"class":1371},[1050,8341,8342,8344,8347,8349,8351],{"class":1052,"line":1120},[1050,8343,1969],{"class":1941},[1050,8345,8346],{"class":2239}," test_http_redirect_to_https",[1050,8348,1923],{"class":1371},[1050,8350,1979],{"class":1978},[1050,8352,1988],{"class":1371},[1050,8354,8355,8357,8360],{"class":1052,"line":1126},[1050,8356,2255],{"class":1076},[1050,8358,8359],{"class":1083},"Test that HTTP requests are redirected to HTTPS",[1050,8361,1077],{"class":1076},[1050,8363,8364],{"class":1052,"line":1131},[1050,8365,2155],{"class":1352},[1050,8367,8368,8370,8372,8374,8376,8378,8380,8382,8384,8386,8389,8391,8393,8396,8398,8400],{"class":1052,"line":1136},[1050,8369,2160],{"class":1352},[1050,8371,1911],{"class":1371},[1050,8373,2102],{"class":1367},[1050,8375,1852],{"class":1371},[1050,8377,8310],{"class":1998},[1050,8379,1852],{"class":1371},[1050,8381,2560],{"class":1919},[1050,8383,1923],{"class":1371},[1050,8385,1504],{"class":1503},[1050,8387,8388],{"class":1507},"/",[1050,8390,1504],{"class":1503},[1050,8392,1513],{"class":1371},[1050,8394,8395],{"class":2503}," secure",[1050,8397,1911],{"class":1371},[1050,8399,5030],{"class":1375},[1050,8401,1524],{"class":1371},[1050,8403,8404],{"class":1052,"line":1141},[1050,8405,2155],{"class":1352},[1050,8407,8408,8410,8412,8415,8417,8419,8421,8424,8426,8429],{"class":1052,"line":1146},[1050,8409,1993],{"class":1367},[1050,8411,1852],{"class":1371},[1050,8413,8414],{"class":1919},"assertEqual",[1050,8416,1923],{"class":1371},[1050,8418,6382],{"class":1919},[1050,8420,1852],{"class":1371},[1050,8422,8423],{"class":1998},"status_code",[1050,8425,1513],{"class":1371},[1050,8427,8428],{"class":1459}," 301",[1050,8430,1524],{"class":1371},[1050,8432,8433,8435,8437,8440,8442,8444,8446,8448,8450,8452,8454,8456,8459,8461],{"class":1052,"line":1152},[1050,8434,1993],{"class":1367},[1050,8436,1852],{"class":1371},[1050,8438,8439],{"class":1919},"assertTrue",[1050,8441,1923],{"class":1371},[1050,8443,6382],{"class":1919},[1050,8445,1852],{"class":1371},[1050,8447,6192],{"class":1998},[1050,8449,1852],{"class":1371},[1050,8451,2293],{"class":1919},[1050,8453,1923],{"class":1371},[1050,8455,1504],{"class":1503},[1050,8457,8458],{"class":1507},"https://",[1050,8460,1504],{"class":1503},[1050,8462,8463],{"class":1371},"))\n",[1050,8465,8466],{"class":1052,"line":1157},[1050,8467,1964],{"class":1352},[1050,8469,8470,8472,8474],{"class":1052,"line":1162},[1050,8471,8325],{"class":1371},[1050,8473,8328],{"class":2239},[1050,8475,4232],{"class":1371},[1050,8477,8478,8481,8483,8486],{"class":1052,"line":1168},[1050,8479,8480],{"class":2503},"        SECURE_HSTS_SECONDS",[1050,8482,1911],{"class":1371},[1050,8484,8485],{"class":1459},"31536000",[1050,8487,2596],{"class":1371},[1050,8489,8490,8493,8495,8497],{"class":1052,"line":1174},[1050,8491,8492],{"class":2503},"        SECURE_HSTS_INCLUDE_SUBDOMAINS",[1050,8494,1911],{"class":1371},[1050,8496,8337],{"class":1375},[1050,8498,2596],{"class":1371},[1050,8500,8501,8504,8506],{"class":1052,"line":1180},[1050,8502,8503],{"class":2503},"        SECURE_HSTS_PRELOAD",[1050,8505,1911],{"class":1371},[1050,8507,8508],{"class":1375},"True\n",[1050,8510,8511],{"class":1052,"line":1186},[1050,8512,8513],{"class":1371},"    )\n",[1050,8515,8516,8518,8521,8523,8525],{"class":1052,"line":1316},[1050,8517,1969],{"class":1941},[1050,8519,8520],{"class":2239}," test_hsts_header",[1050,8522,1923],{"class":1371},[1050,8524,1979],{"class":1978},[1050,8526,1988],{"class":1371},[1050,8528,8529,8531,8534],{"class":1052,"line":1322},[1050,8530,2255],{"class":1076},[1050,8532,8533],{"class":1083},"Test HSTS header configuration",[1050,8535,1077],{"class":1076},[1050,8537,8538],{"class":1052,"line":1754},[1050,8539,2155],{"class":1352},[1050,8541,8542,8544,8546,8548,8550,8552,8554,8556,8558,8560,8562,8564,8566,8568,8570,8572],{"class":1052,"line":1759},[1050,8543,2160],{"class":1352},[1050,8545,1911],{"class":1371},[1050,8547,2102],{"class":1367},[1050,8549,1852],{"class":1371},[1050,8551,8310],{"class":1998},[1050,8553,1852],{"class":1371},[1050,8555,2560],{"class":1919},[1050,8557,1923],{"class":1371},[1050,8559,1504],{"class":1503},[1050,8561,8388],{"class":1507},[1050,8563,1504],{"class":1503},[1050,8565,1513],{"class":1371},[1050,8567,8395],{"class":2503},[1050,8569,1911],{"class":1371},[1050,8571,8337],{"class":1375},[1050,8573,1524],{"class":1371},[1050,8575,8576],{"class":1052,"line":1765},[1050,8577,2155],{"class":1352},[1050,8579,8580,8583,8585,8587,8589,8591,8593,8595,8597,8599],{"class":1052,"line":1790},[1050,8581,8582],{"class":1352},"        hsts_header ",[1050,8584,1911],{"class":1371},[1050,8586,2214],{"class":1352},[1050,8588,1852],{"class":1371},[1050,8590,2560],{"class":1919},[1050,8592,1923],{"class":1371},[1050,8594,1504],{"class":1503},[1050,8596,2885],{"class":1507},[1050,8598,1504],{"class":1503},[1050,8600,1524],{"class":1371},[1050,8602,8603,8605,8607,8610,8612,8614],{"class":1052,"line":1795},[1050,8604,1993],{"class":1367},[1050,8606,1852],{"class":1371},[1050,8608,8609],{"class":1919},"assertIsNotNone",[1050,8611,1923],{"class":1371},[1050,8613,6310],{"class":1919},[1050,8615,1524],{"class":1371},[1050,8617,8618,8620,8622,8625,8627,8629,8632,8634,8636,8638],{"class":1052,"line":1801},[1050,8619,1993],{"class":1367},[1050,8621,1852],{"class":1371},[1050,8623,8624],{"class":1919},"assertIn",[1050,8626,1923],{"class":1371},[1050,8628,1504],{"class":1503},[1050,8630,8631],{"class":1507},"max-age=31536000",[1050,8633,1504],{"class":1503},[1050,8635,1513],{"class":1371},[1050,8637,5567],{"class":1919},[1050,8639,1524],{"class":1371},[1050,8641,8642,8644,8646,8648,8650,8652,8654,8656,8658,8660],{"class":1052,"line":2263},[1050,8643,1993],{"class":1367},[1050,8645,1852],{"class":1371},[1050,8647,8624],{"class":1919},[1050,8649,1923],{"class":1371},[1050,8651,1504],{"class":1503},[1050,8653,5845],{"class":1507},[1050,8655,1504],{"class":1503},[1050,8657,1513],{"class":1371},[1050,8659,5567],{"class":1919},[1050,8661,1524],{"class":1371},[1050,8663,8664,8666,8668,8670,8672,8674,8676,8678,8680,8682],{"class":1052,"line":2268},[1050,8665,1993],{"class":1367},[1050,8667,1852],{"class":1371},[1050,8669,8624],{"class":1919},[1050,8671,1923],{"class":1371},[1050,8673,1504],{"class":1503},[1050,8675,5344],{"class":1507},[1050,8677,1504],{"class":1503},[1050,8679,1513],{"class":1371},[1050,8681,5567],{"class":1919},[1050,8683,1524],{"class":1371},[1050,8685,8686],{"class":1052,"line":2274},[1050,8687,1964],{"class":1352},[1050,8689,8690,8692,8694],{"class":1052,"line":2320},[1050,8691,8325],{"class":1371},[1050,8693,8328],{"class":2239},[1050,8695,4232],{"class":1371},[1050,8697,8698,8701,8703,8705],{"class":1052,"line":2328},[1050,8699,8700],{"class":2503},"        SESSION_COOKIE_SECURE",[1050,8702,1911],{"class":1371},[1050,8704,8337],{"class":1375},[1050,8706,2596],{"class":1371},[1050,8708,8709,8712,8714],{"class":1052,"line":2333},[1050,8710,8711],{"class":2503},"        CSRF_COOKIE_SECURE",[1050,8713,1911],{"class":1371},[1050,8715,8508],{"class":1375},[1050,8717,8718],{"class":1052,"line":2339},[1050,8719,8513],{"class":1371},[1050,8721,8722,8724,8727,8729,8731],{"class":1052,"line":2378},[1050,8723,1969],{"class":1941},[1050,8725,8726],{"class":2239}," test_secure_cookies",[1050,8728,1923],{"class":1371},[1050,8730,1979],{"class":1978},[1050,8732,1988],{"class":1371},[1050,8734,8735,8737,8740],{"class":1052,"line":2385},[1050,8736,2255],{"class":1076},[1050,8738,8739],{"class":1083},"Test that cookies are marked as secure",[1050,8741,1077],{"class":1076},[1050,8743,8744],{"class":1052,"line":2390},[1050,8745,2155],{"class":1352},[1050,8747,8748],{"class":1052,"line":2396},[1050,8749,8750],{"class":1056},"        # Login to create session\n",[1050,8752,8753,8756,8758,8760,8763,8765,8768,8770,8773,8775],{"class":1052,"line":2422},[1050,8754,8755],{"class":1348},"        from",[1050,8757,1849],{"class":1352},[1050,8759,1852],{"class":1371},[1050,8761,8762],{"class":1352},"contrib",[1050,8764,1852],{"class":1371},[1050,8766,8767],{"class":1352},"auth",[1050,8769,1852],{"class":1371},[1050,8771,8772],{"class":1352},"models ",[1050,8774,1349],{"class":1348},[1050,8776,8777],{"class":1352}," User\n",[1050,8779,8780,8783,8785,8788,8790,8793,8795,8798,8800,8802,8805,8807,8809,8811,8814,8816,8818,8820,8823,8825],{"class":1052,"line":2427},[1050,8781,8782],{"class":1352},"        user ",[1050,8784,1911],{"class":1371},[1050,8786,8787],{"class":1352}," User",[1050,8789,1852],{"class":1371},[1050,8791,8792],{"class":1998},"objects",[1050,8794,1852],{"class":1371},[1050,8796,8797],{"class":1919},"create_user",[1050,8799,1923],{"class":1371},[1050,8801,1504],{"class":1503},[1050,8803,8804],{"class":1507},"testuser",[1050,8806,1504],{"class":1503},[1050,8808,1513],{"class":1371},[1050,8810,1516],{"class":1503},[1050,8812,8813],{"class":1507},"test@example.com",[1050,8815,1504],{"class":1503},[1050,8817,1513],{"class":1371},[1050,8819,1516],{"class":1503},[1050,8821,8822],{"class":1507},"testpass",[1050,8824,1504],{"class":1503},[1050,8826,1524],{"class":1371},[1050,8828,8829],{"class":1052,"line":2445},[1050,8830,2155],{"class":1352},[1050,8832,8833,8835,8837,8839,8841,8843,8845,8848,8850,8853,8855,8857,8860,8862,8864],{"class":1052,"line":2455},[1050,8834,2160],{"class":1352},[1050,8836,1911],{"class":1371},[1050,8838,2102],{"class":1367},[1050,8840,1852],{"class":1371},[1050,8842,8310],{"class":1998},[1050,8844,1852],{"class":1371},[1050,8846,8847],{"class":1919},"post",[1050,8849,1923],{"class":1371},[1050,8851,8852],{"class":1919},"reverse",[1050,8854,1923],{"class":1371},[1050,8856,1504],{"class":1503},[1050,8858,8859],{"class":1507},"login",[1050,8861,1504],{"class":1503},[1050,8863,4518],{"class":1371},[1050,8865,5291],{"class":1371},[1050,8867,8868,8870,8873,8875,8877,8879,8881,8883],{"class":1052,"line":2460},[1050,8869,2513],{"class":1503},[1050,8871,8872],{"class":1507},"username",[1050,8874,1504],{"class":1503},[1050,8876,2521],{"class":1371},[1050,8878,1516],{"class":1503},[1050,8880,8804],{"class":1507},[1050,8882,1504],{"class":1503},[1050,8884,2596],{"class":1371},[1050,8886,8887,8889,8892,8894,8896,8898,8900],{"class":1052,"line":2466},[1050,8888,2513],{"class":1503},[1050,8890,8891],{"class":1507},"password",[1050,8893,1504],{"class":1503},[1050,8895,2521],{"class":1371},[1050,8897,1516],{"class":1503},[1050,8899,8822],{"class":1507},[1050,8901,1548],{"class":1503},[1050,8903,8904,8907,8909,8911,8913],{"class":1052,"line":2510},[1050,8905,8906],{"class":1371},"        },",[1050,8908,8395],{"class":2503},[1050,8910,1911],{"class":1371},[1050,8912,8337],{"class":1375},[1050,8914,1524],{"class":1371},[1050,8916,8917],{"class":1052,"line":2538},[1050,8918,2155],{"class":1352},[1050,8920,8921],{"class":1052,"line":2579},[1050,8922,8923],{"class":1056},"        # Check session cookie\n",[1050,8925,8926,8929,8931,8933,8935,8938,8940,8942,8944,8946,8949,8951],{"class":1052,"line":2599},[1050,8927,8928],{"class":1352},"        session_cookie ",[1050,8930,1911],{"class":1371},[1050,8932,2214],{"class":1352},[1050,8934,1852],{"class":1371},[1050,8936,8937],{"class":1998},"cookies",[1050,8939,1852],{"class":1371},[1050,8941,2560],{"class":1919},[1050,8943,1923],{"class":1371},[1050,8945,1504],{"class":1503},[1050,8947,8948],{"class":1507},"sessionid",[1050,8950,1504],{"class":1503},[1050,8952,1524],{"class":1371},[1050,8954,8955,8957,8960],{"class":1052,"line":2605},[1050,8956,2099],{"class":1348},[1050,8958,8959],{"class":1352}," session_cookie",[1050,8961,1949],{"class":1371},[1050,8963,8964,8966,8968,8970,8972,8975,8977,8979,8982,8984],{"class":1052,"line":2610},[1050,8965,2200],{"class":1367},[1050,8967,1852],{"class":1371},[1050,8969,8439],{"class":1919},[1050,8971,1923],{"class":1371},[1050,8973,8974],{"class":1919},"session_cookie",[1050,8976,2880],{"class":1371},[1050,8978,1504],{"class":1503},[1050,8980,8981],{"class":1507},"secure",[1050,8983,1504],{"class":1503},[1050,8985,6675],{"class":1371},[1050,8987,8988],{"class":1052,"line":2616},[1050,8989,2155],{"class":1352},[1050,8991,8992],{"class":1052,"line":2659},[1050,8993,8994],{"class":1056},"        # Check CSRF cookie\n",[1050,8996,8997,9000,9002,9004,9006,9008,9010,9012,9014,9016,9019,9021],{"class":1052,"line":2664},[1050,8998,8999],{"class":1352},"        csrf_cookie ",[1050,9001,1911],{"class":1371},[1050,9003,2214],{"class":1352},[1050,9005,1852],{"class":1371},[1050,9007,8937],{"class":1998},[1050,9009,1852],{"class":1371},[1050,9011,2560],{"class":1919},[1050,9013,1923],{"class":1371},[1050,9015,1504],{"class":1503},[1050,9017,9018],{"class":1507},"csrftoken",[1050,9020,1504],{"class":1503},[1050,9022,1524],{"class":1371},[1050,9024,9025,9027,9030],{"class":1052,"line":2679},[1050,9026,2099],{"class":1348},[1050,9028,9029],{"class":1352}," csrf_cookie",[1050,9031,1949],{"class":1371},[1050,9033,9034,9036,9038,9040,9042,9045,9047,9049,9051,9053],{"class":1052,"line":2684},[1050,9035,2200],{"class":1367},[1050,9037,1852],{"class":1371},[1050,9039,8439],{"class":1919},[1050,9041,1923],{"class":1371},[1050,9043,9044],{"class":1919},"csrf_cookie",[1050,9046,2880],{"class":1371},[1050,9048,1504],{"class":1503},[1050,9050,8981],{"class":1507},[1050,9052,1504],{"class":1503},[1050,9054,6675],{"class":1371},[1050,9056,9057],{"class":1052,"line":2706},[1050,9058,1964],{"class":1352},[1050,9060,9061,9063,9066,9068,9070],{"class":1052,"line":2716},[1050,9062,1969],{"class":1941},[1050,9064,9065],{"class":2239}," test_security_headers",[1050,9067,1923],{"class":1371},[1050,9069,1979],{"class":1978},[1050,9071,1988],{"class":1371},[1050,9073,9074,9076,9079],{"class":1052,"line":2721},[1050,9075,2255],{"class":1076},[1050,9077,9078],{"class":1083},"Test security headers are present",[1050,9080,1077],{"class":1076},[1050,9082,9083],{"class":1052,"line":2727},[1050,9084,2155],{"class":1352},[1050,9086,9087,9089,9091,9093,9095,9097,9099,9101,9103,9105,9107,9109,9111,9113,9115,9117],{"class":1052,"line":2752},[1050,9088,2160],{"class":1352},[1050,9090,1911],{"class":1371},[1050,9092,2102],{"class":1367},[1050,9094,1852],{"class":1371},[1050,9096,8310],{"class":1998},[1050,9098,1852],{"class":1371},[1050,9100,2560],{"class":1919},[1050,9102,1923],{"class":1371},[1050,9104,1504],{"class":1503},[1050,9106,8388],{"class":1507},[1050,9108,1504],{"class":1503},[1050,9110,1513],{"class":1371},[1050,9112,8395],{"class":2503},[1050,9114,1911],{"class":1371},[1050,9116,8337],{"class":1375},[1050,9118,1524],{"class":1371},[1050,9120,9121],{"class":1052,"line":2777},[1050,9122,2155],{"class":1352},[1050,9124,9125],{"class":1052,"line":2783},[1050,9126,9127],{"class":1056},"        # Check for security headers\n",[1050,9129,9130,9132,9134,9136,9138,9140,9142,9144,9146,9148,9150,9152,9154,9156,9158,9160],{"class":1052,"line":2808},[1050,9131,1993],{"class":1367},[1050,9133,1852],{"class":1371},[1050,9135,8414],{"class":1919},[1050,9137,1923],{"class":1371},[1050,9139,6382],{"class":1919},[1050,9141,1852],{"class":1371},[1050,9143,2560],{"class":1919},[1050,9145,1923],{"class":1371},[1050,9147,1504],{"class":1503},[1050,9149,2919],{"class":1507},[1050,9151,1504],{"class":1503},[1050,9153,4518],{"class":1371},[1050,9155,1516],{"class":1503},[1050,9157,2930],{"class":1507},[1050,9159,1504],{"class":1503},[1050,9161,1524],{"class":1371},[1050,9163,9164,9166,9168,9170,9172,9174,9176,9178,9180,9182,9184,9186,9188,9190,9192,9194],{"class":1052,"line":2825},[1050,9165,1993],{"class":1367},[1050,9167,1852],{"class":1371},[1050,9169,8414],{"class":1919},[1050,9171,1923],{"class":1371},[1050,9173,6382],{"class":1919},[1050,9175,1852],{"class":1371},[1050,9177,2560],{"class":1919},[1050,9179,1923],{"class":1371},[1050,9181,1504],{"class":1503},[1050,9183,2944],{"class":1507},[1050,9185,1504],{"class":1503},[1050,9187,4518],{"class":1371},[1050,9189,1516],{"class":1503},[1050,9191,2955],{"class":1507},[1050,9193,1504],{"class":1503},[1050,9195,1524],{"class":1371},[1050,9197,9198,9200,9202,9204,9206,9208,9210,9212,9214,9216,9218,9220,9222,9224,9226,9228],{"class":1052,"line":2830},[1050,9199,1993],{"class":1367},[1050,9201,1852],{"class":1371},[1050,9203,8414],{"class":1919},[1050,9205,1923],{"class":1371},[1050,9207,6382],{"class":1919},[1050,9209,1852],{"class":1371},[1050,9211,2560],{"class":1919},[1050,9213,1923],{"class":1371},[1050,9215,1504],{"class":1503},[1050,9217,2969],{"class":1507},[1050,9219,1504],{"class":1503},[1050,9221,4518],{"class":1371},[1050,9223,1516],{"class":1503},[1050,9225,2980],{"class":1507},[1050,9227,1504],{"class":1503},[1050,9229,1524],{"class":1371},[1050,9231,9232],{"class":1052,"line":2855},[1050,9233,2155],{"class":1352},[1050,9235,9236,9239,9241,9243,9245,9247,9249,9251,9253,9255],{"class":1052,"line":2869},[1050,9237,9238],{"class":1352},"        referrer_policy ",[1050,9240,1911],{"class":1371},[1050,9242,2214],{"class":1352},[1050,9244,1852],{"class":1371},[1050,9246,2560],{"class":1919},[1050,9248,1923],{"class":1371},[1050,9250,1504],{"class":1503},[1050,9252,3027],{"class":1507},[1050,9254,1504],{"class":1503},[1050,9256,1524],{"class":1371},[1050,9258,9259,9261,9263,9265,9267,9270],{"class":1052,"line":2874},[1050,9260,1993],{"class":1367},[1050,9262,1852],{"class":1371},[1050,9264,8609],{"class":1919},[1050,9266,1923],{"class":1371},[1050,9268,9269],{"class":1919},"referrer_policy",[1050,9271,1524],{"class":1371},[1050,9273,9274],{"class":1052,"line":2898},[1050,9275,1064],{"emptyLinePlaceholder":1063},[1050,9277,9278,9280,9283,9285,9287],{"class":1052,"line":2903},[1050,9279,1942],{"class":1941},[1050,9281,9282],{"class":1945}," SSLCertificateTests",[1050,9284,1923],{"class":1371},[1050,9286,8273],{"class":3798},[1050,9288,1988],{"class":1371},[1050,9290,9291,9293,9296],{"class":1052,"line":2909},[1050,9292,1954],{"class":1076},[1050,9294,9295],{"class":1083},"Test SSL certificate validation",[1050,9297,1077],{"class":1076},[1050,9299,9300],{"class":1052,"line":2935},[1050,9301,1964],{"class":1352},[1050,9303,9304,9306,9309,9311,9313],{"class":1052,"line":2960},[1050,9305,1969],{"class":1941},[1050,9307,9308],{"class":2239}," test_certificate_validity",[1050,9310,1923],{"class":1371},[1050,9312,1979],{"class":1978},[1050,9314,1988],{"class":1371},[1050,9316,9317,9319,9322],{"class":1052,"line":2985},[1050,9318,2255],{"class":1076},[1050,9320,9321],{"class":1083},"Test SSL certificate is valid and properly configured",[1050,9323,1077],{"class":1076},[1050,9325,9326],{"class":1052,"line":2990},[1050,9327,2155],{"class":1352},[1050,9329,9330,9333],{"class":1052,"line":2996},[1050,9331,9332],{"class":1348},"        import",[1050,9334,3713],{"class":1352},[1050,9336,9337,9339],{"class":1052,"line":3018},[1050,9338,9332],{"class":1348},[1050,9340,3720],{"class":1352},[1050,9342,9343,9345,9347,9349],{"class":1052,"line":3044},[1050,9344,8755],{"class":1348},[1050,9346,3727],{"class":1352},[1050,9348,1349],{"class":1348},[1050,9350,9351],{"class":1352}," datetime\n",[1050,9353,9354],{"class":1052,"line":3049},[1050,9355,2155],{"class":1352},[1050,9357,9358,9360],{"class":1052,"line":3067},[1050,9359,4108],{"class":1348},[1050,9361,1949],{"class":1371},[1050,9363,9364],{"class":1052,"line":3077},[1050,9365,9366],{"class":1056},"            # Test certificate for your domain\n",[1050,9368,9369,9372,9374,9376,9378,9380],{"class":1052,"line":3106},[1050,9370,9371],{"class":1352},"            context ",[1050,9373,1911],{"class":1371},[1050,9375,4481],{"class":1352},[1050,9377,1852],{"class":1371},[1050,9379,4486],{"class":1919},[1050,9381,4489],{"class":1371},[1050,9383,9384],{"class":1052,"line":3116},[1050,9385,2780],{"class":1352},[1050,9387,9388,9390,9392,9394,9396,9398,9400,9402,9404,9406,9409,9411,9413,9415,9417,9419,9421,9423],{"class":1052,"line":3147},[1050,9389,4540],{"class":1348},[1050,9391,4501],{"class":1352},[1050,9393,1852],{"class":1371},[1050,9395,4506],{"class":1919},[1050,9397,4509],{"class":1371},[1050,9399,1504],{"class":1503},[1050,9401,1814],{"class":1507},[1050,9403,1504],{"class":1503},[1050,9405,1513],{"class":1371},[1050,9407,9408],{"class":1459}," 443",[1050,9410,4518],{"class":1371},[1050,9412,4521],{"class":2503},[1050,9414,1911],{"class":1371},[1050,9416,4526],{"class":1459},[1050,9418,2300],{"class":1371},[1050,9420,4368],{"class":1348},[1050,9422,4533],{"class":1352},[1050,9424,1949],{"class":1371},[1050,9426,9427,9430,9432,9434,9436,9438,9440,9442,9444,9446,9448,9450,9452,9454,9456,9458],{"class":1052,"line":3155},[1050,9428,9429],{"class":1348},"                with",[1050,9431,4543],{"class":1352},[1050,9433,1852],{"class":1371},[1050,9435,4548],{"class":1919},[1050,9437,1923],{"class":1371},[1050,9439,4553],{"class":1919},[1050,9441,1513],{"class":1371},[1050,9443,4558],{"class":2503},[1050,9445,1911],{"class":1371},[1050,9447,1504],{"class":1503},[1050,9449,1814],{"class":1507},[1050,9451,1504],{"class":1503},[1050,9453,2300],{"class":1371},[1050,9455,4368],{"class":1348},[1050,9457,4569],{"class":1352},[1050,9459,1949],{"class":1371},[1050,9461,9462,9465,9467,9469,9471,9473],{"class":1052,"line":3183},[1050,9463,9464],{"class":1352},"                    cert ",[1050,9466,1911],{"class":1371},[1050,9468,4569],{"class":1352},[1050,9470,1852],{"class":1371},[1050,9472,4585],{"class":1919},[1050,9474,4489],{"class":1371},[1050,9476,9477],{"class":1052,"line":3191},[1050,9478,2780],{"class":1352},[1050,9480,9481],{"class":1052,"line":3196},[1050,9482,9483],{"class":1056},"            # Check certificate expiration\n",[1050,9485,9486,9489,9491,9494,9496,9498,9500,9502],{"class":1052,"line":3202},[1050,9487,9488],{"class":1352},"            not_after ",[1050,9490,1911],{"class":1371},[1050,9492,9493],{"class":1352}," cert",[1050,9495,2880],{"class":1371},[1050,9497,1504],{"class":1503},[1050,9499,4653],{"class":1507},[1050,9501,1504],{"class":1503},[1050,9503,1828],{"class":1371},[1050,9505,9506,9509,9511,9513,9515,9517,9519,9521,9523,9525,9527,9529,9531,9533],{"class":1052,"line":3213},[1050,9507,9508],{"class":1352},"            expiry_date ",[1050,9510,1911],{"class":1371},[1050,9512,3732],{"class":1352},[1050,9514,1852],{"class":1371},[1050,9516,4671],{"class":1919},[1050,9518,1923],{"class":1371},[1050,9520,4676],{"class":1919},[1050,9522,1513],{"class":1371},[1050,9524,1516],{"class":1503},[1050,9526,4683],{"class":2485},[1050,9528,4686],{"class":2485},[1050,9530,4689],{"class":1507},[1050,9532,1504],{"class":1503},[1050,9534,1524],{"class":1371},[1050,9536,9537,9540,9542,9544,9546,9548,9550,9552,9554,9556],{"class":1052,"line":3226},[1050,9538,9539],{"class":1352},"            days_until_expiry ",[1050,9541,1911],{"class":1371},[1050,9543,1500],{"class":1371},[1050,9545,4714],{"class":1352},[1050,9547,4717],{"class":1615},[1050,9549,3732],{"class":1352},[1050,9551,1852],{"class":1371},[1050,9553,4724],{"class":1919},[1050,9555,4727],{"class":1371},[1050,9557,4730],{"class":1998},[1050,9559,9560],{"class":1052,"line":3232},[1050,9561,2780],{"class":1352},[1050,9563,9564],{"class":1052,"line":3237},[1050,9565,9566],{"class":1056},"            # Certificate should not expire within 30 days\n",[1050,9568,9569,9571,9573,9576,9578,9581,9583,9586,9588],{"class":1052,"line":3242},[1050,9570,2200],{"class":1367},[1050,9572,1852],{"class":1371},[1050,9574,9575],{"class":1919},"assertGreater",[1050,9577,1923],{"class":1371},[1050,9579,9580],{"class":1919},"days_until_expiry",[1050,9582,1513],{"class":1371},[1050,9584,9585],{"class":1459}," 30",[1050,9587,1513],{"class":1371},[1050,9589,3654],{"class":1919},[1050,9591,9592,9595,9598,9600,9602,9604,9607],{"class":1052,"line":3248},[1050,9593,9594],{"class":1941},"                             f",[1050,9596,9597],{"class":1507},"\"Certificate expires in ",[1050,9599,2486],{"class":2485},[1050,9601,9580],{"class":1919},[1050,9603,2495],{"class":2485},[1050,9605,9606],{"class":1507}," days\"",[1050,9608,1524],{"class":1371},[1050,9610,9611],{"class":1052,"line":3257},[1050,9612,2780],{"class":1352},[1050,9614,9615],{"class":1052,"line":3272},[1050,9616,9617],{"class":1056},"            # Check subject matches domain\n",[1050,9619,9620,9623,9625,9628,9630,9633,9635,9637,9639,9641,9644,9646,9648,9650,9652,9654,9656],{"class":1052,"line":3287},[1050,9621,9622],{"class":1352},"            subject ",[1050,9624,1911],{"class":1371},[1050,9626,9627],{"class":3879}," dict",[1050,9629,1923],{"class":1371},[1050,9631,9632],{"class":1919},"x",[1050,9634,2880],{"class":1371},[1050,9636,3142],{"class":1459},[1050,9638,2890],{"class":1371},[1050,9640,2303],{"class":1348},[1050,9642,9643],{"class":1919}," x ",[1050,9645,2309],{"class":1348},[1050,9647,9493],{"class":1919},[1050,9649,2880],{"class":1371},[1050,9651,1504],{"class":1503},[1050,9653,4872],{"class":1507},[1050,9655,1504],{"class":1503},[1050,9657,6675],{"class":1371},[1050,9659,9660,9662,9664,9666,9668,9670,9672,9674,9676,9679,9681,9683,9685,9687,9690,9692,9694,9696],{"class":1052,"line":3292},[1050,9661,2200],{"class":1367},[1050,9663,1852],{"class":1371},[1050,9665,8624],{"class":1919},[1050,9667,1923],{"class":1371},[1050,9669,1504],{"class":1503},[1050,9671,1814],{"class":1507},[1050,9673,1504],{"class":1503},[1050,9675,1513],{"class":1371},[1050,9677,9678],{"class":1919}," subject",[1050,9680,1852],{"class":1371},[1050,9682,2560],{"class":1919},[1050,9684,1923],{"class":1371},[1050,9686,1504],{"class":1503},[1050,9688,9689],{"class":1507},"commonName",[1050,9691,1504],{"class":1503},[1050,9693,1513],{"class":1371},[1050,9695,2574],{"class":1503},[1050,9697,8463],{"class":1371},[1050,9699,9700],{"class":1052,"line":3297},[1050,9701,2780],{"class":1352},[1050,9703,9704,9706,9708,9710,9712],{"class":1052,"line":3306},[1050,9705,4362],{"class":1348},[1050,9707,4365],{"class":3879},[1050,9709,4368],{"class":1348},[1050,9711,4371],{"class":1352},[1050,9713,1949],{"class":1371},[1050,9715,9716,9718,9720,9723,9725,9727,9730,9732,9734,9736,9738],{"class":1052,"line":3318},[1050,9717,2200],{"class":1367},[1050,9719,1852],{"class":1371},[1050,9721,9722],{"class":1919},"skipTest",[1050,9724,1923],{"class":1371},[1050,9726,2479],{"class":1941},[1050,9728,9729],{"class":1507},"\"Could not test certificate: ",[1050,9731,2486],{"class":2485},[1050,9733,4421],{"class":1919},[1050,9735,2495],{"class":2485},[1050,9737,2498],{"class":1507},[1050,9739,1524],{"class":1371},[1030,9741,9743],{"id":9742},"best-practices-summary","Best Practices Summary",[1035,9745,9747],{"id":9746},"https-implementation","HTTPS Implementation",[9749,9750,9751,9755,9758,9761],"ul",{},[9752,9753,9754],"li",{},"Always use HTTPS in production environments",[9752,9756,9757],{},"Implement proper certificate management and monitoring",[9752,9759,9760],{},"Configure secure cipher suites and protocols",[9752,9762,9763],{},"Use HTTP to HTTPS redirects for all traffic",[1035,9765,5059],{"id":9766},"hsts-configuration-1",[9749,9768,9769,9772,9775,9778],{},[9752,9770,9771],{},"Start with shorter HSTS max-age values and gradually increase",[9752,9773,9774],{},"Include subdomains in HSTS policy when appropriate",[9752,9776,9777],{},"Consider HSTS preloading for maximum security",[9752,9779,9780],{},"Monitor HSTS compliance and configuration",[1035,9782,9784],{"id":9783},"certificate-management","Certificate Management",[9749,9786,9787,9790,9793,9796],{},[9752,9788,9789],{},"Use automated certificate renewal (Let's Encrypt)",[9752,9791,9792],{},"Monitor certificate expiration dates",[9752,9794,9795],{},"Implement proper certificate validation",[9752,9797,9798],{},"Use strong key sizes (2048-bit RSA minimum, prefer ECDSA)",[1035,9800,9802],{"id":9801},"security-headers","Security Headers",[9749,9804,9805,9808,9811,9814],{},[9752,9806,9807],{},"Implement comprehensive security headers",[9752,9809,9810],{},"Use Content Security Policy for additional protection",[9752,9812,9813],{},"Configure proper referrer policies",[9752,9815,9816],{},"Regular security header audits and updates",[1030,9818,9820],{"id":9819},"next-steps","Next Steps",[1026,9822,9823],{},"Now that you understand HTTPS setup and HSTS, let's explore password storage and cryptography to ensure sensitive data is properly protected in Django applications.",[4242,9825,9826],{},"html pre.shiki code .s9Tkl, html code.shiki .s9Tkl{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#A0ADA0;--shiki-default-font-style:inherit;--shiki-dark:#758575DD;--shiki-dark-font-style:inherit}html pre.shiki code .sm7ve, html code.shiki .sm7ve{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#B5695977;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D77;--shiki-dark-font-style:inherit}html pre.shiki code .sVyVU, html code.shiki .sVyVU{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B56959;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .siDh9, html code.shiki .siDh9{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#1E754F;--shiki-default-font-style:inherit;--shiki-dark:#4D9375;--shiki-dark-font-style:inherit}html pre.shiki code .sftqT, html code.shiki .sftqT{--shiki-light:#90A4AE;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .se3Ec, html code.shiki .se3Ec{--shiki-light:#90A4AE;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .soVBu, html code.shiki .soVBu{--shiki-light:#39ADB5;--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .s8XtY, html code.shiki .s8XtY{--shiki-light:#39ADB5;--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .s7CZa, html code.shiki .s7CZa{--shiki-light:#F76D47;--shiki-default:#2F798A;--shiki-dark:#4C9A91}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .sVsLi, html code.shiki .sVsLi{--shiki-light:#39ADB5;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .siWMO, html code.shiki .siWMO{--shiki-light:#6182B8;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .s5Kfy, html code.shiki .s5Kfy{--shiki-light:#9C3EDA;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sD-vU, html code.shiki .sD-vU{--shiki-light:#E2931D;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .sJdAF, html code.shiki .sJdAF{--shiki-light:#6182B8;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sRjD_, html code.shiki .sRjD_{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sCyAa, html code.shiki .sCyAa{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sBPpx, html code.shiki .sBPpx{--shiki-light:#E53935;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .sljsM, html code.shiki .sljsM{--shiki-light:#6182B8;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .s3h35, html code.shiki .s3h35{--shiki-light:#F76D47;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sqOPj, html code.shiki .sqOPj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B07D48;--shiki-default-font-style:inherit;--shiki-dark:#BD976A;--shiki-dark-font-style:inherit}html pre.shiki code .sFGJz, html code.shiki .sFGJz{--shiki-light:#E53935;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sa2tF, html code.shiki .sa2tF{--shiki-light:#E2931D;--shiki-default:#998418;--shiki-dark:#B8A965}",{"title":1045,"searchDepth":1053,"depth":1060,"links":9828},[9829,9833,9838,9842,9847,9851,9854,9860],{"id":1032,"depth":1060,"text":1033,"children":9830},[9831,9832],{"id":1037,"depth":1067,"text":1038},{"id":1192,"depth":1067,"text":1193},{"id":1328,"depth":1060,"text":1329,"children":9834},[9835,9836,9837],{"id":1332,"depth":1067,"text":1333},{"id":1551,"depth":1067,"text":1552},{"id":1831,"depth":1067,"text":1832},{"id":3359,"depth":1060,"text":3360,"children":9839},[9840,9841],{"id":3363,"depth":1067,"text":3364},{"id":3695,"depth":1067,"text":3696},{"id":5054,"depth":1060,"text":5055,"children":9843},[9844,9845,9846],{"id":5058,"depth":1067,"text":5059},{"id":5207,"depth":1067,"text":5208},{"id":6006,"depth":1067,"text":6007},{"id":7632,"depth":1060,"text":7633,"children":9848},[9849,9850],{"id":7636,"depth":1067,"text":7637},{"id":7925,"depth":1067,"text":7926},{"id":8202,"depth":1060,"text":8203,"children":9852},[9853],{"id":8206,"depth":1067,"text":8207},{"id":9742,"depth":1060,"text":9743,"children":9855},[9856,9857,9858,9859],{"id":9746,"depth":1067,"text":9747},{"id":9766,"depth":1067,"text":5059},{"id":9783,"depth":1067,"text":9784},{"id":9801,"depth":1067,"text":9802},{"id":9819,"depth":1060,"text":9820},"md",null,{},{"title":567,"description":1028},"F1f5_-fY4upivQ35XaYAY4cdQ_mqHzhp6Ew-l-yNbpI",[9867,9869],{"title":563,"path":564,"stem":565,"description":9868,"children":-1},"Clickjacking is a malicious technique where attackers trick users into clicking on something different from what they perceive, potentially leading to unauthorized actions. Django provides built-in protection against clickjacking attacks through frame options and Content Security Policy headers.",{"title":571,"path":572,"stem":573,"description":9870,"children":-1},"Proper password storage and cryptographic practices are fundamental to application security. Django provides robust built-in password hashing and cryptographic utilities, but understanding how to use them correctly is crucial for protecting user data.",1772474939359]