CodeIgniter Routing and 404 Custom Errors - .htaccess

I use CodeIgniter.
I route certain urls to different files based on the structure of url using the routes.php file. Everything has been working fine.
However, a few months ago, i thought i would add a custom 404 page. I did and things appeared to be working fine.
HOWEVER, i have just realised that every page on my site (except the home page) gives a server response of 404 error and yet displays to the human user the correct page as the custom page!
I have no idea how that's happening but it's obviously a nightmare as i am now not indexed from all search engine listings!!! Domain is http://citylightstours.com
ROUTES.PHP
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
| URI ROUTING
| -------------------------------------------------------------------------
| This file lets you re-map URI requests to specific controller functions.
|
| Typically there is a one-to-one relationship between a URL string
| and its corresponding controller class/method. The segments in a
| URL normally follow this pattern:
|
| example.com/class/method/id/
|
| In some instances, however, you may want to remap this relationship
| so that a different class/function is called than the one
| corresponding to the URL.
|
| Please see the user guide for complete details:
|
| http://codeigniter.com/user_guide/general/routing.html
|
| -------------------------------------------------------------------------
| RESERVED ROUTES
| -------------------------------------------------------------------------
|
| There area two reserved routes:
|
| $route['default_controller'] = 'welcome';
|
| This route indicates which controller class should be loaded if the
| URI contains no data. In the above example, the "welcome" class
| would be loaded.
|
| $route['404_override'] = 'errors/page_missing';
|
| This route will tell the Router what URI segments to use if those provided
| in the URL cannot be matched to a valid route.
|
*/
$route['default_controller'] = "content";
$route['en/(:num)/(:any)'] = "content/en/$1";
$route['de/(:num)/(:any)'] = "content/de/$1";
$route['es/(:num)/(:any)'] = "content/es/$1";
$route['it/(:num)/(:any)'] = "content/it/$1";
$route['ar/(:num)/(:any)'] = "content/ar/$1";
$route['404_override'] = '';
/* End of file routes.php */
/* Location: ./application/config/routes.php */
.HTACCESS file:
<IfModule mod_rewrite.c>
# Development
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|scripts|styles|vendor|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
# ----------------------------------------------------------------------
# Better website experience for IE users
# ----------------------------------------------------------------------
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
BrowserMatch MSIE ie
Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie
</IfModule>
</IfModule>
<IfModule mod_headers.c>
Header append Vary User-Agent
</IfModule>
# ----------------------------------------------------------------------
# Webfont access
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|font.css)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
# ----------------------------------------------------------------------
# Proper MIME type for all files
# ----------------------------------------------------------------------
# audio
AddType audio/ogg oga ogg
# video
AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm
# Proper svg serving. Required for svg webfonts on iPad
# twitter.com/FontSquirrel/status/14855840545
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
# webfonts
AddType application/vnd.ms-fontobject eot
AddType font/truetype ttf
AddType font/opentype otf
AddType application/x-font-woff woff
# assorted types
AddType image/x-icon ico
AddType image/webp webp
AddType text/cache-manifest appcache manifest
AddType text/x-component htc
AddType application/x-chrome-extension crx
AddType application/x-xpinstall xpi
AddType application/octet-stream safariextz
# ----------------------------------------------------------------------
# gzip compression
# ----------------------------------------------------------------------
<IfModule mod_deflate.c>
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s,?\s(gzip|deflate)?|X{4,13}|~{4,13}|-{4,13})$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
<FilesMatch "^(?!.*\.ogg$|.*\.ogv$|.*\.mp4$).+" >
# html, txt, css, js, json, xml, htc:
<IfModule filter_module>
FilterDeclare COMPRESS
FilterProvider COMPRESS DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/
FilterProvider COMPRESS DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/
FilterChain COMPRESS
FilterProtocol COMPRESS change=yes;byteranges=no
</IfModule>
</FilesMatch>
# webfonts and svg:
<FilesMatch "\.(ttf|otf|eot|svg)$" >
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
# ----------------------------------------------------------------------
# Expires headers (for better cache control)
# ----------------------------------------------------------------------
<IfModule mod_expires.c>
ExpiresActive on
# Perhaps better to whitelist expires rules? Perhaps.
ExpiresDefault "access plus 1 month"
# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)
ExpiresByType text/cache-manifest "access plus 0 seconds"
# your document html
ExpiresByType text/html "access plus 0 seconds"
# data
ExpiresByType text/xml "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
# rss feed
ExpiresByType application/rss+xml "access plus 1 hour"
# favicon (cannot be renamed)
ExpiresByType image/x-icon "access plus 1 week"
# media: images, video, audio
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# htc files (css3pie)
ExpiresByType text/x-component "access plus 1 month"
# webfonts
ExpiresByType font/truetype "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
# css and javascript
ExpiresByType text/css "access plus 2 months"
ExpiresByType application/javascript "access plus 2 months"
ExpiresByType text/javascript "access plus 2 months"
<IfModule mod_headers.c>
Header append Cache-Control "public"
</IfModule>
</IfModule>
# ----------------------------------------------------------------------
# ETag removal
# ----------------------------------------------------------------------
FileETag None
# ----------------------------------------------------------------------
# Stop screen flicker in IE on CSS rollovers
# ----------------------------------------------------------------------
# The following directives stop screen flicker in IE on CSS rollovers - in
# combination with the "ExpiresByType" rules for images (see above). If
# needed, un-comment the following rules.
# BrowserMatch "MSIE" brokenvary=1
# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
# BrowserMatch "Opera" !brokenvary
# SetEnvIf brokenvary 1 force-no-vary
RewriteEngine On
RewriteCond %{HTTP_HOST} !^citylightstours\.com$ [NC]
RewriteRule ^(.*)$ http://citylightstours.com/$1 [R=301,L]
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* ? [F,L]
I have a MY_Router.php file to handle customer 404 pages and wonder whether this is setting a 404 http status incorrectly ??
MY_Router.php file:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Router extends CI_Router {
var $error_controller = 'error';
var $error_method_404 = 'error_404';
function My_Router()
{
parent::CI_Router();
}
// this is just the same method as in Router.php, with show_404() replaced by $this->error_404();
function _validate_request($segments)
{
// Does the requested controller exist in the root folder?
if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
{
return $segments;
}
// Is the controller in a sub-folder?
if (is_dir(APPPATH.'controllers/'.$segments[0]))
{
// Set the directory and remove it from the segment array
$this->set_directory($segments[0]);
$segments = array_slice($segments, 1);
if (count($segments) > 0)
{
// Does the requested controller exist in the sub-folder?
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
{
return $this->error_404();
}
}
else
{
$this->set_class($this->default_controller);
$this->set_method('index');
// Does the default controller exist in the sub-folder?
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
{
$this->directory = '';
return array();
}
}
return $segments;
}
// Can't find the requested controller...
return $this->error_404();
}
function error_404()
{
$this->directory = "";
$segments = array();
$segments[] = $this->error_controller;
$segments[] = $this->error_method_404;
return $segments;
}
function fetch_class()
{
// if method doesn't exist in class, change
// class to error and method to error_404
$this->check_method();
return $this->class;
}
function check_method()
{
$ignore_remap = true;
$class = $this->class;
if (class_exists($class))
{
// methods for this class
$class_methods = array_map('strtolower', get_class_methods($class));
// ignore controllers using _remap()
if($ignore_remap && in_array('_remap', $class_methods))
{
return;
}
if (! in_array(strtolower($this->method), $class_methods))
{
$this->directory = "";
$this->class = $this->error_controller;
$this->method = $this->error_method_404;
include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT);
}
}
}
function show_404()
{
include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT);
call_user_func(array($this->error_controller, $this->error_method_404));
}
}
/* End of file MY_Router.php */
/* Location: ./system/application/libraries/MY_Router.php */
Can someone please help!??
Thanks

Your Routes needs fixing : -
$route['en/(:num)/(:any)'] = "content/en/$1";
$route['de/(:num)/(:any)'] = "content/de/$1";
$route['es/(:num)/(:any)'] = "content/es/$1";
$route['it/(:num)/(:any)'] = "content/it/$1";
$route['ar/(:num)/(:any)'] = "content/ar/$1";
Have a read at this : -
http://www.codeigniter.com/userguide2/general/routing.html
According to your routing you have a controller for each language. for example(enController,deController,esController etc... ) which i am presuming you don't have that you just have a content controller.
The response you are looking for can be found here : -
https://github.com/bcit-ci/CodeIgniter/wiki/URI-Language-Identifier

Related

Understanding BNF notation for an RTSP request

According to RTSP documentation page 21 https://www.rfc-editor.org/rfc/rfc2326, an RTSP response is:
Request = Request-Line ; Section 6.1
*( general-header ; Section 5
| request-header ; Section 6.2
| entity-header ) ; Section 8.1
CRLF
[ message-body ] ; Section 4.3
The *, as far as I know and according to https://www.w3.org/Notation.html, means "1 or more of the thing after it". So I'm interpreting the thing above as
*(general-header|request-header|entity-header)CRLF
This would explain this example below, where the headers are of the type general-header \r\n, like this: Cseq: 2\r\nContent-Base: rtsp://example.com/media.mp4\r\nContent-Type: application/sdp\r\nContent-Length: 360\r\n:
S->C: RTSP/1.0 200 OK
CSeq: 2
Content-Base: rtsp://example.com/media.mp4
Content-Type: application/sdp
Content-Length: 460
m=video 0 RTP/AVP 96
a=control:streamid=0
a=range:npt=0-7.741000
a=length:npt=7.741000
a=rtpmap:96 MP4V-ES/5544
a=mimetype:string;"video/MP4V-ES"
a=AvgBitRate:integer;304018
a=StreamName:string;"hinted video track"
m=audio 0 RTP/AVP 97
a=control:streamid=1
a=range:npt=0-7.712000
a=length:npt=7.712000
a=rtpmap:97 mpeg4-generic/32000/2
a=mimetype:string;"audio/mpeg4-generic"
a=AvgBitRate:integer;65790
a=StreamName:string;"hinted audio track"
The headers are in the form general-header \r\n (where \r\n is CRLF). But what about that extra white line (a \r\n) before the message body? This is not explained by the repetition.
I think I'm interpreting something wrong.
This interpretation is correct:
Request = Request-Line *(general-header|request-header|entity-header) CRLF [message-body]
Although the example given is a response, which has this similar grammar:
Response = Status-Line *(general-header|response-header|entity-header) CRLF [message-body]
In either case, the set of headers is separated from the message-body by a CRLF (\r\n), which is NOT repeated. In the example:
RTSP/1.0 200 OK # This is the Status-Line
CSeq: 2 # general-header (see Section 12)
Content-Base: rtsp://example.com/media.mp4 # entity-header (see Section 8.1, 12.11)
Content-Type: application/sdp # entity-header (see Section 8.1, 12.16)
Content-Length: 460 # entity-header (see Section 8.1, 12.14)
# the CRLF marking the end of headers
m=video 0 RTP/AVP 96 # the message body follows
...
"The thing after the *" is the parenthesis block, without the CRLF. Each header ends with a CRLF because the grammar for message headers includes that. See Section 4.2, which refers to Section 4.2 of RFC 2068:
message-header = field-name ":" [ field-value ] CRLF

Varnish Breaking Social Sharing

Facebook uses a curl with range option to retrieve HTML of a page for sharing. Varnish is only returning page header info and not the html. This is the result I would say 75% to 80% of the time. Every once in a while it returns the correct Result
Anyone have an Idea how to fix this.
Example
#curl -v -H Range:bytes=0-524288 http://americanactionnews.com/articles/huge-protest-calls-for-death-to-usa-demands-isis-control
* Trying 52.45.101.42...
* TCP_NODELAY set
* Connected to americanactionnews.com (52.45.101.42) port 80 (#0)
> GET /articles/huge-protest-calls-for-death-to-usa-demands-isis-control HTTP/1.1
> Host: americanactionnews.com
> User-Agent: curl/7.51.0
> Accept: */*
> Range:bytes=0-524288
>
< HTTP/1.1 206 Partial Content
< Content-Type: text/html; charset=utf-8
< Status: 200 OK
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Date: Fri, 23 Dec 2016 16:39:46 GMT
< Cache-Control: max-age=300, public
< X-Request-Id: 8007fb76-3878-430d-845c-06a8710ae1ae
< X-Runtime: 0.247333
< X-Powered-By: Phusion Passenger 4.0.55
< Server: nginx/1.6.2 + Phusion Passenger 4.0.55
< X-Varnish-TTL: 300.000
< X-Varnish: 65578
< Age: 0
< Via: 1.1 varnish-v4
< X-Cache: MISS
< Transfer-Encoding: chunked
< Connection: keep-alive
< Accept-Ranges: bytes
< Content-Range: bytes 0-15/16
<
* Curl_http_done: called premature == 0
* Connection #0 to host americanactionnews.com left intact
We have found the answer and made some modifications to our varnish based on the following link and it seems to be working.
https://info.varnish-software.com/blog/caching-partial-objects-varnish
It looks like it is actually your backend server (Nginx) that is the problem. Especially considering your mentioned hit-rate-like success rate :) Plus, the failure's example is a MISS (delivered from backend server).
Make sure that you don't have anything in your Nginx configuration that prevents range requests, i.e. one popular thing that breaks it is:
ssi on;
ssi_types *;

How to split video or audio by silent parts

I need to automatically split video of a speech by words, so every word is a separate video file. Do you know any ways to do this?
My plan was to detect silent parts and use them as words separators. But i didn't find any tool to do this and looks like ffmpeg is not the right tool for that.
You could first use ffmpeg to detect intervals of silence, like this
ffmpeg -i "input.mov" -af silencedetect=noise=-30dB:d=0.5 -f null - 2> vol.txt
This will produce console output with readings that look like this:
[silencedetect # 00000000004b02c0] silence_start: -0.0306667
[silencedetect # 00000000004b02c0] silence_end: 1.42767 | silence_duration: 1.45833
[silencedetect # 00000000004b02c0] silence_start: 2.21583
[silencedetect # 00000000004b02c0] silence_end: 2.7585 | silence_duration: 0.542667
[silencedetect # 00000000004b02c0] silence_start: 3.1315
[silencedetect # 00000000004b02c0] silence_end: 5.21833 | silence_duration: 2.08683
[silencedetect # 00000000004b02c0] silence_start: 5.3895
[silencedetect # 00000000004b02c0] silence_end: 7.84883 | silence_duration: 2.45933
[silencedetect # 00000000004b02c0] silence_start: 8.05117
[silencedetect # 00000000004b02c0] silence_end: 10.0953 | silence_duration: 2.04417
[silencedetect # 00000000004b02c0] silence_start: 10.4798
[silencedetect # 00000000004b02c0] silence_end: 12.4387 | silence_duration: 1.95883
[silencedetect # 00000000004b02c0] silence_start: 12.6837
[silencedetect # 00000000004b02c0] silence_end: 14.5572 | silence_duration: 1.8735
[silencedetect # 00000000004b02c0] silence_start: 14.9843
[silencedetect # 00000000004b02c0] silence_end: 16.5165 | silence_duration: 1.53217
You then generate commands to split from each silence end to the next silence start. You will probably want to add some handles of, say, 250 ms, so the audio will have a duration of 250 ms * 2 more.
ffmpeg -ss <silence_end - 0.25> -t <next_silence_start - silence_end + 2 * 0.25> -i input.mov word-N.mov
(I have skipped specifying audio/video parameters)
You'll want to write a script to scrape the console log and generate a structured (maybe CSV) file with the timecodes - one pair on each line: silence_end and the next silence_start. And then another script to generate the commands with each pair of numbers.

LSB init service dependency

I have added the two services A and B. B is dependent on A means if i will start B then A should be start automatically if it is not running already. But A is not coming up automatically when i am starting B.
Can you please tell where am i wrong ?. I have mentioned the Init scripts for both the services below.
B Init script:
#!/bin/bash
# Author: Jsingh <jsingh#sandvine.com>
# chkconfig: 2345 95 05
# processname: B
# config: /usr/local/etc/rc.conf
# pidfile: /var/run/B.pid
### BEGIN INIT INFO
# Provides: B
# Required-Start: $local_fs $network A
# Required-Stop: $local_fs $network A
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop System daemon
# Description:
### END INIT INFO
A Init Script:
#!/bin/bash
# Author: Jsingh <jsingh#sandvine.com>
# chkconfig: 2345 90 10
# processname: A
# config: /usr/local/etc/rc.conf
# pidfile: /var/run/A.pid
### BEGIN INIT INFO
# Provides: A
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop System daemon
# Description:
### END INIT INFO

Varnish error : no backend connection

I tried to install Varnish on my debian 7 with apache2.
But when i type www.mydomain.com:6081 to test the connection, i got a 503 error service unavaible.
Varnish log says :
12 Hash c www.mywebsite.com:6081
12 VCL_return c hash
12 VCL_call c pass pass
12 FetchError c no backend connection
12 VCL_call c error deliver
12 VCL_call c deliver deliver
12 TxProtocol c HTTP/1.1
12 TxStatus c 503
My etc/varnish/default.vcl file :
(only one backend for now)
backend site1 {
.host = "92.243.5.12"; // ip adress for www.mydomain.com
.port = "8080";
.connect_timeout = 6000s;
.first_byte_timeout = 6000s;
.between_bytes_timeout = 6000s;
}
# Default backend is set to site1
set req.backend = site1;
My etc/default/varnish file :
DAEMON_OPTS="-a :80
-T localhost:6082
-f /etc/varnish/default.vcl
-S /etc/varnish/secret
-p thread_pool_add_delay=2
-p thread_pools=4
-p thread_pool_min=200
-p thread_pool_max=4000
-p cli_timeout=25
-p session_linger=100
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
Thank you very much
In your conf file, you are making varnish listen to port 80 and you are sending requests to port 6081, that may be a reason.

Resources