URL Mapping, with and without mod_rewrite

Rich Bowen
Rich BowenCommunity Growth Hacker at SourceForge
mod_rewrite and
       friends
     URL Mapping Power Tools

     Rich Bowen - SourceForge
AKA: Oh, no, not
     yet another
mod_rewrite talk
      URL Mapping Power Tools

      Rich Bowen - SourceForge
URL Mapping

 What            Directory
                 (listing)
 does that
 URL mean?    Redirect

              Proxy
  File
              Error
  Handler
mod_rewrite

Gave that talk for the last four PHP|Tek
conferences

I think half of you attended those talks

So, what can we do that's different?
Although ...



       If you actually
   *wanted* a mod_rewrite
   talk, that can probably
         be arranged.
Let's start with the
interesting stuff


We can proceed to the boring stuff as we
have time.
<If>


New in 2.4

This is the reason you've been looking for
to upgrade to 2.4
Expressions




                                              Function by vestman, on Flickr
Mathematical statement which is either true
or false

Can consider any variable that interests
you
<If "%{HTTP_HOST} != 'www.example.com'">
    Redirect permanent / http://www.example.com
</If>




             <If> can be used in any
             context (server, vhost,
              directory, .htaccess)
Goodbye mod_rewrite

Doesn't replace mod_rewrite in *all*
contexts

But it does for many of the things you're
using it for

And it's much more readable, usually
So ...
Example: hotlinking

RewriteCond %{HTTP_REFERER} 
         !www.example.com [NC]
RewriteRule .(gif|jpg|png)$ - [F,NC]
Becomes:
                     Note: Shorter is not
                    always better. I think
                      this is *clearer*


<If "%{HTTP_REFERER} !~ www.example.com">
 <If "%{REQUEST_URI} =~ .(gif|jpg|png)$">
   Require all denied
 </If>
</If>
Also
<If "-R '10.1.0.0/16'">
  # ...
</If>
<ElseIf "-R '10.0.0.0/8'">
  # ...
</ElseIf>
<Else>
  # ...
</Else>
                 -R is like
        "%{REMOTE_ADDR} -ipmatch ..."
More later
We could give examples of this all day, but
let's move on to something else ...




                                      By Roby Ferrari, on Flickr
FallbackResource


New as of 2.2.16

You all need it
You've all seen this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
</IfModule>

# END WordPress
You've all seen this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
        This bit says "If mod_rewrite
 RewriteBase /
             is enabled", and is
 RewriteRule ^index.php$ - [L]
          completely unnecessary.
 RewriteCond %{REQUEST_FILENAME} !-f
         That's probably a rant for
 RewriteCond %{REQUEST_FILENAME} !-d
                another time.
 RewriteRule . /index.php [L]
</IfModule>

# END WordPress
You've all seen this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index.php$ - [L]
 RewriteCond Annoying bit to keep
             %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
              mod_rewrite happy
 RewriteRule . /index.php [L]
</IfModule>

# END WordPress
You've all seen this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
                 If it's already
 RewriteRule . /index.php [L]
            index.php, don't bother
</IfModule>

# END WordPress
You've all seen this:
# BEGIN WordPress
               If it's not a file, and it's
<IfModule mod_rewrite.c>
                 not a directory (ie, a
 RewriteEngine On
                     valid resource)
 RewriteBase /
 RewriteRule ^index.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
</IfModule>

# END WordPress
You've all seen this:
# BEGIN WordPress
               Send everything else to
<IfModule mod_rewrite.c>
                index.php as a "front
 RewriteEngine On
                     controller"
 RewriteBase /
 RewriteRule ^index.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
</IfModule>

# END WordPress
Or


FallbackResource /index.php
How it works


FallbackResource /index.php
         Triggers just before the error
          handlers, once other options
        have been checked. This ensures
        that existing resources (css, js,
        images, etc) continue to work as
                     desired.
How it works


FallbackResource /index.php


       Note that that's a URL path, not
        just a file name. Otherwise it
                 gets grumpy.
REQUEST_URI
FallbackResource /index.php
No need to rewrite
RewriteRule ^/(.*) /index.php?$1
# or something like that ...
                     Instead ...

   FallbackResource /index.php


$args = explode('/',
       $_SERVER['REQUEST_URI'] );
 Remember that the first character of a
        URL path is always "/"
Robert Fornal, on Flickr
        *Match

Directives: AliasMatch, RedirectMatch,
ProxyPassMatch

Containers: DirectoryMatch, LocationMatch,
FilesMatch
AliasMAtch

# Keep the images separate

AliasMatch ^/image/(.*).jpg$ 
             /files/jpg.images/$1.jpg
AliasMatch ^/image/(.*).gif$ 
             /files/gif.images/$1.gif
AliasMatch ^/image/(.*).png$ 
             /files/png.images/$1.gif
Case insensitive

 AliasMatch (?i)^/image(.*) 
   /ftp/pub/image$1
Everything but ...
RedirectMatch ^/(?!images/)(.*) 
       http://dynamic.myhost.com/$1
Everything but ...
RedirectMatch ^/(?!images/)(.*) 
       http://dynamic.myhost.com/$1



 This is called a zero-width
   assertion. Zero-width
because it doesn't capture a
        backreference
Everything but ...
RedirectMatch ^/(?!images/)(.*) 
       http://dynamic.myhost.com/$1




  Matches anything that
DOESN'T start with 'images/'
Everything but ...
RedirectMatch ^/(?!images/)(.*) 
       http://dynamic.myhost.com/$1




Result: Everything that's not
 an image goes over *there*
FilesMatch
 Recommended way to configure .php files
 with mod_php

<FilesMatch .php$>
 SetHandler application/x-httpd-php
</FilesMatch>
FilesMatch
 Recommended way to configure .php files
 with mod_php

<FilesMatch .php$>
 SetHandler application/x-httpd-php
</FilesMatch>


     Avoids .php.txt files being
       processed, for example
ProxyPassMatch


ProxyPassMatch ^/(.*.gif)$ 
  http://backend.example.com:8000/$1
ProxyPassMatch
  ProxyPassMatch ^/(.*.gif)$ 
    http://backend.example.com:8000/$1



   Security note: The target URL
shouldn't be modifiable by the URL. That is,
 there must not be any way that a cleverly
crafted URL could result in the target URL
        being something nefarious.
Consider:
ProxyPassMatch ^/(.*)$ 
 http://backend.example.com$1




          What if my URL was
   http://yourserver.com/.myserver.com/
Consider:
ProxyPassMatch ^/(.*)$ 
 http://backend.example.com$1




          What if my URL was
   http://yourserver.com/.myserver.com/
Consider:
ProxyPassMatch ^/(.*)$ 
 http://backend.example.com$1

                         Gotcha


            What if my URL was
http://backend.example.com.myserver.com/

http://yourserver.com/.myserver.com/index.php
Consider:
ProxyPassMatch ^/(.*)$ 
 http://backend.example.com$1


      Fortunately, this actually
         shouldn't work, since
  ProxyPassMatch will return a 500
     if the target URL isn't valid
   before the substitution. (ie, no
            trailing slash)
Oh, all right


We'll do some mod_rewrite stuff, because
you'd go home sad if I didn't.
Did you know ...


You can now use expr in RewriteCond, which
is practically magic
RewriteCond expr 
   "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule ^/images - [F]
New keyword 'expr'



RewriteCond expr 
   "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule ^/images - [F]
-strmatch is a glob,
    not a regex



RewriteCond expr 
   "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule ^/images - [F]
RewriteCond expr 
   "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule ^/images - [F]




         If the referer doesn't look
              like the source ...
RewriteCond expr 
   "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule ^/images - [F]




         Yes, this is yet another way
         to prevent "hot linking" of
                    images.
RewriteMap

Table-based lookup

More programmatic lookups

Database queries
Database rewrites
   RewriteMap supports database queries in 2.4


RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
Map Name




RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
Argument




RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
Default




RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
Query is prepared and executed,
  so sql injection is mitigated, but
    you still need to be careful.




RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
Use "fastdbd" to enable query
    caching, "dbd" to do without
               caching



RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
Default value if there's no
     returned value. If multiple
  values, one is selected randomly




RewriteMap myquery 
   "fastdbd:SELECT ID 
   FROM breeds WHERE name = %s"

RewriteRule ^/dogs/(.*) 
   /breeds.php?id=${myquery:$1|0} [PT]
mod_proxy_html

New module in 2.4

Was available as third-party module in
earlier versions

Simplifies proxying to a back-end app
mod_proxy_html


Proxying to internal server which is
closed-source, or that you don't have time
to monkey with

Generated HTML has fully-qualified URLs:
Client
http://app.local/




                    http://example.com/
                                          <html>
                                          <a href="http://
                                          app.local">
                                          Link</a>
                                          ...
mod_proxy_html


Fixes up the HTML

Also inspects cookies, and other headers,
and fixes those
mod_proxy_express


Another new module in 2.4

Simplifies the creation of proxying a bunch
of vhosts to back-end servers
##
##express-map.txt:
##

www1.example.com http://192.168.211.2:8080
www2.example.com http://192.168.211.12:8088
www3.example.com http://192.168.212.10
##
##express-map.txt:
##

www1.example.com http://192.168.211.2:8080
www2.example.com http://192.168.211.12:8088
www3.example.com http://192.168.212.10



  httxt2dbm -i express-map.txt -o emap




      ProxyExpressDBMFile emap
mod_proxy_express


Especially awesome for a bunch of VMs,
with a front-end proxy/cache server

Avoids having a jillion ProxyPass directives
or rewrite rules
And while we're on
the subject

mod_proxy_balancer is twice as caffeinated
as it used to be
mod_proxy_balancer

<Proxy balancer://mycluster>
    BalancerMember http://192.168.1.50:80
    BalancerMember http://192.168.1.51:80
</Proxy>

ProxyPass /test balancer://mycluster
ProxyPassReverse /test balancer://mycluster
Balance By ...

Busyness




                 SuperFantastic, on Flickr
Byrequests

Bytraffic

heartbeats
Heartbeats




                                     Mark McLaughlin, on Flickr
This is new

mod_heartmonitor and mod_heartbeat
verify that a server is alive, and now you
balance by what server is more idle
Fin

rbowen@geek.net

@rbowen

 https://joind.in/6509
1 of 70

Recommended

Apache mod_rewrite by
Apache mod_rewriteApache mod_rewrite
Apache mod_rewriteDave Ross
989 views14 slides
mod_rewrite by
mod_rewritemod_rewrite
mod_rewriteguest9912e5
11K views68 slides
Apache Rewrite Rules by
Apache Rewrite RulesApache Rewrite Rules
Apache Rewrite RulesAkhil Bansal
2.2K views13 slides
Modern Web Development with Perl by
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
32.3K views77 slides
Apache Hacks by
Apache HacksApache Hacks
Apache HacksBeth Skwarecki
2.8K views36 slides
Advanced Perl Techniques by
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
7.7K views182 slides

More Related Content

What's hot

Advanced Perl Techniques by
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
7.2K views156 slides
Xslate sv perl-2013-7-11 by
Xslate sv perl-2013-7-11Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Goro Fuji
2.8K views28 slides
You don’t know query - WordCamp UK Edinburgh 2012 by
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012l3rady
978 views53 slides
Php by
PhpPhp
Phpmohamed ashraf
445 views16 slides
You Don't Know Query (WordCamp Netherlands 2012) by
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)andrewnacin
62.3K views69 slides
Demystifying Object-Oriented Programming - ZendCon 2016 by
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Alena Holligan
524 views49 slides

What's hot(20)

Advanced Perl Techniques by Dave Cross
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross7.2K views
Xslate sv perl-2013-7-11 by Goro Fuji
Xslate sv perl-2013-7-11Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11
Goro Fuji2.8K views
You don’t know query - WordCamp UK Edinburgh 2012 by l3rady
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012
l3rady978 views
You Don't Know Query (WordCamp Netherlands 2012) by andrewnacin
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)
andrewnacin62.3K views
Demystifying Object-Oriented Programming - ZendCon 2016 by Alena Holligan
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
Alena Holligan524 views
HTML Templates Using Clear Silver by PaulWay
HTML Templates Using Clear SilverHTML Templates Using Clear Silver
HTML Templates Using Clear Silver
PaulWay2.4K views
Hack in the Box Keynote 2006 by Mark Curphey
Hack in the Box Keynote 2006Hack in the Box Keynote 2006
Hack in the Box Keynote 2006
Mark Curphey666 views
Perl6 Regexen: Reduce the line noise in your code. by Workhorse Computing
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
Ruby on Rails testing with Rspec by Bunlong Van
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
Bunlong Van1.9K views
Introduction to Modern Perl by Dave Cross
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern Perl
Dave Cross18K views
Supercharging WordPress Development in 2018 by Adam Tomat
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018
Adam Tomat212 views
関西PHP勉強会 php5.4つまみぐい by Hisateru Tanaka
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka2.6K views
Php and MySQL by Tiji Thomas
Php and MySQLPhp and MySQL
Php and MySQL
Tiji Thomas29.5K views
The Joy of Smartmatch by Andrew Shitov
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
Andrew Shitov1.2K views

Viewers also liked

XAJA - Reverse AJAX framework by
XAJA - Reverse AJAX frameworkXAJA - Reverse AJAX framework
XAJA - Reverse AJAX frameworkSri Prasanna
3.3K views12 slides
Htaccess file tutorial and tips by
Htaccess file tutorial and tipsHtaccess file tutorial and tips
Htaccess file tutorial and tipsImam Rosidi
902 views4 slides
Lithium: The Framework for People Who Hate Frameworks by
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
12.2K views123 slides
How to scale PHP applications by
How to scale PHP applicationsHow to scale PHP applications
How to scale PHP applicationsEnrico Zimuel
29.5K views39 slides
Vulnerable Active Record: A tale of SQL Injection in PHP Framework by
Vulnerable Active Record: A tale of SQL Injection in PHP FrameworkVulnerable Active Record: A tale of SQL Injection in PHP Framework
Vulnerable Active Record: A tale of SQL Injection in PHP FrameworkPichaya Morimoto
9.8K views13 slides
The Perils of Perception in 2016: Ipsos MORI by
The Perils of Perception in 2016: Ipsos MORIThe Perils of Perception in 2016: Ipsos MORI
The Perils of Perception in 2016: Ipsos MORIIpsos UK
424.1K views30 slides

Viewers also liked(20)

XAJA - Reverse AJAX framework by Sri Prasanna
XAJA - Reverse AJAX frameworkXAJA - Reverse AJAX framework
XAJA - Reverse AJAX framework
Sri Prasanna3.3K views
Htaccess file tutorial and tips by Imam Rosidi
Htaccess file tutorial and tipsHtaccess file tutorial and tips
Htaccess file tutorial and tips
Imam Rosidi902 views
Lithium: The Framework for People Who Hate Frameworks by Nate Abele
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele12.2K views
How to scale PHP applications by Enrico Zimuel
How to scale PHP applicationsHow to scale PHP applications
How to scale PHP applications
Enrico Zimuel29.5K views
Vulnerable Active Record: A tale of SQL Injection in PHP Framework by Pichaya Morimoto
Vulnerable Active Record: A tale of SQL Injection in PHP FrameworkVulnerable Active Record: A tale of SQL Injection in PHP Framework
Vulnerable Active Record: A tale of SQL Injection in PHP Framework
Pichaya Morimoto9.8K views
The Perils of Perception in 2016: Ipsos MORI by Ipsos UK
The Perils of Perception in 2016: Ipsos MORIThe Perils of Perception in 2016: Ipsos MORI
The Perils of Perception in 2016: Ipsos MORI
Ipsos UK424.1K views
By Phasse - Catalogue-ing by Kent Phan
By Phasse - Catalogue-ingBy Phasse - Catalogue-ing
By Phasse - Catalogue-ing
Kent Phan1.5K views
AmyandSusan by sgrobins
AmyandSusanAmyandSusan
AmyandSusan
sgrobins1.3K views
Learning organization may2010 by Michael Jones
Learning organization may2010Learning organization may2010
Learning organization may2010
Michael Jones366 views
Presentasi wwoooooooooooooookeeeeeeeee by Olga Tiara
Presentasi wwoooooooooooooookeeeeeeeeePresentasi wwoooooooooooooookeeeeeeeee
Presentasi wwoooooooooooooookeeeeeeeee
Olga Tiara1.4K views
Web Services Catalog by Rudolf Husar
Web Services CatalogWeb Services Catalog
Web Services Catalog
Rudolf Husar786 views
Nossa Experiência - Promott by promott12
Nossa Experiência - PromottNossa Experiência - Promott
Nossa Experiência - Promott
promott12435 views

Similar to URL Mapping, with and without mod_rewrite

CodeIgniter PHP MVC Framework by
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
27.4K views87 slides
Rush, a shell that will yield to you by
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to youguestdd9d06
744 views43 slides
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017) by
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
3.1K views94 slides
[Bristol WordPress] Supercharging WordPress Development by
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress DevelopmentAdam Tomat
889 views68 slides
Cloud Automation with Opscode Chef by
Cloud Automation with Opscode ChefCloud Automation with Opscode Chef
Cloud Automation with Opscode ChefSri Ram
351 views11 slides
Laying the proper foundation for plugin and theme development by
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentTammy Hart
1.3K views25 slides

Similar to URL Mapping, with and without mod_rewrite(20)

CodeIgniter PHP MVC Framework by Bo-Yi Wu
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu27.4K views
Rush, a shell that will yield to you by guestdd9d06
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to you
guestdd9d06744 views
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017) by James Titcumb
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb3.1K views
[Bristol WordPress] Supercharging WordPress Development by Adam Tomat
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
Adam Tomat889 views
Cloud Automation with Opscode Chef by Sri Ram
Cloud Automation with Opscode ChefCloud Automation with Opscode Chef
Cloud Automation with Opscode Chef
Sri Ram351 views
Laying the proper foundation for plugin and theme development by Tammy Hart
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
Tammy Hart1.3K views
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT) by Mike Schinkel
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Mike Schinkel10.5K views
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017) by James Titcumb
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
James Titcumb1.6K views
Your own (little) gem: building an online business with Ruby by Lindsay Holmwood
Your own (little) gem: building an online business with RubyYour own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with Ruby
Lindsay Holmwood1.1K views
Single Page Web Applications with CoffeeScript, Backbone and Jasmine by Paulo Ragonha
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha24.6K views
Zend Framework 1.9 Setup & Using Zend_Tool by Gordon Forsythe
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
Gordon Forsythe8.5K views
Childthemes ottawa-word camp-1919 by Paul Bearne
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919
Paul Bearne531 views
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017) by James Titcumb
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
James Titcumb1.5K views
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013) by arcware
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware4.2K views
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss... by King Foo
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
King Foo1.2K views
Nginx Workshop Aftermath by Denis Zhdanov
Nginx Workshop AftermathNginx Workshop Aftermath
Nginx Workshop Aftermath
Denis Zhdanov2.8K views
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি by Faysal Shahi
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটিWordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
Faysal Shahi706 views

More from Rich Bowen

The apacheway by
The apachewayThe apacheway
The apachewayRich Bowen
749 views51 slides
Why your employees should contribute to Open Source by
Why your employees should contribute to Open SourceWhy your employees should contribute to Open Source
Why your employees should contribute to Open SourceRich Bowen
3.3K views47 slides
Don't be a jerk by
Don't be a jerkDon't be a jerk
Don't be a jerkRich Bowen
3.1K views70 slides
Write A Better FM - Ohio Linux 2011 by
Write A Better FM - Ohio Linux 2011Write A Better FM - Ohio Linux 2011
Write A Better FM - Ohio Linux 2011Rich Bowen
1.1K views96 slides
mod_rewrite bootcamp, Ohio LInux 2011 by
mod_rewrite bootcamp, Ohio LInux 2011mod_rewrite bootcamp, Ohio LInux 2011
mod_rewrite bootcamp, Ohio LInux 2011Rich Bowen
4.6K views208 slides
Apache Wizardry - Ohio Linux 2011 by
Apache Wizardry - Ohio Linux 2011Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011Rich Bowen
4.4K views198 slides

More from Rich Bowen(8)

The apacheway by Rich Bowen
The apachewayThe apacheway
The apacheway
Rich Bowen749 views
Why your employees should contribute to Open Source by Rich Bowen
Why your employees should contribute to Open SourceWhy your employees should contribute to Open Source
Why your employees should contribute to Open Source
Rich Bowen3.3K views
Don't be a jerk by Rich Bowen
Don't be a jerkDon't be a jerk
Don't be a jerk
Rich Bowen3.1K views
Write A Better FM - Ohio Linux 2011 by Rich Bowen
Write A Better FM - Ohio Linux 2011Write A Better FM - Ohio Linux 2011
Write A Better FM - Ohio Linux 2011
Rich Bowen1.1K views
mod_rewrite bootcamp, Ohio LInux 2011 by Rich Bowen
mod_rewrite bootcamp, Ohio LInux 2011mod_rewrite bootcamp, Ohio LInux 2011
mod_rewrite bootcamp, Ohio LInux 2011
Rich Bowen4.6K views
Apache Wizardry - Ohio Linux 2011 by Rich Bowen
Apache Wizardry - Ohio Linux 2011Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Rich Bowen4.4K views
Write a better FM by Rich Bowen
Write a better FMWrite a better FM
Write a better FM
Rich Bowen789 views
Apache Cookbook - TekX Chicago 2010 by Rich Bowen
Apache Cookbook - TekX Chicago 2010Apache Cookbook - TekX Chicago 2010
Apache Cookbook - TekX Chicago 2010
Rich Bowen2.8K views

Recently uploaded

Uni Systems for Power Platform.pptx by
Uni Systems for Power Platform.pptxUni Systems for Power Platform.pptx
Uni Systems for Power Platform.pptxUni Systems S.M.S.A.
50 views21 slides
Black and White Modern Science Presentation.pptx by
Black and White Modern Science Presentation.pptxBlack and White Modern Science Presentation.pptx
Black and White Modern Science Presentation.pptxmaryamkhalid2916
14 views21 slides
Web Dev - 1 PPT.pdf by
Web Dev - 1 PPT.pdfWeb Dev - 1 PPT.pdf
Web Dev - 1 PPT.pdfgdsczhcet
55 views45 slides
PharoJS - Zürich Smalltalk Group Meetup November 2023 by
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023Noury Bouraqadi
120 views17 slides
Data-centric AI and the convergence of data and model engineering: opportunit... by
Data-centric AI and the convergence of data and model engineering:opportunit...Data-centric AI and the convergence of data and model engineering:opportunit...
Data-centric AI and the convergence of data and model engineering: opportunit...Paolo Missier
34 views40 slides
Throughput by
ThroughputThroughput
ThroughputMoisés Armani Ramírez
36 views11 slides

Recently uploaded(20)

Black and White Modern Science Presentation.pptx by maryamkhalid2916
Black and White Modern Science Presentation.pptxBlack and White Modern Science Presentation.pptx
Black and White Modern Science Presentation.pptx
maryamkhalid291614 views
Web Dev - 1 PPT.pdf by gdsczhcet
Web Dev - 1 PPT.pdfWeb Dev - 1 PPT.pdf
Web Dev - 1 PPT.pdf
gdsczhcet55 views
PharoJS - Zürich Smalltalk Group Meetup November 2023 by Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi120 views
Data-centric AI and the convergence of data and model engineering: opportunit... by Paolo Missier
Data-centric AI and the convergence of data and model engineering:opportunit...Data-centric AI and the convergence of data and model engineering:opportunit...
Data-centric AI and the convergence of data and model engineering: opportunit...
Paolo Missier34 views
Special_edition_innovator_2023.pdf by WillDavies22
Special_edition_innovator_2023.pdfSpecial_edition_innovator_2023.pdf
Special_edition_innovator_2023.pdf
WillDavies2216 views
DALI Basics Course 2023 by Ivory Egg
DALI Basics Course  2023DALI Basics Course  2023
DALI Basics Course 2023
Ivory Egg14 views
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen... by NUS-ISS
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...
NUS-ISS28 views
SAP Automation Using Bar Code and FIORI.pdf by Virendra Rai, PMP
SAP Automation Using Bar Code and FIORI.pdfSAP Automation Using Bar Code and FIORI.pdf
SAP Automation Using Bar Code and FIORI.pdf
Emerging & Future Technology - How to Prepare for the Next 10 Years of Radica... by NUS-ISS
Emerging & Future Technology - How to Prepare for the Next 10 Years of Radica...Emerging & Future Technology - How to Prepare for the Next 10 Years of Radica...
Emerging & Future Technology - How to Prepare for the Next 10 Years of Radica...
NUS-ISS16 views
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors by sugiuralab
TouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective SensorsTouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective Sensors
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors
sugiuralab15 views
Spesifikasi Lengkap ASUS Vivobook Go 14 by Dot Semarang
Spesifikasi Lengkap ASUS Vivobook Go 14Spesifikasi Lengkap ASUS Vivobook Go 14
Spesifikasi Lengkap ASUS Vivobook Go 14
Dot Semarang35 views
The Importance of Cybersecurity for Digital Transformation by NUS-ISS
The Importance of Cybersecurity for Digital TransformationThe Importance of Cybersecurity for Digital Transformation
The Importance of Cybersecurity for Digital Transformation
NUS-ISS27 views
Beyond the Hype: What Generative AI Means for the Future of Work - Damien Cum... by NUS-ISS
Beyond the Hype: What Generative AI Means for the Future of Work - Damien Cum...Beyond the Hype: What Generative AI Means for the Future of Work - Damien Cum...
Beyond the Hype: What Generative AI Means for the Future of Work - Damien Cum...
NUS-ISS34 views
How the World's Leading Independent Automotive Distributor is Reinventing Its... by NUS-ISS
How the World's Leading Independent Automotive Distributor is Reinventing Its...How the World's Leading Independent Automotive Distributor is Reinventing Its...
How the World's Leading Independent Automotive Distributor is Reinventing Its...
NUS-ISS15 views

URL Mapping, with and without mod_rewrite

  • 1. mod_rewrite and friends URL Mapping Power Tools Rich Bowen - SourceForge
  • 2. AKA: Oh, no, not yet another mod_rewrite talk URL Mapping Power Tools Rich Bowen - SourceForge
  • 3. URL Mapping What Directory (listing) does that URL mean? Redirect Proxy File Error Handler
  • 4. mod_rewrite Gave that talk for the last four PHP|Tek conferences I think half of you attended those talks So, what can we do that's different?
  • 5. Although ... If you actually *wanted* a mod_rewrite talk, that can probably be arranged.
  • 6. Let's start with the interesting stuff We can proceed to the boring stuff as we have time.
  • 7. <If> New in 2.4 This is the reason you've been looking for to upgrade to 2.4
  • 8. Expressions Function by vestman, on Flickr Mathematical statement which is either true or false Can consider any variable that interests you
  • 9. <If "%{HTTP_HOST} != 'www.example.com'"> Redirect permanent / http://www.example.com </If> <If> can be used in any context (server, vhost, directory, .htaccess)
  • 10. Goodbye mod_rewrite Doesn't replace mod_rewrite in *all* contexts But it does for many of the things you're using it for And it's much more readable, usually
  • 12. Example: hotlinking RewriteCond %{HTTP_REFERER} !www.example.com [NC] RewriteRule .(gif|jpg|png)$ - [F,NC]
  • 13. Becomes: Note: Shorter is not always better. I think this is *clearer* <If "%{HTTP_REFERER} !~ www.example.com"> <If "%{REQUEST_URI} =~ .(gif|jpg|png)$"> Require all denied </If> </If>
  • 14. Also <If "-R '10.1.0.0/16'"> # ... </If> <ElseIf "-R '10.0.0.0/8'"> # ... </ElseIf> <Else> # ... </Else> -R is like "%{REMOTE_ADDR} -ipmatch ..."
  • 15. More later We could give examples of this all day, but let's move on to something else ... By Roby Ferrari, on Flickr
  • 16. FallbackResource New as of 2.2.16 You all need it
  • 17. You've all seen this: # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
  • 18. You've all seen this: # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On This bit says "If mod_rewrite RewriteBase / is enabled", and is RewriteRule ^index.php$ - [L] completely unnecessary. RewriteCond %{REQUEST_FILENAME} !-f That's probably a rant for RewriteCond %{REQUEST_FILENAME} !-d another time. RewriteRule . /index.php [L] </IfModule> # END WordPress
  • 19. You've all seen this: # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond Annoying bit to keep %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d mod_rewrite happy RewriteRule . /index.php [L] </IfModule> # END WordPress
  • 20. You've all seen this: # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d If it's already RewriteRule . /index.php [L] index.php, don't bother </IfModule> # END WordPress
  • 21. You've all seen this: # BEGIN WordPress If it's not a file, and it's <IfModule mod_rewrite.c> not a directory (ie, a RewriteEngine On valid resource) RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
  • 22. You've all seen this: # BEGIN WordPress Send everything else to <IfModule mod_rewrite.c> index.php as a "front RewriteEngine On controller" RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
  • 24. How it works FallbackResource /index.php Triggers just before the error handlers, once other options have been checked. This ensures that existing resources (css, js, images, etc) continue to work as desired.
  • 25. How it works FallbackResource /index.php Note that that's a URL path, not just a file name. Otherwise it gets grumpy.
  • 27. No need to rewrite RewriteRule ^/(.*) /index.php?$1 # or something like that ... Instead ... FallbackResource /index.php $args = explode('/', $_SERVER['REQUEST_URI'] ); Remember that the first character of a URL path is always "/"
  • 28. Robert Fornal, on Flickr *Match Directives: AliasMatch, RedirectMatch, ProxyPassMatch Containers: DirectoryMatch, LocationMatch, FilesMatch
  • 29. AliasMAtch # Keep the images separate AliasMatch ^/image/(.*).jpg$ /files/jpg.images/$1.jpg AliasMatch ^/image/(.*).gif$ /files/gif.images/$1.gif AliasMatch ^/image/(.*).png$ /files/png.images/$1.gif
  • 30. Case insensitive AliasMatch (?i)^/image(.*) /ftp/pub/image$1
  • 31. Everything but ... RedirectMatch ^/(?!images/)(.*) http://dynamic.myhost.com/$1
  • 32. Everything but ... RedirectMatch ^/(?!images/)(.*) http://dynamic.myhost.com/$1 This is called a zero-width assertion. Zero-width because it doesn't capture a backreference
  • 33. Everything but ... RedirectMatch ^/(?!images/)(.*) http://dynamic.myhost.com/$1 Matches anything that DOESN'T start with 'images/'
  • 34. Everything but ... RedirectMatch ^/(?!images/)(.*) http://dynamic.myhost.com/$1 Result: Everything that's not an image goes over *there*
  • 35. FilesMatch Recommended way to configure .php files with mod_php <FilesMatch .php$> SetHandler application/x-httpd-php </FilesMatch>
  • 36. FilesMatch Recommended way to configure .php files with mod_php <FilesMatch .php$> SetHandler application/x-httpd-php </FilesMatch> Avoids .php.txt files being processed, for example
  • 37. ProxyPassMatch ProxyPassMatch ^/(.*.gif)$ http://backend.example.com:8000/$1
  • 38. ProxyPassMatch ProxyPassMatch ^/(.*.gif)$ http://backend.example.com:8000/$1 Security note: The target URL shouldn't be modifiable by the URL. That is, there must not be any way that a cleverly crafted URL could result in the target URL being something nefarious.
  • 39. Consider: ProxyPassMatch ^/(.*)$ http://backend.example.com$1 What if my URL was http://yourserver.com/.myserver.com/
  • 40. Consider: ProxyPassMatch ^/(.*)$ http://backend.example.com$1 What if my URL was http://yourserver.com/.myserver.com/
  • 41. Consider: ProxyPassMatch ^/(.*)$ http://backend.example.com$1 Gotcha What if my URL was http://backend.example.com.myserver.com/ http://yourserver.com/.myserver.com/index.php
  • 42. Consider: ProxyPassMatch ^/(.*)$ http://backend.example.com$1 Fortunately, this actually shouldn't work, since ProxyPassMatch will return a 500 if the target URL isn't valid before the substitution. (ie, no trailing slash)
  • 43. Oh, all right We'll do some mod_rewrite stuff, because you'd go home sad if I didn't.
  • 44. Did you know ... You can now use expr in RewriteCond, which is practically magic
  • 45. RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule ^/images - [F]
  • 46. New keyword 'expr' RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule ^/images - [F]
  • 47. -strmatch is a glob, not a regex RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule ^/images - [F]
  • 48. RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule ^/images - [F] If the referer doesn't look like the source ...
  • 49. RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule ^/images - [F] Yes, this is yet another way to prevent "hot linking" of images.
  • 51. Database rewrites RewriteMap supports database queries in 2.4 RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 52. Map Name RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 53. Argument RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 54. Default RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 55. Query is prepared and executed, so sql injection is mitigated, but you still need to be careful. RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 56. Use "fastdbd" to enable query caching, "dbd" to do without caching RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 57. Default value if there's no returned value. If multiple values, one is selected randomly RewriteMap myquery "fastdbd:SELECT ID FROM breeds WHERE name = %s" RewriteRule ^/dogs/(.*) /breeds.php?id=${myquery:$1|0} [PT]
  • 58. mod_proxy_html New module in 2.4 Was available as third-party module in earlier versions Simplifies proxying to a back-end app
  • 59. mod_proxy_html Proxying to internal server which is closed-source, or that you don't have time to monkey with Generated HTML has fully-qualified URLs:
  • 60. Client http://app.local/ http://example.com/ <html> <a href="http:// app.local"> Link</a> ...
  • 61. mod_proxy_html Fixes up the HTML Also inspects cookies, and other headers, and fixes those
  • 62. mod_proxy_express Another new module in 2.4 Simplifies the creation of proxying a bunch of vhosts to back-end servers
  • 64. ## ##express-map.txt: ## www1.example.com http://192.168.211.2:8080 www2.example.com http://192.168.211.12:8088 www3.example.com http://192.168.212.10 httxt2dbm -i express-map.txt -o emap ProxyExpressDBMFile emap
  • 65. mod_proxy_express Especially awesome for a bunch of VMs, with a front-end proxy/cache server Avoids having a jillion ProxyPass directives or rewrite rules
  • 66. And while we're on the subject mod_proxy_balancer is twice as caffeinated as it used to be
  • 67. mod_proxy_balancer <Proxy balancer://mycluster> BalancerMember http://192.168.1.50:80 BalancerMember http://192.168.1.51:80 </Proxy> ProxyPass /test balancer://mycluster ProxyPassReverse /test balancer://mycluster
  • 68. Balance By ... Busyness SuperFantastic, on Flickr Byrequests Bytraffic heartbeats
  • 69. Heartbeats Mark McLaughlin, on Flickr This is new mod_heartmonitor and mod_heartbeat verify that a server is alive, and now you balance by what server is more idle

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n