redirect to index using staticApp with defaultWebAppSettings - haskell

I'm using the wai-app-static static package to serve a small website. Originally I called it as:
staticApp defaultFileServerSettings root
and all was right with the world. I wanted to switch to using defaultWebAppSettings, though, (as this is a website). I was able to get that to work, such that if I went to http://localhost:3000/index.html, it was fine, but I also need to set up a redirect from the root folder to the index site (viz. http://localhost:3000 --> http://localhost:3000/index.html).
Based on what I saw in the code, I tried a couple of variations of:
(defaultWebAppSettings root) { ssIndices = map unsafeToPiece ["index.html"],
ssRedirectToIndex = True }
I'm able to compile and run the server, but I can't get the redirection to work.
Any pointers or ideas would be greatly appreciated!
Thanks

Hmm, I didn't know about the ssIndices or ssRedirectToIndex settings. What I did for my app that has dynamic and static parts, was on requests to /, alter that request to say /index.html instead and send it to the "static server".
https://github.com/LeifW/online-typechecker/blob/master/index.hs#L20

This code works for me
httpApp :: Wai.Application
httpApp = Static.staticApp $ s {Static.ssIndices = [Static.unsafeToPiece "index.html"]} where s = Static.defaultWebAppSettings "./static"

Related

Trying to create a back button using HTTP REFERER and PHP that works even after page self reload

I am trying to save the HTTP_REFERER to a $_SESSION[] variable and only updating it if the referring page does not match the current page. This way if I reload the page through a PHP script it does not save the current page I'm on as the referrer.
First I am getting the REFERER and comparing it to the current URL:
$referer = $_SERVER["HTTP_REFERER"];
preg_match('/^(.*?\:\/\/)/', $referer, $start);
$url = $start[0].$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
Then I have an IF statement that says if they DONT match to update Session:
if($url != $referer){
$_SESSION['referer'] = $_SERVER["HTTP_REFERER"];
}
Then I check the output:
echo $_SESSION['referer'];
The issue is that it updates the session no matter what!
I have tried to do the same with cookies instead of the session variable. With cookies, I can see it changing in the consol. It won't update, and then a second later it updates. Almost as if the page is loading twice.
When I set this code
setcookie('test', $_SERVER["HTTP_REFERER"]);
When I go to a new page, it will correctly display the correct refer, and then after a second, it switches to the current page.
My current setup uses .htaccess so that I don't have to type the file names of the pages. I have all requests of any subfolders go to /index.php
So http://example.com/home or http://example.com/coolpage will all go back to http://example.com/index.php
Then with PHP I look for the file named the same as that subfolder and then "include" it in my index.php file as a sort of simple templating system.
Are these .htaccess redirects messing with the $_SERVER["HTTP_REFERER"]? If I just use the $_SERVER["HTTP_REFERER"] directly within my code it works fine (it's not updating). It's only when I try to save it to another variable that things go wonky.
Is there a better way to have a back button that sends the user back to where they came from without taking into account multiple page loads of the same URI?
I found a workaround that seems a bit odd, but it achieves the effect I want.
I wrap the whole thing in an if statement only executing if the $uri != favicon.ico
if($uri != 'favicon.ico'){
$referer = $_SERVER["HTTP_REFERER"];
preg_match('/^(.*?\:\/\/)/', $referer, $start);
$url = $start[0].$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
if($url != $referer){
$_SESSION['referer'] = $_SERVER["HTTP_REFERER"];
}
$backButton = $_SESSION['referer'];
}

Hosting project in IIS appends project name to the URL and breaks my routing

I have a web api 2 project, and in my code I do some routing stuff myself.
I have all my actions going to a single route, so hitting localhost/<anything> will always go to one route.
In that route I am doing some custom pattern matching.
If the user goes to /Kittens/AdoptAKitten/12345
It will match against a template I have using regex, defined as /Kittens/AdoptAKitten/{something}
The problem is when I host my project locally, it ends up at localhost/KITTENCORP.ADOPTION/ which is the name of my project. As a result the route matching doesn't work.
I am not sure how to take into account this 'root' address. Previously I was just looking at the domain part of the Uri object but I need to include this part in the comparison to make it work (or disregard/remove it).
This code will however also be deployed to a server somewhere at which point it will probably be hosted on adoptionservice.kittens.org and thus adoptionservice.kittens.org/Kittens/AdoptAKitten/12345 will be the url. So it has to account for both situations.
Any ideas how I can resolve this problem?
For anyone stumbling across this and wondering the same thing, I fixed it with this code:
// When hosted in IIS it may get a virtual path such as localhost/KittenLibrary that needs including in comparisons
if (!string.IsNullOrEmpty(HttpRuntime.AppDomainAppVirtualPath))
{
urlStart = UrlCombine(urlStart, HttpRuntime.AppDomainAppVirtualPath);
}
UrlCombine is a function I pinched from another SO question:
private static string UrlCombine(string url1, string url2)
{
if (url1.Length == 0)
{
return url2;
}
if (url2.Length == 0)
{
return url1;
}
url1 = url1.TrimEnd('/', '\\');
url2 = url2.TrimStart('/', '\\');
return string.Format("{0}/{1}", url1, url2);
}

Routing in locomotive using ejs

I'm trying out node and some frameworks for node atm, specifically locomotive. However, i seem to be stuck on routing using locomotive. A couple questions i can't find the answer to, so here goes:
why does the locomotive out-of-box install use index.html.ejs as a
filename? Why not just index.ejs? What's the benefit?
i'm trying to add a route to a view: searchName.html.ejs which i
added in the views folder. To achieve this i made a toolController
like this:
var locomotive = require('locomotive').Controller,
toolController = new Controller();
toolController.searchName = function() {
this.render();
}
module.exports = toolController;
I also added a route in routes.js like so:
this.match('searchName', 'tool#searchName');
However, that doesn't work (and yet it's what the documentation says ought to work). The result is a 404 error. So how do i make that route work?
Suppose i want to make a route to eg, anExample.html? How do i go
about that? I notice that in the out-of-the-box app from
locomotive, you cannot enter localhost:3000/index.html . Nor even
localhost:3000/index This seems highly impractical to me, as there
are plenty of users who'll add the specific page they want to go to.
So how can i make that work?
PS: I went through all questions regarding this on stackoverflow and searched the web, but i still can't figure this out.enter code here
The benefit is that this naming scheme allows you to specify several different formats for a single route. So you could have search_name.html.ejs and search_name.xml.ejs, then respond with either view depending on what your client is expecting.
There are a couple issues with the example code you posted. You should be seeing a more descriptive error than a 404, so I'm not sure what's happening there, but here are the fixes to your code that work in my environment.
In the controller:
//tool_controller.js
var locomotive = require('locomotive');
var toolController = new locomotive.Controller();
toolController.searchName = function() {
this.render();
};
module.exports = toolController;
In routes.js:
//routes.js
module.exports = function routes()
{
this.match('searchName', 'tool#searchName');
}
Then, you'll need to change the view to this: views/tool/search_name.html.ejs. It's not clear from the documentation, but locomotive automatically lowercases and underscores actions that are camel-cased, like searchName.
Now start the app and browse to http://localhost:3000/searchName
If you just want to serve a static html file, the easiest way is to just drop it in the public folder. This folder is specifically for serving up static content like client-side js, css, etc. And it works just fine for serving static HTML as well.

How to do navigation durandal.js?

i am trying to use durandal.js for single page architecture,
i already have application where i am loading all pages in div = old approach for single page architecture,
what i want to do is when i click on page i need to open hotspa pages,
for now i write something like this . www.xyz.com#/details,
where # details is my durandal view page!
when i put <a> herf ....#/details, i got error like this :
http://postimg.org/image/hoeu1wiz5/
but when i refresh with same url, it is working fine, i am able to see view!
i do not know why i got this error
If you are using anything before version 2.0 of Durandal, you are getting this because in your Shell.js you are not defining router, or you have a bad definition of where the router module is, or possibly you are defining scripts in your index instead of 'requiring them' via require.js
1st - Check shell.js, at the top you should have a define function and it should say / do something like this, and should be exposing that to the view like so -
define(['durandal/plugins/router'], function (router) {
var shell = {
router: router
};
return shell;
};
2nd - Check and make sure the 'durandal/plugins/router' is point to the correct location in the solution explorer, in this case it is app > durandal > plugins > router. If it is not or if there is no router you can add it using nuget.
3rd - Make sure you aren't loading scripts up in your index or shell html pages. When using require.js you need to move any scripts you are loading into a require statement for everything to function properly. The 'Mismatched anonymous define() module' error usually occurs when you are loading them elsewhere - http://requirejs.org/docs/errors.html#mismatch

Standalone PHP script using Expression Engine

Is there a way to make a script where I can do stuff like $this->EE->db (i.e. using Expression Engine's classes, for example to access the database), but that can be run in the command line?
I tried searching for it, but the docs don't seem to contain this information (please correct me if I'm wrong). I'm using EE 2.4 (the link above should point to 2.4 docs).
The following article seems to have a possible approach: Bootstrapping EE for CLI Access
Duplicate your index.php file and name it cli.php.
Move the index.php file outside your DOCUMENT_ROOT. Now, technically, this isn’t required, but there’s no reason for prying
eyes to see your hard work so why not protect it.
Inside cli.php update the $system_path on line 26 to point to your system folder.
Inside cli.php update the $routing['controller'] on line 96 to be cli.
Inside cli.php update the APPPATH on line 96 to be $system_path.'cli/'.
Duplicate the system/expressionengine directory and name it system/cli.
Duplicate the cli/controllers/ee.php file and name it cli/controllers/cli.php.
Finally, update the class name in cli/controllers/cli.php to be Cli and remove the methods.
By default EE calls the index method, so add in an index method to do what you need.
#Zenbuman This was useful as a starting point although I would add I had issues with all of my requests going to cli -> index, whereas I wanted some that went to cli->task1, cli->task2 etc
I had to update *system\codeigniter\system\core\URI.php*so that it knew how to extract the parameters I was passing via the command line, I got the code below from a more recent version of Codeigniter which supports the CLI
// Is the request coming from the command line?
if (php_sapi_name() == 'cli' or defined('STDIN'))
{
$this->_set_uri_string($this->_parse_cli_args());
return;
}
// Let's try the REQUEST_URI first, this will work in most situations
and also created the function in the same file
private function _parse_cli_args()
{
$args = array_slice($_SERVER['argv'], 1);
return $args ? '/' . implode('/', $args) : '';
}
Also had to comment out the following in my cli.php file as all routing was going to the index method in my cli controller and ignoring my parameters
/*
* ~ line 109 - 111 /cli.php
* ---------------------------------------------------------------
* Disable all routing, send everything to the frontend
* ---------------------------------------------------------------
*/
$routing['directory'] = '';
$routing['controller'] = 'cli';
//$routing['function'] = '';
Even leaving
$routing['function'] = '';
Will force requests to go to index controller
In the end I felt this was a bit hacky but I really need to use the EE API library in my case. Otherwise I would have just created a separate application with Codeigniter to handle my CLI needs, hope the above helps others.
I found #Zenbuman's answer after solving my own variation of this problem. My example allows you to keep the cron script inside a module, so if you need your module to have a cron feature it all stays neatly packaged together. Here's a detailed guide on my blog.

Resources