Help me set URL using .htaccess in CodeIgniter - .htaccess

I use CodeIgniter and I want to set URL by htaccess. I have tried many ways but have not succeeded yet.
My folder structure :
--application
----corntrollers
-------public
----------home.php
----------log
-------------- login.php
-------admin
----views
-------public
----------home.tpl
----------log
-------------- login.tpl
--system
--mysite
I want to set URL to rewrite :
http://localhost/mysite/index.php/log/login
=>
http://localhost/mysite/log-in
How can I do that ?

Enable url rewriting module of Apache2:
a2enmod rewrite
Change /config/config.php
$config['index_page'] = "index.php";
to
$config['index_page'] = "";
As well
$config['uri_protocol'] = 'AUTO';
to
$config['uri_protocol'] = 'REQUEST_URI';
The correct way of .htaccess is:
#AddHandler application/x-httpd-php5 .php
<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteBase /
#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 index.php
</IfModule>
php_flag short_open_tag on
<FilesMatch "\.(php)$">
FileETag None
<IfModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</IfModule>
</FilesMatch>
Restar Apache2 Service:
sudo systemctl restart apache2.service
Hope that helps.

First of all make sure url rewriting is enabled and then create .htaccess file with code below.
DirectoryIndex index.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
Then in /config/config.php
/*
|--------------------------------------------------------------------------
| Index File
|--------------------------------------------------------------------------
|
| Typically this will be your index.php file, unless you've renamed it to
| something else. If you are using mod_rewrite to remove the page set this
| variable so that it is blank.
|
*/
$config['index_page'] = 'index.php';
change
$config['index_page']
to
$config['index_page'] = '';
Next in
/config/routes.php
$route['log-in'] = "log/log-in";

Related

How do I correctly handle multiple capturing groups in .htaccess?

I'm trying to get:
example.com/curriculum/<curriculum name>/unit/<unit name>/
to rewrite to:
example.com/curriculum/unit/?c=<curriculum name>&u=<unit name>
so far I have:
RewriteRule ^/curriculum/([A-Za-z0-9_-]+)/unit/([A-Za-z0-9_-]+)/?$ https://www.example.com/curriculum/unit/?c=$1&u=$2
Considering that:
RewriteRule ^curriculum/([A-Za-z0-9_-]+)/?$ https://www.example.com/curriculum/?c=$1
works as expected, I assume my syntax is off, as when loading, I just get error 404, with the URL not rewritten from its original format. To clarify, /curriculum/unit does exist.
Any guidance or advice on what I need to do to make this work? Thanks!
Update
Full .htaccess file as requested:
### activate mod_expires
ExpiresActive On
### Expire .gif's 1 month from when they're accessed
ExpiresByType image/gif A2592000
### Expire everything else 1 day from when it's last modified
### (this uses the Alternative syntax)
ExpiresDefault "modification plus 1 day"
### Apply a Cache-Control header to index.html and styles.css
###Cross-Site Scripting protection
Header always set X-Xss-Protection "1; mode=block"
###Disallow websites to frame legacycars - user protection
Header always append X-Frame-Options SAMEORIGIN
<IfModule mod_headers.c>
#No Cache browser revalidates on each request and fetches new version IF contents change based on ETag or Last-Modified response
<FilesMatch "\.(html|php)$">
Header set Cache-Control "no-cache"
</FilesMatch>
#DAY Stock and Cover images expire at the end of each day, but must be checked for changes
<FilesMatch "\.(jpg|jpeg)$">
Header set Cache-Control "max-age=86400, public, must-revalidate"
</FilesMatch>
#WEEK Icons and badges expire after a week
<FilesMatch "\.(ico|png|gif|swf|svg|xml)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
#MONTH Site framework expires after a month, but must be checked for changes
<FilesMatch "\.(js|css|json)$">
Header set Cache-Control "max-age=2628000, public, must-revalidate"
</FilesMatch>
#Hide .credentials
<FilesMatch ".credentials.php">
Order allow,deny
Deny from all
</FilesMatch>
Options +FollowSymLinks -MultiViews
ErrorDocument 404 https://www.example.com/error/404.html
ErrorDocument 403 https:/www.example.com/error/403.html
# Turn mod_rewrite on
RewriteEngine On
#Rewrite curriculum and unit to GET vars
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^curriculum/([\w-]+)/unit/([\w-]+)/?$ curriculum/unit/?c=$1&u=$2 [L,QSA,NC]
RewriteRule ^curriculum/([\w-]+)/?$ curriculum/?c=$1 [L,QSA,NC]
# Externally redirect direct client requests for subdomain-subdirectory URLs
# to subdomain URLs without subdomain-subdirectory URL-path
Redirect permanent /sd_manage/ https://manage.example.com
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^manage(.*)$ https://manage.example.com [R=301,L]
RewriteRule ^manage/(.*)$ https://manage.example.com/$1 [R=301,L]
# Rewrite root subdomain to www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
# Rewrite valid subdomains to the secure site
RewriteCond %{HTTPS} off
# RewriteCond %{HTTP_HOST} ^(www|manage)\.example\.com$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
</IfModule>
# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php71” package as the default “PHP” programming language.
<IfModule mime_module>
AddHandler application/x-httpd-ea-php71 .php .php7 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit
You may keep these 2 rewrite rules:
ErrorDocument 404 /error/404.html
ErrorDocument 403 /error/403.html
Options +FollowSymLinks -MultiViews
RewriteEngine On
# Externally redirect direct client requests for subdomain-subdirectory URLs
# to subdomain URLs without subdomain-subdirectory URL-path
RewriteRule ^sd_manage/ https://manage.example.com [L,R=301,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.com$ [NC]
RewriteRule ^manage(/.*)?$ https://manage.example.com$1 [R=301,L,NC,NE]
# Rewrite root subdomain to www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# Rewrite valid subdomains to the secure site
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
#Rewrite curriculum and unit to GET vars
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^curriculum/([\w-]+)/?$ curriculum/?c=$1 [L,QSA,NC]
RewriteRule ^curriculum/([\w-]+)/unit/([\w-]+)/?$ curriculum/unit/?c=$1&u=$2 [L,QSA,NC]

htaccess 301 redirect with GET doesn't work

What I want to achieve is the following:
URL /element.php?dogtag=tdcf_tdcbusiness_ak should redirect to /ajankohtaista
I have the following .htaccess:
RewriteCond %{QUERY_STRING} dogtag=tdcf_tdcbusiness_ak
RewriteRule ^element\.php$ /ajankohtaista/? [L,R=301]
But it doesn't work. Any clue what I am missing ?
EDIT: here is my full .htaccess:
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$">
Order allow,deny
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php index.html index.htm
# Override PHP settings that cannot be changed at runtime. See
# sites/default/default.settings.php and drupal_environment_initialize() in
# includes/bootstrap.inc for settings that can be changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_flag magic_quotes_gpc off
php_flag magic_quotes_sybase off
php_flag register_globals off
php_flag session.auto_start off
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_flag mbstring.encoding_translation off
</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
ExpiresActive Off
</FilesMatch>
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule "(^|/)\." - [F]
# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
RewriteCond %{QUERY_STRING} dogtag=tdcf_tdcbusiness_ak
RewriteRule ^element\.php$ /ajankohtaista/? [L,R=301]
# Rules to correctly serve gzip compressed CSS and JS files.
# Requires both mod_rewrite and mod_headers to be enabled.
<IfModule mod_headers.c>
# Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
# Serve correct encoding type.
Header set Content-Encoding gzip
# Force proxies to cache gzipped & non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
</IfModule>
I think you don't have element.php file anymore (it does not exist).
Because of that, it is rewritten to index.php regarding on your previous rule.
An easy solution would be to swap your two rules.
This part
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
RewriteCond %{QUERY_STRING} dogtag=tdcf_tdcbusiness_ak
RewriteRule ^element\.php$ /ajankohtaista/? [L,R=301]
should be like this
RewriteCond %{QUERY_STRING} dogtag=tdcf_tdcbusiness_ak
RewriteRule ^element\.php$ /ajankohtaista [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]

Removing index.php in CodeIgniter using .htaccess file

I'm currently developing a website using CodeIgniter and I recently stumbled upon a routing & .htaccess problem.
Basically, the structure of my simple website (let's call my project 'CIExample' for the sake of simplicity) is as follow:
-Home
-About Us
-Our Service
-News
-Contact Us
which I implemented using a Page controller. This controller has 5 functions which called respective page's view, i.e:
Home(), which calls the view 'Home'
About(), which calls the view 'About Us' and so on..
Previously, to access 'Home', I would need to type http://localhost/CIExample/index.php/page/home into the url window, but after setting the following routes I was able to remove the 'page' (classname) part:
$route['default_controller'] = 'page/home';
$route['home'] = 'page/home';
$route['about'] = 'page/about';
$route['service'] = 'page/service';
$route['news'] = 'page/news';
$route['contact'] = 'page/contact';
However, the tricky part came when I try to remove the 'index.php'.
I want to be able to access the home page by typing http://localhost/CIExample/home.
So I did a lot of searches on CI forum/tutorial/stack overflow, and found some codes for .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
or http://ellislab.com/forums/viewthread/197675/#929904
I tried both codes but none works..
http://localhost/CIExample/home would direct me to 404 not found page, but http://localhost/CIExample/index.php/home would work just fine.
I wonder what went wrongs? Is it my routes.php or .htaccess or both?
Thanks.
Note: I've also changed my 'config/config.php' file -> $config['index_page'] = '';
EDIT:
Finally it works!
After tweaking the config.php file in config folder and set the following $config['uri_protocol'] = 'PATH_INFO'; (from 'AUTO').
Available Values:
| 'AUTO' Default - auto detects
| 'PATH_INFO' Uses the PATH_INFO
| 'QUERY_STRING' Uses the QUERY_STRING
| 'REQUEST_URI' Uses the REQUEST_URI
| 'ORIG_PATH_INFO' Uses the ORIG_PATH_INFO
Dunno what's the different but according to one of the comments in http://www.jotorres.com/2011/12/removing-index-php-from-url-in-codeigniter/, the same code might/might not work in the production server.
Anyone can explain the reason maybe?
You just need to paste this in your .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</IfModule>
and make this alternation to your application/config/config.php file:
$config['index_page'] = '';
I have use following method, it is working perfectly in UBUNTU...!!
First of all verify that you have enabled mod_rewrite (you can verify using phpinfo()) in your index.php file.
IF DISABLED mod_rewrite then RUN:
1. sudo a2enmod rewrite
2. sudo gedit /etc/apache2/sites-available/defaut
just replace "AllowOverride None" to "AllowOverride All" in Tag(<'Directory /var/www/'>)
3. Then please run sudo service apache2 restart
Ok Good...
Now in your root directory of Codeigniter -> Find .htaccess file, if not found then press ctrl+h , still not found then create a file .htaccess
In .htaccess
Paste following code :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /ROOT DIRECTORY NAME/
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
Ok finally just replace ROOT DIRECTORY NAME
DONT FORGOT TO REMOVE index.php from application/config/config.php file
Make that line like
$config['index_page'] = '';
I use this htaccess for all my CodeIgniter projects. It supports subfolders too.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#When your application folder isn't in the system folder
#This snippet prevents user access to the application folder
#Submitted by: Fabdrol
#Rename 'application' to your applications folder name.
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
</IfModule>
In your system/application/config/config.php, Change
$config['index_page'] = "index.php";
To
$config['index_page'] = "";
And in your .htaccess,add this:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|stylesheets|scripts|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
for Codeigniter 3.1.4
# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php56” package as the default “PHP” programming language.
<IfModule mime_module>
AddType application/x-httpd-ea-php56 .php .php5 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit
# BEGIN cPanel-generated php ini directives, do not edit
# Manual editing of this file may result in unexpected behavior.
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
# For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
<IfModule php5_module>
php_flag asp_tags On
php_flag display_errors On
php_value max_execution_time 30
php_value max_input_time 60
php_value max_input_vars 1000
php_value memory_limit 512M
php_value post_max_size 128M
php_value session.gc_maxlifetime 1440
php_value session.save_path "/var/cpanel/php/sessions/ea-php56"
php_value upload_max_filesize 128M
php_flag zlib.output_compression Off
</IfModule>
# END cPanel-generated php ini directives, do not edit
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</IfModule>
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Live:
#RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
Local:
#RewriteRule .* index.php/$0 [PT,L]

CodeIgniter Mod_Rewrite issues

Having issues removing index.php? from the URL:
http://localhost/index.php?/reset_password
With htaccess file:
# Customized error messages.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</IfModule>
CI Settings:
$config['uri_protocol'] = 'AUTO';
I looked at the other threads on here with similar problems but none of their htaccess files work. Am I missing a setting?
I've never seen that .htaccess setup before, although it may work. I've used this for every CI project I've done, give it a try:
<IfModule mod_rewrite.c>
RewriteEngine on
# If the start of the URL doesn't match one of these...
RewriteCond $1 !^(index\.php|robots\.txt|assets|cache|themes|uploads)
# Route through index.php
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
Add don't forget this in config.php:
/*
|--------------------------------------------------------------------------
| Index File
|--------------------------------------------------------------------------
|
| Typically this will be your index.php file, unless you've renamed it to
| something else. If you are using mod_rewrite to remove the page set this
| variable so that it is blank.
|
*/
$config['index_page'] = '';
And remember: This will not "remove" index.php from your URL automatically, but rather route the request through it if it isn't present. If you have hardcoded links with index.php in them, they'll have to be changed or you'll need additional .htaccess configuration. If you are using the CI url functions like base_url(), site_url(), and anchor(), they won't use index.php if you have it blank in your config above.
This code works for me:
If name of my site is codeIgniter_ci_intro
I used code in .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /codeIgniter_ci_intro//index.php/$1 [L]
and I changed in config.php
$config['index_page'] = '';

htaccess 301 redirect not working

I'm trying to add a simple 301 rule to the .htaccess file of a codeigniter site.
redirect 301 /newsletter http://sub.domain.com/newsletters/may2010
When I visit http://sub.domain.com/newsletter the redirect goes to
http://sub.domain.com/newsletters/may2010/?/newsletter
I'm not sure where the ?/newsletter is coming from. Full .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
redirect 301 /newsletter http://sub.domain.com/newsletters/may2010
#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
</IfModule>
#####################################################
# CONFIGURE media caching
#
Header unset ETag
FileETag None
<FilesMatch "(?i)^.*\.(ico|flv|jpg|jpeg|png|gif|js|css)$">
Header unset Last-Modified
Header set Expires "Fri, 21 Dec 2012 00:00:00 GMT"
Header set Cache-Control "public, no-transform"
</FilesMatch>
#
#####################################################
<IfModule mod_deflate.c>
<FilesMatch "\.(js|css)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
How can I fix this?
Heh, this is Apache pulling a sneaky order-of-processing trick on you. As it turns out, the fact that you put your Rewrite command at the top of the file doesn't mean that it's what's actually executed first. What happens instead is that mod_rewrite is run first, followed by mod_alias (which is responsible for handling your Rewrite).
This results in the following transformation, per mod_rewrite:
newsletter --> index.php?/newsletter
mod_rewrite happily sets the query string to ?/newsletter, but because you don't have the PT flag specified, does not passthrough the rewritten URL index.php to mod_alias. Therefore, mod_alias still sees the /newsleter path, redirects it to http://sub.domain.com/newsletters/may2010, and appends the (now changed) query string ?/newsletter to the end to seal the deal. Fun stuff, right?
Anyway, a quick-fix for this scenario would be to ignore requests for just newsletter:
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !newsletter$
RewriteRule ^(.*)$ index.php?/$1 [L]

Resources