HTML5 PushState Regex Issue - regex

I've been experimenting with Backbone for a project I'm working on, and I've been having problems with getting Backbone's 'pushState' functioning how I'd like to.
I've got a simple project consisting of 4 views, and a router. I'm routing via the id of the elements if it matters in this case. When I go to the hash for one of the views (http://example.com/backbonetest/#step1), it's displayed correctly, and the url is changed. This is what I'd expect to happen here, but the problem comes when I try and navigate to the same thing without the hash in it (http://example.com/backbonetest/step1). I get a 404 on the server (IIS) which is to be expected, as the page doesn't exist.
What I've been trying to do all day is write a regex expression for IIS which would catch and rewrite the url, removing the fragment at the end of the url so the page is served correctly. I'd rather simply rewrite the url than having a physical file with the same name, as the content of the page will be dynamically generated, and will require scripts to get the content anyway.
The issue I've come across may be related to how I need to have the folders/scripts/styles structured on the file system. I was hoping to be able to have the whole example contained within the /backbonetest/ folder. For scripts, 'backbonetest/scripts' and so on.
I made a list of URLs which I've been testing my regex expressions against, and the results I've been trying to achieve:
Input: Output:
2
a2
ab2
ab22
step2
script.js script.js
scripts/ scripts/
555/stuff 555/stuff
scripts/script.js scripts/script.js
Edit: I've since found that the url which is used does not include the preceding slash,
which is why Qtax's solution doesn't work in IIS. The new input structure is shown above.
The '/555/stuff' url I would expect to 404 as normal. I only want to rewrite the url if there are no subdirectories defined other than the current one, and if the url doesn't reference an explicit file (one with an extension for example).
I've been scouring the net all day for a solution to this, as well as experimenting with regexr, but not managed to come up with the proper solution to my problem. After not finding a single thing anywhere, I'm thinking I must be looking at this the wrong way...
Can anyone help me out please?

After much head/desk banging, I've come up with the solution. It's irritatingly simple for all the fuss it's caused:
^[^\./]+$
Essentially:
Replace if the url doesn't contain a '/' or a '.' anywhere in it.
This should now be a solution for anyone using IIS with Backbone and HTML5 push state. Just pop it in the web.config in the root of your app, and change the rewrite action to ".", and it should just work.

This melted my brain all morning!
I've added to this - In my scenario, I have an API project which sits in an API virtual directory (to eliminate the need for CORS) - I obviously don't want to rewrite any of the PAI calls, so I re-wrote mine as follows - you can do similar for your API URLs if needed...
<rule name="Handle PushState">
<match url="^[^\./]+[^\./api]+(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="." />
</rule>

Related

Case Sensitive URL

I've launched a small website.
I have found that I'm getting errors by users and upon investigation see that the urls they are trying to use are all lowercase whereas I've declared them as camelCase.
I've no idea why these users should be trying to use all lower case (I can't imagine anyone would actually take the time to change:
www.mysite.com/myAction.do
to
www.mysite.com/myaction.do
However I can't think of anyway this would otherwise be changed. Has anyone else experienced this where:
yourAction.do in your mapping file is then attempted to be accessed by users as youraction.do ?
I'm using Struts2.3.1, sitemesh 2.4.2 - I've never heard of or encountered such a situation and would like advice on what may be causing it if any of you have encountered the same or similar.
Are there any browsers out there that remap camelCase.do to camelcase.do ? For whatever reason.
The only 'solution' I can think of (the best out of two very ugly and inelegant workarounds) is to duplicate the action mappings in struts.xml
<action name="myAction" class="myActionClass" />
<action name="myaction" class="myActionClass" /> //added extra but what a 'dumb' solution
Edit:
Is is possible to do the same with methods?
So that:
myAction!clear.do
will still be correctly mapped with the URL:
myaction!clEAr.do
?
I notice from re-reading my error logs that it's the 'wrong case' method in the ULR which is causing most errors.
You can use regex pattern matcher with (?i) to "embed" the matching flag(s) in the regex body. For example
<constant name="struts.patternMatcher" value="regex" />
<action name="{(?i)myaction}" class="myActionClass" />

Changing default base URL of Sitecore ServiceApiController, Is it possible?

when we implement SitecoreApiController, for each action method we make using Sitecore.Services.Core.ServicesController("namespace") attribute, we get a url like this:
/sitecore/api/ssc/{namespace}/{controller}/{id}/{action}
I wonder if we could change this default pattern, somehow in config files. I particularly interested in /sitecore/api/ part, because sometimes in the sense of security concerns, certain clients don't like to reveal that much about CMS platform behind the scene. Sometimes they even ask us to hide anything in HTTP header that tells about Microsoft ASP.NET explicitly.
Is this possible here?
Edit
this link shows a way to customize it using pipelines but I wonder if we could change the base url just through config files without needing a custom pipeline
I had a look at it, and I think I found out how - although I haven't tested it.
It looks for a setting named Sitecore.Services.RouteBase and if it can't find it, it uses sitecore/api/ssc/ as the default value.
You should be able to change it with a config patch like this in the App_Config/Include folder:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<settings>
<setting name="Sitecore.Services.RouteBase" value="custom/api/" />
</settings>
</sitecore>
</configuration>

How to remove comments when server returns a JSP page?

Which class of tomcat is responsible for converting .jsp file to .class file? I want to see the source code written for the conversion. My aim is to check the logic how scriptlet comments are eliminated and based on that I'll write my own code that will remove HTML comments as well (I've not decided how will I implement it).
I am sure source code should be available as it's open source.
Or is it possible to implement some kind of filter so the each time server returns a JSP page it removes the comments. I can replace all HTML comments into Scriptlet comments. But I want to ensure, if someone use html comments in future, it is not displayed. It's basically for security.
[Added]
As per the suggestion given by JB Nizet, we will be modifying build.xml file to remove comments. I have come up with this to remove HTML comments -
<target name="-trim.html.comments">
<echo message="Inside trim html comments" />
<fileset id="html.fileset" dir="${build.dir}" includes="**/*.jsp, **/*.html" />
<!-- HTML Comments -->
<replaceregexp replace="" flags="g" match="\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>">
<fileset refid="html.fileset"/>
</replaceregexp>
</target>
However, I am not sure how to remove comments that starts with // or /* */. Any suggestion how can I do so? I have searched over internet but didn't get a clue.
We are using ant script for build.
[Added]
To remove single line comment that starts with // I am using below regex. But somehow it's not working. Can anyone please help me what I'm doing wrong? Thanks in advance.
<replaceregexp flags="gs" match="?:^\s*\/\/(?:.*)$" replace="">
Rather than doing it in Tomcat, use Apache directly. It supports modules which do exactly what you need. mod pagespeed is probably closest to what you want; mod deflate may be configurable to do the same thing, though it also compresses the data, which might be overkill.
As a nice side-effect, this allows you to leave your handy comments in and they'll be served to your internal users (developers) who use port 8080, while those using port 80 will see only the minified product.

URLRewriteFilter re-writing of params for a nicer url

I've tried a couple of different options to re-write URLs but I seem to be failing, I'm not sure if it's cause what I'm trying to do is more complex or not...
I have this working currently in my app, calling either of these URLs, I can access my pages:
http://localhost:8080/myapp/template.jsp?site=mysite1&lng=en&pageToLoad=welcome
This could also be (note the m-)
http://localhost:8080/myapp/m-template.jsp?site=mysite1&lng=en&pageToLoad=welcome
However, I would like to re-write my URLs to look like this:
http://localhost:8080/myapp/mysite1/en/welcome
http://localhost:8080/myapp/m/mysite1/en/welcome
I have tried using JBoss's:
org.jboss.web.rewrite.RewriteValve
And now I'm attempting with:
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
But I can't figure out how my rule in either would need to be written so that I can make this change, any suggestions would be much appreciated.
Wow, pretty much took all day, but I finally got it. There might be a way to improve, but this is what I got working and I won't be tweaking it myself till it's committed to git :)
<rule>
<from>^([/m])([a-z]*)/(en|it)/([a-z]*)(?!.)</from>
<to>/template.jsp?site=$2&lng=$3&pageToLoad=$4</to>
</rule>
<rule>
<from>m/([a-z]*)/(en|it)/([a-z]*)(?!.)</from>
<to>/m-template.jsp?site=$1&lng=$2&pageToLoad=$3</to>
</rule>
<outbound-rule>
<from>([^\r]*)/template\.jsp\?site=([a-z]*)&lng=(en|it)&pageToLoad=([a-z]*)</from>
<to>%{context-path}/$2/$3/$4</to>
</outbound-rule>
<outbound-rule>
<from>([^\r]*)/m-template\.jsp\?site=([a-z]*)&lng=(en|it)&pageToLoad=([a-z]*)</from>
<to>%{context-path}/m/$2/$3/$4</to>
</outbound-rule>
Hope this'll be helpful to others.
Cheers.

Cant build correct Regular Expression for Mod Rewrite/URLRewriteFilter. How do I negate a range?

I am having trouble building such a simple rule. I want to clean a URL only if the class 1 variable does not fall between 4000 and 5999.
When the user goes to f?p=3999:1:1::::: I want the user to be directed to /3999/1?vars=:1:::::. If the user goes to f?p=4000:1:1::::: the URL will not be cleaned.
Here is what I have thus far. This does what I want it to with the exception of the range. Someone please help!:
<rule match-type="regex">
<note>
FROM= URL typed in by user
TO= URL user is redirected to.
</note>
<from>^/f\?p=([0-9A-Za-z]+):([0-9A-Za-z]+):([0-9A-Za-z]*)(.*)$</from>
<to type="redirect">/$1/$2?vars=$3$4</to>
</rule>
Using the solution provided by Lindrian, I was able to insert it into my code to get desired results.
The final solution:
<rule match-type="regex">
<note>
FROM= URL typed in by user
TO= URL user is redirected to.
</note>
<from>^/f\?p=((?:[0-3]|[6-9])[0-9]*|[54]\d{4,}):([0-9A-Za-z]+):([0-9A-Za-z]*)(.*)$</from>
<to type="redirect">/$1/$2?vars=$3$4</to>
What I am doing here is using URLRewriteFilter to clean up an oracle application express URL. The issue here is that APEX is using relative referencing so if you login to APEX the linked pages will now look for $1/f?p... as the linked paged. This errors out because $1 doesnt exist! So, I turned URL cleaning off for the development UI
I can't help you with the mod-rewrite code, but I can help you with your regular expression. Even though regex is not the best tool for doing things like this, it can be done.
I have created a short simple regular expression that matches all digits but those in the range of 4000to 5999: http://regex101.com/r/aU5qC4
I hope you can make this work with your other code.
Good luck.