Perl CGI on IIS form POST returns 404 - perl

I am using a home grown small CGI Router for a simple webapp, code can be found here on github
The webapp has a login form like this
my $form = start_form( -method => 'post', -action => '/login' );
$form .= p( label('Mail'), textfield( -name => 'mail' ) );
$form .= p( label('Mail'), password_field( -name => 'pass' ) );
$form .= p( submit( -value => 'Log ind', -class => 'button button-primary' ) );
$form .= end_form();
and I have a router handling the post request like this
$router->add_route( 'POST', '/login', sub {
if ( param ) {
# Get mail and pass
my $mail = $cgi->param( 'mail' );
my $pass = $cgi->param( 'password' );
# Check against user table
# Set cookie and redirect to admin
}
# Otherwise redirect to /login
print redirect( -url => '/login' );
});
on my local environment, osx 10.10.3, perl 5, version 18, subversion 2 (v5.18.2), this is working like expected, I submit the form and handle the login, no problem.
my production environment is a Microsoft-IIS/5.0 according to ENV{'SERVER_SOFTWARE'}
On the production environment is returning a 404 and unfortunately I am unable to get my hands on any log file that could reveal something useful.
.htaccess file on both production and local environment
# RewriteBase /
DirectoryIndex index.pl index.phtml index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.pl [L,QSA]

The problem is most likely down to differing environments, check not just the server software but also the versions of perl and versions of the CGI.pm module. Also worth noting is that IIS can cause problems with CGI.pm due to the whole NPH thing - check the POD for CGI.pm for more details.
With regards to CGIRouter:
Out of the box CGI qw/:standard/ offers many of the features you would expect from a web framework, it has methods for creating HTML markup like anchors, paragraphs and H tags. CGI may not be as sexy as some of the modern frameworks.
It's not that CGI.pm isn't "sexy", it's simply not fit for purpose in any modern web app. Not to mention that the HTML markup functions are considered deprecated and shouldn't be used
adding a framework, any framework, would mean adding modules and dependencies which would then have to be kept up to date, as well as spending time on understanding the framework in question, it's cons and pros in order to pick the best one suited for the task at hand.
This is also a none-argument. CGI.pm has been removed from the perl core as of 5.22 so you will need to install it and its dependencies pretty soon. If you want to write a trivial RESTful web service using a simple to use framework with minimal dependencies then look at Mojolicious::Lite. For more examples and other alternatives see CGI::Alternatives.

After doing a ton of testing, I realised, the problem is not in the router or the fact that POST is not handled by IIS. The problem is the redirect subroutine.
Whereas redirect( -url => '/admin' ); works on OSX, it's not working on IIS. On IIS the full URL has to be passed like so redirect( -url => 'http://example.com/admin' ).

Related

Access Slim Framework 4 as Subfolder

I am trying to build an api with SLIM Framework V4.
htdocs/slim/public/index.php
<?php
require __DIR__ . '/../vendor/autoload.php';
use DI\Container;
use Slim\Factory\AppFactory;
use Illuminate\Pagination\Paginator;
use App\Middlewares\RequestUser;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
// Create Container using PHP-DI
$container = new Container();
// Set container to create App with on AppFactory
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response;
});
$app->get('/', function (Request $request, Response $response, $args) {
$data = array('message' => 'Unauthorized access');
$payload = json_encode($data);
$response->getBody()->write($payload);
return $response
->withHeader('Content-Type', 'application/json')
->withStatus(201);
});
$app->run();
If i run php server, it works fine
G:\xampp\htdocs\slim\public> php -S localhost:8888
PHP 7.2.27 Development Server started at Sun Apr 19 18:42:11 2020
Listening on http://localhost:8888
Document root is G:\xampp\htdocs\slim\public
If i run
http://localhost/slim/public/
I am getting
Fatal error: Uncaught Slim\Exception\HttpMethodNotAllowedException: Method not allowed. Must be one of: OPTIONS in G:\xampp\htdocs\slim\vendor\slim\slim\Slim\Middleware\RoutingMiddleware.php:96 Stack trace: #0 G:\xampp\htdocs\slim\vendor\slim\slim\Slim\Routing\RouteRunner.php(72): Slim\Middleware\RoutingMiddleware->performRouting(Object(Slim\Psr7\Request)) #1 G:\xampp\htdocs\slim\vendor\slim\slim\Slim\MiddlewareDispatcher.php(81): Slim\Routing\RouteRunner->handle(Object(Slim\Psr7\Request)) #2 G:\xampp\htdocs\slim\vendor\slim\slim\Slim\App.php(211): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #3 G:\xampp\htdocs\slim\vendor\slim\slim\Slim\App.php(195): Slim\App->handle(Object(Slim\Psr7\Request)) #4 G:\xampp\htdocs\slim\public\index.php(37): Slim\App->run() #5 {main} thrown in G:\xampp\htdocs\slim\vendor\slim\slim\Slim\Middleware\RoutingMiddleware.php on line 96
htdocs
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
</IfModule>
I am working on windows 10, xampp v3.2.4
The production will be go daddy shared hosting, as a subfolder. I tested it as a subdomain on godaddy server it is working fine. But i need it to be a sub folder of main domain, as godaddy is charging SSL certificate for subdomain too.
Thanks for the help in advance.

Submit Form not Working in CodeIgniter 3.0.3

I was tasked to write a simple program in CodeIgniter.I am coding in Symfony 2 and I have no trouble creating forms for testing since Symfony 2 offers a nice CRUD through command line which CodeIgniter lacks.So i have to create manually everytime I am creating forms for testing..But in chrome, the form does nothing when submit button is hit, and in Mozilla, and error message something like
The address wasn't understood
Firefox doesn't know how to open this address, because one of the following protocols (localhost) isn't associated with any program or is not allowed in this context.
You might need to install other software to open this address.
Controller
public function add_makers()
{
$this->load->helper('form');
$this->load->library('form_validation');
$data['title'] = 'Add New Car Maker';
$data['main_content'] = 'makers/add_makers';
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('description', 'Description', 'required');
$this->form_validation->set_rules('nation_id', 'Nation_Id', 'required');
if ($this->form_validation->run() == FALSE) {
$this->load->view('templates/template', $data);
//echo "ok";
}
else
{
$this->makers_model->new_makers();
//$this->load->view('makers/success');
}
Form
<h1><?php echo $title; ?></h1>
<?php echo form_open('makers/add_makers'); ?>
<label for="name">Name</label>
<?php
$data = array(
'type' => 'text',
'name' => 'name'
);
echo form_input($data);
?>
<label for="description">Description</label>
<?php
$data = array(
'type' => 'text',
'name' => 'description'
);
echo form_textarea($data);
?>
<label for="nation_id">Country</label>
<?php
$data = array(
'name' => 'nation_id',
'type' => 'text'
);
echo form_input($data);
?>
templates
<?php
/*
*Load header contents, and footer
*
*/
$this->load->view('templates/header');
$this->load->view($main_content);
$this->load->view('templates/footer');
I am running development in vagrant(ubuntu trusty) installed in Windows and I have no problem using this in Symfony2 or Laravel project.Rewrite is all enable by running
sudo a2enmod rewrite
Inside Apache, I configure virtual host this way
<VirtualHost *:80>
#ServerAdmin admin#yourdomain.com
DocumentRoot /var/www/CodeIgniter-3.0.3/
#ServerName yourdomain.com
#ServerAlias www.yourdomain.com
<Directory /var/www/CodeIgniter-3.0.3/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
#ErrorLog /var/www/CodeIgniter-3.0.3/logs/httpd/yourdomain.com-error_log
#CustomLog /var/log/httpd/yourdomain.com-access_log common
</VirtualHost>
Out in the box, I have this .ht access pre configured inside
Project
/Application
.htaccess
<IfModule authz_core_module>
Require all denied
</IfModule>
<IfModule !authz_core_module>
Deny from all
</IfModule>
And lastly routes
$route['makers/add_makers'] = 'makers/add_makers';
//$route['news/(:any)'] = 'news/view/$1';
//$route['news'] = 'news';
//$route['(:any)'] = 'pages/view/$1';
$route['default_controller'] = 'services/index';
I already searched Google for this and found no solution.Is there something missing in my files?
You could check the html code generated by CI, and try to Enter the full post URL in the address bar, maybe something happen, and then check the log file of apache and php, may it be helpful to solve your problem
Found the solution
I modify the .htaccess and move it outside application folder and put in root folder
RewriteEngine On
RewriteCond $1 !^(index\.php|styles|scripts|images|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1
#<IfModule mod_gzip.c>
# mod_gzip_on Yes
# mod_gzip_dechunk Yes
# mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
# mod_gzip_item_include handler ^cgi-script$
# mod_gzip_item_include mime ^text/.*
# mod_gzip_item_include mime ^application/x-javascript.*
# mod_gzip_item_exclude mime ^image/.*
# mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
#</IfModule>
Refactor apache 2.4
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
#ServerAdmin webmaster#localhost
DocumentRoot /var/www/Codeigniter
AcceptPathInfo On
<Directory /var/www/Codeigniter>
AllowOverride None
Require all granted
</Directory>
Then inside config/config.php
$config['base_url'] = '';//note the auto guessing.If I set this to localhost:8090/something, this form will not submitting
$config['index_page'] = '';
I tried many solutions provided in google and other suggestions but none works.Just got it right by spending many hours in trying possible solutions.
I am using Vagrant and Ubuntu trusty in development.Previously , I used Wamp for this project and I have no problem submitting forms.

Apache rewriteRule to check login and redirect to page

This is a follow up for this question Apache directory directive authentication based on Perl CGI::Session
Alias /files /myData/all
<Directory /myData/all >
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)$ cgi-bin/checklogin.pl?url=/files/$1 [L,R]
Options +Indexes
</Directory>
/files is a directory listing.
I edited the directive so that if a user goes to webserver/files/ they are redirected to checklogin.pl which checks for the existance of a session. If there is one it should redirect to the ?url if not it takes them to the loginpage.
The first part works. The redirect to $url causes a loop.
my $url = $cgi->param("url");
my $cookie = $cgi->cookie('mysession');
if(!$cookie){
$session = new CGI::Session();
print $session->redirect('/loginpage.html');
}else{
# HOW DO I display folder or files now?
$session = new CGI::Session(undef, $cookie, {Directory=>'/tmp/'});
print $session->redirect($url);
}
I am, obviously, getting a redirect loop error in Apache
This webpage has a redirect loop
If you redirect every request to checklogin.pl, any requests made inside checklogin.pl will redirect to checklogin.pl, which will redirect to checklogin.pl, which will redirect to checklogin.pl...
Instead, why don't you make a master script with a logged_in function that you call with each request:
#!/usr/bin/perl -T
use strict;
use warnings;
use CGI;
sub logged_in {
# Check session
}
my $q = CGI->new;
if (not logged_in()) {
print $q->redirect('http://url/to/login.html'); # Need to use a full URL
}
else {
# Do stuff
}

Joomla after SEF " Page Not Found " 404 Error?

I am trying to open URL of article from Facebook page on my website but the problem is every time error 404 is raised although the article is exists .
After searching I find that there is problem in .htaccess codes and I need help in this.
The problem :
URL : like from facebook page
Website : worked like Real link
As you can see there different between this two links.
The part is added "component/content/" and without the another language prefix "ar".
Some Details :
This is my .htaccess file :
> ##
# #package Joomla
# #copyright Copyright (C) 2005 - 2012 Open Source Matters. All rights reserved.
# #license GNU General Public License version 2 or later; see LICENSE.txt
##
##
# READ THIS COMPLETELY IF YOU CHOOSE TO USE THIS FILE!
#
# The line just below this section: 'Options +FollowSymLinks' may cause problems
# with some server configurations. It is required for use of mod_rewrite, but may already
# be set by your server administrator in a way that dissallows changing it in
# your .htaccess file. If using it causes your server to error out, comment it out (add # to
# beginning of line), reload your site in your browser and test your sef url's. If they work,
# it has been set by your server administrator and you do not need it set here.
##
## Can be commented out if causes errors, see notes above.
Options +FollowSymLinks
## Mod_rewrite in use.
RewriteEngine On
## Begin - Rewrite rules to block out some common exploits.
# If you experience problems on your site block out the operations listed below
# This attempts to block the most common type of exploit `attempts` to Joomla!
#
# Block out any script trying to base64_encode data within the URL.
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
# Block out any script that includes a <script> tag in URL.
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL.
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL.
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Return 403 Forbidden header and show the content of the root homepage
RewriteRule .* index.php [F]
#
## End - Rewrite rules to block out some common exploits.
## Begin - Custom redirects
#
# If you need to redirect some pages, or set a canonical non-www to
# www redirect (or vice versa), place that code here. Ensure those
# redirects use the correct RewriteRule syntax and the [R=301,L] flags.
#
## End - Custom redirects
##
# Uncomment following line if your webserver's URL
# is not directly related to physical file paths.
# Update Your Joomla! Directory (just / for root).
##
RewriteBase /
## Begin - Joomla! core SEF Section.
#
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
#
# If the requested path and file is not /index.php and the request
# has not already been internally rewritten to the index.php script
RewriteCond %{REQUEST_URI} !^/index\.php
# and the request is for something within the component folder,
# or for the site root, or for an extensionless URL, or the
# requested URL ends with one of the listed extensions
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
# and the requested path and file doesn't directly match a physical file
RewriteCond %{REQUEST_FILENAME} !-f
# and the requested path and file doesn't directly match a physical folder
RewriteCond %{REQUEST_FILENAME} !-d
# internally rewrite the request to the index.php script
RewriteRule .* index.php [L]
#
# Forward to sitemap
Redirect /sitemap.xml http://www.businesstendersmag.com/ar/?option=com_xmap&view=xml&tmpl=component&id=3
## End - Joomla! core SEF Section.
That's all! Any help will be appreciated.
How do you generate URLs that are posted to Facebook?
Are you generating URLs like this?
// require com_content router.
require_once (JPATH_SITE.'/components/com_content/helpers/route.php');
// generate link.
$link = JURI::root() . substr( JRoute::_( ContentHelperRoute::getArticleRoute( $article->slug, $article->categorySlug ) ), strlen(JURI::base(true)) + 1);
// Where $article->slug & $article->categorySlug are fetched from database.

Help with mapping or routing subdomain to Zend Framework Controller (mobile version of site)

What I am trying to do is use a subdomain for a special mobile version of my ZF application. Ideally it would map to a specific controller like the example below, but at this point I'm willing to try any method that works:
Ex. m.domain.com/action would route to the "mobile" controller and whatever action is specified.
I found a number of similar questions here and elsewhere on the Google but I get the feeling I am missing something obvious because no matter what route I set up it's just being ignored. I suspect it has something to do with htaccess but could be wrong there.
Here is the route I currently have in my bootstrap file (but I have tried a number of different patters here). Right now I'm just trying to get it to show the plain index for simplicity:
$hostRoute = new Zend_Controller_Router_Route_Hostname(':subdomain.domain.com',
array(
'controller' => 'index',
'action' => 'index'
)
);
$plainPathRoute = new Zend_Controller_Router_Route(':controller/:action/*',
array('controller' => 'index', 'action' => 'index'));
$controller->getRouter()->addRoute('mobile', $hostRoute->chain($plainPathRoute));
And my htaccess has:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Now there are 2 methods I have been trying out here because I have been so frustrated.
Create the subdomain "m" inside of my hosting account
Subdomain "app" does not exist on my web hosting account
For method 1, it just goes to the generic index.html file that is in domain.com/m/. Method 2 tells me the page doesn't exist.
I'm really hoping there is something obvious here that I'm missing. Like I mentioned above, I'm not picky about how exactly this gets executed, so long as I can have a subdomain point to a specific controller. It's going to be a very simplified version of the site so I don't really need to do anything complex.
Thanks for your help.
First of all, you need to configure your virtual host to handle multiple domains:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAlias m.example.com
ServerAlias www.m.example.com
...
You may also do this by adding new subdomain pointing to your site root, via your hosting panel options.
Then you may create a route chain, as in your example, or handle the switch yourself, e.g. in the controller plugin:
$host = strtolower($request->getServer('HTTP_HOST'));
if ('m.' === substr($host, 0, 2) || 'www.m.' === substr($host, 0, 6)) {
$themes->setTheme('m');
$userSession->theme = 'm';
...
I use something similar, but instead of the subdomain mapping to a controller I use it for a module, I use the following route:
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
':module.domain.com',
array(
'module' => 'default'
)
);
$normalRoute = new Zend_Controller_Router_Route(
':controller/:action/*',
array(
'controller' => 'index',
'action' => 'index'
)
);
$router->addRoute('default', $hostnameRoute->chain($normalRoute));