CouchDB cross-domain access from XMLHttpRequest? - cross-domain

Currently, web application need to offer some kind of cross-domain HTTP header to access data on other domain: http://openfontlibrary.org/wiki/Web_Font_linking_and_Cross-Origin_Resource_Sharing
Is there any way to configure CouchDB to support unlimited cross-domain access? (it may use apache httpd internally) I'm using the db in-house purpose only.

The easiest way I found to solve it is by using locally installed Apache Web Server with enabled mod_proxy module and configured ProxyPass directive.
Let start with basic setup
I have Apache Web Server installed on http://127.0.0.1:8181, not configured yet
I have CouchDB installed on http://127.0.0.1:5984/
I have index.html deployd on Apache on: http://localhost:8181/couchdb.html.
index.html has the following content
<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
var http = XMLHttpRequest();
http.open('GET', 'http://127.0.0.1:5984/_all_dbs', true); // ! WE WILL CHANGE THIS LINE
http.onreadystatechange = function() {
if (http.readyState == 4 && http.status == 200) {
console.debug('it works');
}
};
http.send(null)
</script>
<head><title>Test Access to CouchDB</title></head>
<body>
</body>
</html>
If you try it just now it will not work because of the cross domain problem (in this instance ports don't match 8181 != 5984).
How to fix it
configure Apache (apache_home/conf/httpd.conf)
uncomment LoadModule proxy_module modules/mod_proxy.so
uncomment LoadModule proxy_http_module modules/mod_proxy_http.so
add ProxyPass /couchdb http://127.0.0.1:5984 (as top level property like ServerAdmin)
restart Apache
modify index.html
replace http.open('GET', 'http://127.0.0.1:5984/_all_dbs', true); with http.open('GET', '/couchdb/_all_dbs', true);
Try now and you should see 'it works' output in the javascript console (I used Firebug Console)

You could use a CouchDB show function to set the Access-Control-Allow-Origin header.
function(doc, req) {
return {
body : 'whatever',
headers : {
"Access-Control-Allow-Origin": "\"*\""
}
}
}
More info on show functions here: http://guide.couchdb.org/draft/show.html

CouchDB 1.3 solves this with CORS: https://wiki.apache.org/couchdb/CORS

Eonil, I want Cross-Domain access too, but is not supported by CouchDB,
you can vote for that feature to be implemented here:
https://issues.apache.org/jira/browse/COUCHDB-431
ps: that feature request has been created on 23/Jul/09 :( I hope they hear us.

you should enable CORS in CouchDB > 1.3. This is as simple as editing your default.ini and setting enable_cors = true and then modifying origins under the [cors] section to have the top level urls you need. For example I had to do the following to whitelist my local grunt server.
enable_cors = true
[cors]
origins = http://127.0.0.1:9000
to fully answer this question though you'd want to set
origins = *
though this could be argued to be a vulnerability, and you should probably restrict the origins more.

The way I have solved this is to write a 2 line Rebol wrapper CGI and then ask my Ajax in Jquery to call my CGI instead of the URL for getting data from Couchdb:
Rebol [
{wrapper to overcome cross-domain fetching of data from couchdb}
]
print "Content-type: application/json^/" ;text/plain^/"
print read http://127.0.0.1:5984/syncspace/_design/vals/_view/xxxx?group=true

I made a list that returns JSONp...but still read only support
"jsonp": "function(head, req) {
var row;
var rows=[];
while(row = getRow()){
rows.push(row);
}
rj = JSON.stringify({\"rows\" : rows,\"total_rows\":rows.length});
return req.query.callback+\"(\"+rj+\");\";
}",

Related

Haxe / OpenFL solving CORS error without having access to the server?

I know there are tons of questions regarding CORS policy in HTML5 tag.
All of them are talking about the server side settings that you need to change the access headers in the server settings or put the headers yourself in the php file etc.
But i am loading images using Loader class and i don't have access to that server.
how do i change the :
Access-Control-Allow-Origin to *
i tried pushing the headers with the URL Request :
urlRequest.requestHeaders.push( new URLRequestHeader( 'Access-Control-Allow-Origin', '*' ) );
but no matter what i did :
i get this error :
Complete code snippet:
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoadComplete);
var request:URLRequest = new URLRequest();
request.url = "http://www.someserver.com/some_image.jpg";
request.contentType = "image/jpeg"; //tried it didn't make a difference
request.requestHeaders.push( new URLRequestHeader( 'Access-Control-Allow-Origin', '*' ) );
loader.load(request);
In order to enable cross-origin requests, you will need to add the header on the server side. The alternative is to disable web security:
Disable same origin policy in Chrome
There was a window of time on OpenFL 6.3.0 (before 6.4.0 was released) where there was a regression in the default behavior of openfl.net.Loader (in regards to CORS), but this is resolved in OpenFL 6.4.0 or newer.
Is this for development purposes? I only ask because of the 127.0.0.1 URL involved. It looks like you are hosting your game on 127.0.0.1:3000 and requesting a URL at www.___.com/___.jpg, correct?
Not considering OpenFL specifically, one typical solution would be that the server at 127.0.0.1:3000 could have a proxy capability, fetching and serving images from another web server, so that the browser doesn't see the difference.
This wouldn't help you in the real world, but if you're talking about a development environment, perhaps it's be a workaround.

Always redirect http traffic to https traffic in google app engine nodejs flex environment [duplicate]

I've followed the answer of this: Redirect from http to https in google cloud but it does not seem to be currently accurate any more. The anchor referenced ( https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml#security ) seems to have been removed but without a note of a replacement.
For reference, I am serving NodeJS over a Google App (flex) Engine. As per the answer I've got in my app.yaml:
handlers:
- url: /.*
script: IGNORED
secure: always
Since HTTPS is obviously terminated before it hits my Express engine (and redirection on there would be useless); how is it currently correctly implemented?
Potentially helpful, I have an external domain attached via the "Custom domains" tab in the console, and there is indeed a SSL certificate configured (so if a user manually goes to https://.com everything is fine)
The flexible environment does not current support handlers in the app.yaml. If you want https:// redirection, you have a few options:
Use helmet to do to HSTS stuff for you, and implement your own initial redirect.
I wrote a happy little library to always forces SSL on all routes for express yes-https
We are considering auto-redirecting all traffic to SSL by default. Do you think that would be a good thing for your apps?
Pulling Justin's yes-https library, I was able to get this to work:
var app = express();
app.use(function(req, res, next){
if (req.host != 'localhost' && req.get('X-Forwarded-Proto') == 'http') {
res.redirect(`https://${req.host}${req.url}`);
return;
}
app.router(req, res, next);
});
At first I thought I had to do that since I was on an appengine subdomain and couldn't use HSTS. Then I learned HSTS works fine for subdomains. :) Regardless, I thought people might want to see what the magic bit to use was if they didn't want to use yes-https for some reason.
Justin, auto-redirecting all traffic to SSL by default sounds great to me. I just spent hours trying to figure out how to do so before I found this post because I was trying to get my app to get Chrome's add to homescreen install banner as per https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/.
GCP This should be as easy to just use the gcloud app cli and configure a header (Strict-Transport-Security) or redirect rule. Perhaps the push is to force us to Firebase Hosting instead which is forcing HTTPS already. For a quick solution for Single Page apps (static content) with React, Angular etc, we can use this JS snippet.
It ignores localhost environments. You can change localhost with a host name that you would like to exclude. It then redirects using https as protocol.
if ( location.host.indexOf("localhost") < 0 && location.protocol.toLowerCase() !== "https:"){
const url= `https://${location.host}`;
location.replace(url);
}

HTTP to HTTPS redirection on App Engine Flexible

I've followed the answer of this: Redirect from http to https in google cloud but it does not seem to be currently accurate any more. The anchor referenced ( https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml#security ) seems to have been removed but without a note of a replacement.
For reference, I am serving NodeJS over a Google App (flex) Engine. As per the answer I've got in my app.yaml:
handlers:
- url: /.*
script: IGNORED
secure: always
Since HTTPS is obviously terminated before it hits my Express engine (and redirection on there would be useless); how is it currently correctly implemented?
Potentially helpful, I have an external domain attached via the "Custom domains" tab in the console, and there is indeed a SSL certificate configured (so if a user manually goes to https://.com everything is fine)
The flexible environment does not current support handlers in the app.yaml. If you want https:// redirection, you have a few options:
Use helmet to do to HSTS stuff for you, and implement your own initial redirect.
I wrote a happy little library to always forces SSL on all routes for express yes-https
We are considering auto-redirecting all traffic to SSL by default. Do you think that would be a good thing for your apps?
Pulling Justin's yes-https library, I was able to get this to work:
var app = express();
app.use(function(req, res, next){
if (req.host != 'localhost' && req.get('X-Forwarded-Proto') == 'http') {
res.redirect(`https://${req.host}${req.url}`);
return;
}
app.router(req, res, next);
});
At first I thought I had to do that since I was on an appengine subdomain and couldn't use HSTS. Then I learned HSTS works fine for subdomains. :) Regardless, I thought people might want to see what the magic bit to use was if they didn't want to use yes-https for some reason.
Justin, auto-redirecting all traffic to SSL by default sounds great to me. I just spent hours trying to figure out how to do so before I found this post because I was trying to get my app to get Chrome's add to homescreen install banner as per https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/.
GCP This should be as easy to just use the gcloud app cli and configure a header (Strict-Transport-Security) or redirect rule. Perhaps the push is to force us to Firebase Hosting instead which is forcing HTTPS already. For a quick solution for Single Page apps (static content) with React, Angular etc, we can use this JS snippet.
It ignores localhost environments. You can change localhost with a host name that you would like to exclude. It then redirects using https as protocol.
if ( location.host.indexOf("localhost") < 0 && location.protocol.toLowerCase() !== "https:"){
const url= `https://${location.host}`;
location.replace(url);
}

transmission rpc with expressjs

i currently have transmission-daemon web ui served by nginx
server {
listen 2324;
server_name torrent.example.com;
location /rpc {
proxy_pass http://127.0.0.1:9091/transmission/rpc;
}
location /transmission {
proxy_pass http://127.0.0.1:9091/transmission;
}
location / {
proxy_pass http://127.0.0.1:9091/transmission/web/;
}
}
i am trying to display this page via https://github.com/stormpath/stormpath-express-sample this dashboard/user interface
in routes/index.js i have
router.get('/torrent', function (req, res, next) {
if (!req.user || req.user.status !== 'ENABLED') {
return res.redirect('/login');
}
var newurl = 'http://127.0.0.1:2324'
request(newurl).pipe(res)
});
i see the html when i goto /torrent but no images/css/js i am thinking the request is not the right tool for this purpose could some one offer a better solution
many thanks
Your HTML probably refers to CSS/images/etc using URLs such as /index.css. The browser makes these into fully-qualified URLs that look like http://torrent.example.com/index.css, which is not proxied by ngnix the way you have it set up.
You probably want to either use URLs such as /transmission/index.css for your CSS (when specified in the HTML), or alternatively have a <base> tag in your HTML for that.
ok so i have made progress with html/css i moved the transmission interface into the express root and imported the html into jade but now i am having a new problem
when i load the /torrent page i can seen in the web console it makes a request to /rpc which i have made a route for
router.get('/rpc|/rpc/', function (req, res) {
var newurl = 'http://127.0.0.1:9091/torrent/rpc/'
request(newurl).pipe(res)
});
but this comes up with a 404 when i change router.get to router.post i get a 405 error
i have removed the 409 error from transmission so this should work
i have solved the issue
i imported the transmission index.html into a jade template
i routed /torrent to render that template
then i made a new route for /rpc|/rpc/ made that do a post request to the backend transmission-daemon
i also changed /js/remote.js to look for the RPC._Root at the atchual domain

How to know if a request is http or https in node.js

I am using nodejs and expressjs. I wonder if there is something like request.headers.protocol in the clientRequest object. I would like to build the baseUrl for the web links. So if the request was done via https I would like to keep https in all links.
var baseUrl = request.headers.protocol + request.headers.host;
Edit: For Express, it's safer and recommended to use req.secure (as #Andy recommends below). While it uses a similar implementation, it will be safe for future use and it also optionally supports the X-Forwarded-Proto header.
That being said, for your use case it would be quicker to use Express' req.protocol property, which is either http or https. Note, however, that for outgoing links, you can just refer to //example.com/path, and the browser will use the current protocol. (See also Can I change all my http:// links to just //?)
For node Request object without Express:
It's in req.connection.secure (boolean).
Edit:
The API has changed, for Node 0.6.15+:
An HTTPS connection has req.connection.encrypted (an object with information about the SSL connection). An HTTP connection doesn't have req.connection.encrypted.
Also (from the docs):
With HTTPS support, use request.connection.verifyPeer() and request.connection.getPeerCertificate() to obtain the client's authentication details.
req.secure is a shorthand for req.protocol === 'https' should be what you looking for.
If you run your app behind proxy, enable 'trust proxy' so req.protocol reflects the protocol that's been used to communicate between client and proxy.
app.enable('trust proxy');
For pure NodeJS (this works locally and deployed, e.g. behind Nginx):
function getProtocol (req) {
var proto = req.connection.encrypted ? 'https' : 'http';
// only do this if you trust the proxy
proto = req.headers['x-forwarded-proto'] || proto;
return proto.split(/\s*,\s*/)[0];
}
You don't need to specify the protocol in URL, thus you don't need to bother with this problem.
If you use <img src="//mysite.comm/images/image.jpg" /> the browser will use HTTP if the page is served in HTTP, and will use HTTPS if the page is served in HTTPS. See the #Jukka K. Korpela explanation in another thread.
This worked for me:
req.headers['x-forwarded-proto']
Hope this helped,
E
This is what works for me:
getAPIHostAndPort = function(req, appendEndSlash) {
return (req.connection && req.connection.encrypted ? 'https' : 'http') + '://' + req.headers.host + (appendEndSlash ? '/' : '');
}
If you are using request module and for example want to know what protocol does some www use, you can use: response.request.uri.protocol
request(YOUR_TARGET, function(error, response, body){
if (error){
console.log(error);
}
else {
console.log(response.request.uri.protocol); // will show HTTP or HTTPS
}
});
If you need user protocol then use request.headers.referer.split(':')[0]; just like #Harsh gave you.
If you want to know whether request is http or https then use this in your code:
req.headers.referer.split(':')[0];
This will return whether req is http or https.
If you want to find the request protocol string: either http or (for TLS requests) https just use
req.protocol
Express documentation: https://expressjs.com/en/4x/api.html#req.protocol

Resources