Express route with multible slash - Linux & Windows difference - node.js

I have encountered a strange behaviour with express routes. I want to enter an ID via HTML-Form and fetch the result via ajav (jquery) to display the entry. All was working fine, till i have to expand the ID from numbers to strings (with slashes).
I edited all functions and calls. I check the strign with a reg ex and want to fetch the request with a modified route (express). but here comes the problem. i get it working under windows but it is failing on linux. Perhaps the problem is caused by the invrastructure, because the node.js app is located behind an reverse proxy apache2 to tunnel the service to public (with domain & cert).
what ever. perhaps somebody can help me set this thing up and get it running.
app.get(/^\/byId\/(.+)/, getSourceById);
not using req.params[0] in the called function. on the test server (windows) it is working even with the old route
app.get('/byId/:id', getSourceById);
because the html form does request %2F not /. How ever, both ways should work to fetch the request. But both aren't working for me. did i miss something?
i'm thankful for any help!

Found the answer of my question. It was indeed the reverse proxy who was blocking the request.
Simular problem: http://www.gossamer-threads.com/lists/apache/users/314562
How to solve the behaviour:
http://httpd.apache.org/docs/2.0/mod/core.html#allowencodedslashes
Default forbidden because of security issues. If you need it, use it carefully.

Related

How To Setup Https In Nest js (Official doc solution is not working)

I have two B/E servers and both of them deployed in an SSL environment.
EX:- https://one-xxx.com/ and https://two-xxx.com/
And I have a strategy like this.
https://one-xxx.com/api/v1/get -> https://two-xxx.com/api/v1/get
When My F/E application makes a request to the first E/P and it is going to hit the second E/P (Just like reverse proxy).
When I make a request for this E/P it's returning this error: Error: unable to verify the first certificate.
I google this error and found out what is going on and this solution for nest js. (It's on nest js official doc). But the problem is when I apply those changes to both my B/E server My Error remains the same. I really need your help on this. Thank you!

A third party application may be attempting to make unauthorized access to your account - Ameritrade

I was trying to do some simple authorization for ameritrade's developer platform. I was attempting.
According to the platform, the Endpoint I need to access is is:
https://auth.tdameritrade.com/auth?response_type=code&redirect_uri={uri}&client_id={client_id}}%40AMER.OAUTHAP
https://developer.tdameritrade.com/content/simple-auth-local-apps
When looking at the client_id, for the dev application, I was noticing that they may actually be referencing the Applications, Consumer Key instead? So i did just that, but when attempting to query the information, it returns: A third-party application may be attempting to make unauthorized access to your account. The reason why i think it is the consumer key, is listed at: https://developer.tdameritrade.com/content/getting-started
So I ended up doing something like:
from urllib.parse import urlencode, quote_plus
url = "https://auth.tdameritrade.com/auth?response_type=code&redirect_uri={uri}&client_id={client_id}}%40AMER.OAUTHAP".format(
uri=urlencode("http://localhost", quote_via=quote_plus),
client_id="JHBDFGJH45OOUDFHGJKSDBNG" #Sample
)
I dont think this is because I am currently in a different country currently, I think that something else is wrong here.
It doesnt follow through with it, but instead returns a 400 error with that information. Im not sure whats wrong though.
This happens when you copied the callback URI incorrectly. Imagine if this were a client application, and TD detected that the application is trying to send the user to a different URL than the app is configured with. If they send the callback request to that application, it will receive the token and gain full control over your account.
Have you double and triple checked that you're copying the callback URL correctly, protocol name, ports, and trailing slashes and everything? Also, consider using an API library instead of writing your own. You can find documentation about this specific error here.
I had this issue and I solved it using simply using http://127.0.0.1 on the call back URI of the App.
I then used below URL and it worked as expected.
https://auth.tdameritrade.com/auth?response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1&client_id={MyConsumerKey}%40AMER.OAUTHAP
Just in case anyone is still having this problem, make sure the callback URI is spelled EXACTLY the same as you specified when creating the app. I was having this problem because I set the callback on the TD developer website to "https://localhost/" and used "https://localhost" in the URL instead (missing the slash at the end). As soon as I added the slash at the end, it worked.
I found out that the issue is caused by the way the callback URL is set. It have to be exactly the same as the callback URL you have typed in at the apps details on the TD developer API page. I tried several permutations and indeed to get the authorization to work both have to be the same. eg. https or http.. end with '/' or does not, it matters. There is also no need to URL encode it.

Is it possible for an http request to be too long? why do I keep getting back a 400?

I have written some code in node.js that is expecting a whole slew of unique id's in the route.
it looks something like this
api/389+138+638+659+665+814+148+713+730+834+241+77+682+802+173+661+695+192+809+733+644+272+675+735+76+656+660+757+144+745+628+593+624+787+788+789+129+668+810+630+474+673+716+36+837+771+203+725+169+133+655+103+636+731+11+300+813+417+742+799+803+794+755+812+429+387+75+831+830+451+163+835+642+734+817+844+696+187+286+363+613+750+822+807+292+38+671+710+793+437+683+676+649+648+392+712+711+702+801+653+754+806+597+843+140+643+740+773+394+223+294+48+239+792+827+824+826+815+828+825+795+309+805+838+335+722+412+749+763+301+634+820+821+819+818+833+785+720+718+719+744+743+631+782+753+796+847+832+736+645+641+196+848+27+421+748+737+777+778+172+457+625+780+845+666+433+574+577+368+63+846+633+623+411+249+640+762+791+410+770+797+727+377+449+839+840+237+709+751+829+694+219+229+841+800+647+81+674+376+114+444+685+407+432+431+403+760+678+579+836+752+408+586
I get a 400 -- bad request back every time.
But, if I shorten the list significantly like this it hits the API with no problems.
api/429+387+75+831+830+451+163+835+642+734+817+844+696+187+286+363+613+750+822+807+292+38+671+710+793+437+683+676+649+648+392+712+716
Is it possible for a request to be too long? It may also be worth noting that this is not an issue at all when I'm developing locally. It only throws it back at me when I'm in one of our deployed environments.
Is there a better way to make this request or is there some kind of node, server, or application setting that can be adjusted?
Yes, it is possible. You need to increase the size in your web server (ex: nginx, apache)
Add this to your server block for nginx
client_max_body_size 2M;
For anyone else who stumbles across this, it seemed like the only way to change this was to get into the IIS register. I didn't want to do that because this for a number of reasons. So instead, I changed my code to have to route be a POST instead of a GET and sent all of the info in the header. This may not fix the issue 10 times out of 10, but it took me like 20 minutes to reconfigure everything on the front and back end and it works fine.

Flask - Trouble Requesting Specific Endpoint that lies at a Subdomain

So.. Back again with another flask question:
My application is set up largely around the use of subdomains for various portions instead of prefixes. As such, typical urls for my app look like this:
domain.tld/
domain.tld/about
admin.domain.tld/
admin.domain.tld/login
etc.
I'm composing unit tests and I've seem to run into a problem. I've done a lot of searching of the Flask and Werkzeug documentation but I can't seem to figure out how to fix my issue.
Basically, when I'm testing I'm trying to simulate a GET request to various urls.. and a lot of those URLs will fall on subdomains. I've tried the following which would seem to be logical:
with app.app_context():
url = url_for("admin.login") # returns http://admin.domain.tld:80/login
with app.test_client() as c:
resp = c.get(url) # Fails: returns 404
assert resp.data == "Expected test response", "Bad Response"
Now.. my c.get should return a response containing expected data at the url, but instead I'm being given the default 404 handler. This makes it quite hard to test many of my routes.
I've done some reading into Flask and found a github issue that notes that the test client expects a relative url... well.. I'm not sure how to provide that since I need to specify the subdomain.
Additionally, I've done further reading and discovered that the Flask test client is built on the Werkzeug test client and the Werkzeug test client contains an option for "allow_subdomain_redirects" that is normally false. Sadly, attempting to configure my Flask test client to have that behavior so far has failed (I might be doing it wrong).
Anyways, does anyone know how I can simulate a request in my flask app and target a subdomain? At the moment, I'm all out of ideas. Thanks for any suggestions. :)
So.. After a lot of debugging I have found the problem... and it seems to be a Flask issue after all, though not the one I linked above.
First, after LOTS of searching I found this archive here which seemed to give guidance on how to properly make the request for subdomains:
with app.test_client() as c:
c.get("/target/path.html", base_url="admin.domain.tld/")
There is a caveat, however... Depending on what app.config["SERVER_NAME"] is set to this might not work... Specifically, as of flask 0.11.1 if app.config["SERVER_NAME"] has an explicit port of 80 the above c.get will FAIL. (i.e. if SERVER_NAME looks like domain.tld:80 ) However.. if SERVER_NAME contains any other port it will function properly. (i.e. if SERVER_NAME looks like domain.tld:5000 everything will work fine)
I don't know if this is intended or not.. but it has caused me a lot of headache and work.. I'll be posting a github issue on it shortly just to make sure it is indeed intended.

Server side response to allow client side routing

I am developing a single page application that has a client side router. so although the base url to run the application will be either http:://example.com or http:://example.com/index.html - skipping the domain name that is routes '/' and '/index.html'
But somewhere in my application, because of my client side router, I may call up a route something like '/appointments/20160113 and the client router will redirect me to the appropriate "Appointments Page" inside my SPA passing the parameter of todays date.
But if the user calls directly http://example.com/appointments/20160113, I am led to believe that the server should respond directly with /index.html so the browser doesn't get a 404.
I am building the server using nodejs (specifically the http2 module, but I don't think that is very important, and my examples don't use https, although with http2 they do). I just tried changing the server so if its hit with an unknown url it responds with the index.html file.
However, the browser sees this as its first response and then makes requests for the rest of its attached files relative to the url (so for instance follows up with /appointments/20160113/styles/main.css). This leads to an infinite loop, as the server responds with another copy in index.html (and immediately gets a request back for /appointments/20160113/styles/styles/main.css ).
Its too early in the lifecycle of the page for the javascript to be running yet (and specifically the router software), so clearly the approach is too simplistic.
I have also written the client side router (using the history api) so I can change things if I need to.
How should this situation be handled. I am thinking perhaps a 301 redirect to /index.html or something and then the router's initial dispatch knows this and can do a popstate or something. I ideally want to support the passing of urls via external means between users, but until I actually tried to implement it I hadn't realise the implications.
I don't know if this is the best way or not, but having not received any answers on here, I decided to try a number of different ways and see which worked out the best.
Each way involved doing a 301 redirect to /index.html, and then providing the url from which I was redirecting via different mechanisms
This is what I tried
Setting a cookie with a short expiry date the value of which was the url
Adding a query string with a ?redirect= parameter with the url
Adding a #fragment after /index.html with the url
In the end I rejected 1) because chrome wasn't deleting the cookie after I had used it and making the value shorted lived depends on accurate timing between client and server. The solution appeared too fragile.
I tried 2) and it was looking good until I came to test it. Unfortunately setting window.location.search causes a page reload, and I was really struggling with finding out what was happening. However, what I discovered in 3) about mocking could well be provided to a solution based on 2) so it is one that could be used. I still might return to this solution as it "feels" right to me.
I tried 3) and it worked quite well. However I was struggling with timing issues in testing since my router element was using the #fragment during initialisation, but I couldn't set the window.location.hash until after the router was established in the test suite. I wanted to mock window.location.hash with sinon so I could control it, but it turns out you can't
The solution to this was for the router to wrap its own calls to window.location.hash in a library, so that I could mock the library. And that is what I did in the end and it all worked.
I could go back to using a query string and wrapping window.location.search in a library call, so I could stub that call and avoid the problems of page reloading.

Resources