Need help fix 400 Bad Request for CodeIgniter project - .htaccess

In my codeigniter project, i have the following htaccess file to remove the index.php from URL
RewriteEngine on
RewriteCond $1 !^(index\.php|js|media|style|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I am using the search form (using form helper). Since it is POST based, I have created a controller called "pre_search" to redirect it to search controller so that the POSTed data will be visible in URL and I can use it with URI helper's segment method.
So my pre_search controller
<?php
class Presearch extends CI_Controller {
//just to make form POST data visible in URL string for search
public function index() {
redirect('search/' . $this->input->post('term'));
}
}
And search controller does the real search. For the mean time I have allowed all the characters in URL for testing.
$config['permitted_uri_chars'] = '';
My problem is now when I have percentage sign (%) in URL it shows bad request. I think it is the apache's response and codeigniter have nothing to do with it.
After some research I found that somebody suggested to fix that problem by modifying htaccess like this
RewriteRule ^(.*)$ /index.php/$1 [B,L]
I have tried this method and it breaks everything.
Since % sign was not encoded, I tried to use also in my pre_search controller like this
redirect('search/' . urlencode($this->input->post('term')));
But didn't solve the problem.
So what is the best way to solve this? I know this is apache problem. I am just illustrating my codeigniter codes to clarify my intentions.
Thanks in advance
Deepak

I do the same, these are my params and I also found this link it might help you with the htaccess http://www.dracos.co.uk/code/apache-rewrite-problem/
$this->load->library('form_validation');
$this->form_validation->set_rules('s', '','trim|min_length[3]|required|xss_clean');
if ($this->form_validation->run() == FALSE):
$this->session->set_flashdata('errorMsg', form_error('s'));
redirect($this->session->userdata['redirectUrl']);
else:
redirect(base_url() . $this->lang->line('link_search') . '/' . $this->functions->convertToUrl($this->functions->secureString($this->input->post('s', TRUE))));
endif;
My config values
$config['permitted_uri_chars'] = 'a-z 0-9~%\.\:_\-ñ';
$config['uri_protocol'] = 'PATH_INFO';
I convert the POST to legible url, changing characters to the ones permitted, and then I do the redirect.

Related

Why My_controller doesn't work in linux hosting?

got empty page when I create MY_controller and Frontend_controller for my website.
Here is Controller
class welcome extends Frontend_controller{
public function index(){
$this->load->view('welcome_message');
}
}
And I also create Frontend_controller in libraries named:Frontend_controller.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Class Frontend_controller extends MY_controller{
public function __construct(){
parent::__construct();
echo'<script>alert()</script>';
}
}
?>
and I also create MY_controller.php in Core folder
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Class MY_controller extends CI_controller{
public $data = array();
public function __construct() {
parent::__construct();
}
}
?>
for calling all Class name I also copy this function from some tutorial and keep in config.php
function __autoload($classname) {
if (strpos($classname, 'CI_') !== 0) {
$file = APPPATH . 'libraries/' . $classname . '.php';
if (file_exists($file)) {
#include_once($file);
}
}
}
Finaly I create .Htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:REDIRECT_APP_PATH} !^$
RewriteRule ^(.*)$ - [E=APP_PATH:%{ENV:REDIRECT_APP_PATH}]
RewriteCond %{ENV:APP_PATH} ^$
RewriteRule ^(.*)$ - [E=APP_PATH:/$1]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
</IfModule>
I have change and testing this option for URI and $config['base_url'] = ''; too
| '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
|
*/
$config['uri_protocol'] = 'QUERY_STRING';
Here is View welcome_message.php In views fold
Html wrap
But it work in my localhost why it doesn't work on linux hosting **
**Should I change hosting ?
The result I get empty pages when I type welcome or log to my website
I'm really sorry friend I don't know how to do because I spending more time on it. if I can't I will get warning letter from company.
And thank for help
Linux is a case sensitive OS while windows is not.
You should change
MY_controller to MY_Controller
CI_controller to CI_Controller
also .Htaccess should be renamed to .htaccess.
Empty php pages also known as "white page of death" usually means that you encountered a php fatal error.You should check your logs whenever this happens for a detailed error report (or enable show error if you are NOT in a production server).

Add rewrite rule in plugin: with .htaccess in plugin folder or using WordPress functions

I need add a rewrite rule in my plugin, and distribute it with my code. All works fine if I put the rule in the .htaccess in the WordPress root folder, but I need distribute the plugin with my rule.
I try to put a .htaccess inside the plugin folder and try to use the add_rewrite_rule function but doesn't works either.
Here the .htaccess code that works correctly in WordPress root folder but doesn't works in my plugin folder:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule my-plugin/pages/tp(.*)\.php$ wp-content/plugins/my-plugin/pages/request.php?pid=$1
</IfModule>
I try the follow code in my plugin but doesn't works either:
add_filter( 'query_vars', 'add_query_vars' );
function add_query_vars( $query_vars )
{
$query_vars[] = 'pid';
return $query_vars;
}
add_action( 'init', 'add_init' );
function add_init()
{
$plugin_url = 'the-path-to-my-plugin-folder';
add_rewrite_rule('my-plugin/pages/tp(.*)\.php'
, $plugin_url . 'pages/request.php?pid=$matches[1]','top');
global $wp_rewrite;
$wp_rewrite->flush_rewrite_rules(); // I know this should be called only one time, but I put it here just to keep simple the sample code
}
But I always get the error that the URL wasn't found.
What I'm doing wrong? How can I do what I need? I searched for similar questions but none solve my problem.
My plugin folder structure is:
Main folder: /wp-content/plugins/my-plugin
------ /pages (sub folder)
-------------/request.php (script that should receive the request)
NOTE: WordPress Rewrite API is not the same as Apache Rewrite module.
WP Rewrite API doesn't redirect a request to another URL, it used to
parse current URL and fill query_vars array.
The issue is in the second parameter of you add_rewrite_rule function call. It has to start from index.php? and then there should be your arguments, like pid, for example:
"index.php?pid=$matches[1]...."
So your add_init function should be like this:
add_action( 'init', 'wpse8170_add_init' );
function wpse8170_add_init()
{
add_rewrite_rule('my-plugin/pages/tp(.*)\.php', 'index.php?pid=$matches[1]', 'top');
}
Don't forget to flush rewrite rules by visiting Settings » Permalinks page.
Further reading:
The Rewrite API: The Basics
The Rewrite API: Post Types & Taxonomies
WP handles the plugins from the /wp-admin directory with a PHP script (admin.php), like this:
http://MyWP.com/wp-admin/admin.php?page=MyPlugin/module.php
Therefore, .htaccess files in the plugin directory are not parsed when the plugin is called. They have to be placed in the wp-admin directory or in the root directory, as you already found out.
Although copying the .htacces file to the root directory when the plugin is installed -and deleting it when it is removed- is possible, I don't think it is the best option. Having .htaccess files in the WP space doesn't seem like a good idea.
Your second approach looks much better: Creating rewrite rules in the main script.
Looking at your code, I think the problem are the pattern (Incoming URL string to match) and possibly the substitution URL path ($plugin_url in your question).
The $rule parameter in the add_rewrite_rule() function should capture a segment of the URL (Above) used to call the plugin's modules.
I can't suggest anything else because you don't supply enough information about the plugin and it's directory tree, except what can be guessed from the regex in the rewrite rule. But, this is a general idea of a way to achieve what you need.

URL with encoded slashes goes to 404

I use user-provided content to generate URLs.
One of my URL had for title Kikar Habusiness - émission du 2/12/12, which converted to the URL /url/Kikar+Habusiness+-+émission+du+2%2F12%2F12.
It goes to a 404. If I remove the %2F from the URL it works fine.
An interesting thing is that my php code (using Yii) usually handles 404 with custom pages, but this one returns a default Apache 404. Which leads me to believe it doesn't even reach my bootstrap file.
The .htaccess reads:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
My Yii parseUrl reads:
public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) {
if(preg_match('%^url/(\d+)%',$pathInfo,$matches)){
$_GET['id'] = $matches[1];
return 'url/view';
}
else if(preg_match('%^category/(\d+)%',$pathInfo,$matches)){
$_GET['id'] = $matches[1];
return 'category/view';
}
return false;
}
My URL slug generator is:
public static function slug($title){
$title = ToolBox::trim($title,60,false);
$title = urlencode($title);
return $title;
}
Note that I cannot have basic ASCII URLs, because some of the content is non-latin (such as Hebrew or Arabic).
This is a common problem in Apache and nothing to do with Yii fortunately.
Apache will automatically block any URL it sees with encoded URL parts %2F (/) and %5C (\). It won't even reach any mod_proxy or mod_rewrite rules.
There are a number of ways around this without changing too much code, depending on your environment, including:
"AllowEncodedSlashes" Directive
Double urlencode() values
See here for a full list and instructions: http://www.jampmark.com/web-scripting/5-solutions-to-url-encoded-slashes-problem-in-apache.html
More info as the link is down
If you have access to it, you can enable the AllowEncodedSlashes directive, it's a very old semi-security fix that it's turned off by default anyway. This will get round the problem. If you can't access the Apache configs, then you'll have to look into the other solutions.
The jampark url redirectsto an incorrect page, use the bellow url:
http://www.leakon.com/archives/865

htaccess and image caching

Need Help, I want create an image access caching, example image at url
example.com/caching/m_images.jpg
if that image exists then show image, but if don't exist, maybe with .htaccess script, to run image function at :
example.com/recaching/m_images.jpg
to create new image with custom size at caching folder, then access again the image url.
How to do this, or there is another better solution ??
Thanks.
ps
I already have little script htaccess to remove 'index.php?' from codeigniter url
RewriteEngine on
RewriteCond $1 !^(index\.php|js|css|caching)
RewriteRule ^(.*)$ index.php/$1 [L]
so the real url of function is:
example.com/index.php?recaching/m_images.jpg
How about:
RewriteEngine on
RewriteRule ^images/(.*)$ index.php/recaching/$1 [L,QSA]
RewriteCond $1 !^(index\.php|js|css|caching)
RewriteRule ^(.*)$ index.php/$1 [L]
the above "should" (i've not tested it) redirect any requested files inside the images folder (assuming you have an images folder) and passes the path to the route recaching.
You can then, using file_exists, readfile and header write the file to the browser if it does not exist.
i.e.
function recaching($path)
{
$tmpPath = FCPATH . 'images/' . $path;
if(!file_exists($tmpPath))
{
// change $tmpPath to a file that exists, i.e. a 404 image
// or if you are generating an image when one doesn't exist
// create it here.
}
$info = getimagesize($tmpPath);
if($info !== false)
{
header('content-type: ' . $info['mime']);
readfile($tmpPath);
}
else
{
die('There was a problem rendering the image.');
}
}

Kohana modules -path .htaccess protection and media -files

In Kohana there's modules -path protection in .htaccess
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
How could I allow paths like:
http://localhost/modules/mymodule/media/js/myjavascript.js
I would like to include javascript and other media files to my module and still protect other module files like .php
I could allow whole modules -path, but then all .php -files would be listed too.
# Protect application and system files from being viewed
RewriteRule ^(?:application|system)\b.* index.php/$0 [L]
Sure there is basic PHP -protection, but I still won't want that anyone could list my modules -path.
<?php defined('SYSPATH') or die('No direct script access.');
The best solution would be to serve those files using a media controller. So a user could request "js/script.js" and Kohana would load the first file it finds using the cascading file structure. There's a good media controller that comes with Kohana, it's in the Userguide module:
Line 247 of classes/controller/userguide.php
public function action_media()
{
// Get the file path from the request
$file = $this->request->param('file');
// Find the file extension
$ext = pathinfo($file, PATHINFO_EXTENSION);
// Remove the extension from the filename
$file = substr($file, 0, -(strlen($ext) + 1));
if ($file = Kohana::find_file('media/guide', $file, $ext))
{
// Check if the browser sent an "if-none-match: <etag>" header, and tell if the file hasn't changed
$this->response->check_cache(sha1($this->request->uri()).filemtime($file), $this->request);
// Send the file content as the response
$this->response->body(file_get_contents($file));
// Set the proper headers to allow caching
$this->response->headers('content-type', File::mime_by_ext($ext));
$this->response->headers('last-modified', date('r', filemtime($file)));
}
else
{
// Return a 404 status
$this->response->status(404);
}
}
This wont be the fastest solution, but if you correctly set the response headers the files should be cached on the client browser.
Solution, add this RewriteCond just before RewriteRule
# Protect application and system files from being viewed
RewriteCond %{REQUEST_URI} !^(.*/)*(application|application/cache|modules/[^/]*)/media/.*$
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]

Resources