update URL string with different port - javascript

In my program I got URL like following format,
when I use the url.parse nothing happen,I need to change the port ,how it suggested do do that ?
The port is after the colon %3 55123 and I need to change it to 8080
http%3A%2F%2Fmo-de73.mo.bmw.corp%3A55123%2Flogin%2Fcallback&client_id=s2.app
The number can be change(any valid port) so I cannot use the replace
Btw there is parser which change the format from %3 to colon and and %2F to slash as standard URL output?

Before you can parse it, you must decode it. You can do this using the built-in decodeURIComponent function.
var url = require('url');
var encodedUrl = 'http%3A%2F%2Fmo-de73.mo.bmw.corp%3A55123%2Flogin%2Fcallback&client_id=s2.app';
var decodedUrl = decodeURIComponent(encodedUrl);
//=> 'http://mo-de73.mo.bmw.corp:55123/login/callback&client_id=s2.app'
var parts = url.parse(decodedUrl);
/* =>
{ protocol: 'http:',
slashes: true,
auth: null,
host: 'mo-de73.mo.bmw.corp:55123',
port: '55123',
hostname: 'mo-de73.mo.bmw.corp',
hash: null,
search: null,
query: null,
pathname: '/login/callback&client_id=s2.app',
path: '/login/callback&client_id=s2.app',
href: 'http://mo-de73.mo.bmw.corp:55123/login/callback&client_id=s2.app' }
*/
parts.port = 8080;
//=> 8080
delete parts.host;
//=> true
url.format(parts);
//=> 'http://mo-de73.mo.bmw.corp:8080/login/callback&client_id=s2.app'
The last part there is a bit of a hack. After you update the port, your parts object will look like this
{
// ...
host: 'mo-de73.mo.bmw.corp:55123',
port: '8080',
hostname: 'mo-de73.mo.bmw.corp',
// ...
}
The hostname is correct, but the host still has the port hard-coded in there. If you just remove the host using delete parts.host, url.format will automatically create the correct host using {hostname}:{port}.
Maybe there's a better way to do it, but at least this should get you started.

Try this
var url="http%3A%2F%2Fmo-de73.mo.bmw.corp%3A55123%2Flogin%2Fcallback&client_id=s2.app";
url=url.replace('%3A55123',":8080");
var decodedUrl = decodeURIComponent(url);
//decodedUrl=http://mo-de73.mo.bmw.corp:8080/login/callback&client_id=s2.app

Related

Adding rule to the security group which is created automatically

I am using the AWS CDK to create an ApplicationLoadBalancer which has port 80 accepting external connections.
I want to use port 8080 of target to health check port.
const lb = new elb.ApplicationLoadBalancer(this, "LB", {
vpc: cluster.vpc,
loadBalancerName : loadBalancerName,
internetFacing: true,
vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
});
const listener = lb.addListener("Listener", { port: 80 });
const targetGroup = listener.addTargets("ECS", {
protocol: elb.ApplicationProtocol.HTTP,
port: 80,
targets: [ecsAdminService]
});
targetGroup.configureHealthCheck({
path: "/",
port: "8080"
})
In this case ApplicationLoadBalancer makes the security group automatically.
However, it has an outbound rule only port 80. I want to add anoutbound rule port 8080
How can I change the security group so it is automatically generated?
When you create a Load Balancer with CDK if a security group isn't provided, the CDK will be automatically create a Security Group for you.
So, if want to manage the Security group rules, you can create a Security Group with the rules that you need and attach to the created ALB:
const securityGroup1 = new ec2.SecurityGroup(this, 'SecurityGroup1', { vpc });
securityGroup1.addIngressRule(
ec2.Peer.anyIpv4(),
ec2.Port.tcp(80),
'allow HTTP traffic from anywhere',
);
const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
vpc,
internetFacing: true,
securityGroup: securityGroup1, // Optional - will be automatically created otherwise
});

Trying connection mqtt in browser

I'm trying to get a mqtt connection on my browser with JS
I'm following this tutorial: https://emqx.medium.com/use-websocket-to-connect-to-mqtt-broker-9e7baf1aa773
So I've got this:
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script>
// Globally initializes an mqtt variable
const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)
const host = 'ws://broker.***.***.com:9883'
const options = {
keepalive: 60,
clientId: clientId,
username: '***',
password: '***',
protocolId: 'MQTT',
protocolVersion: 4,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
will: {
topic: 'WillMsg',
payload: 'Connection Closed abnormally..!',
qos: 0,
retain: false
},
}
console.log('Connecting mqtt client')
const client = mqtt.connect(host, options)
client.on('connect', () => {
console.log('Client connected:' + clientId)
// Subscribe
})
</script>
And in my browser I've got this error:
After some research, some people say that need to use certificate: https://github.com/eclipse/paho.mqtt.javascript/issues/187
So, I've got this :
<script src="../browserMqtt.js"></script>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
var options = {
keyPath: '../credentials/client-key.pem',
certPath: '../credentials/client-cert.pem',
rejectUnauthorized : false,
ca: ['../credentials/a-cert.pem'],
protocolId: 'MQTT',
username: '***',
password: '***',
clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8)
};
var client = mqtt.connect('ws://broker.***.***.com:9883',options);
client.on('connect', function(){
console.log('Connected');
});
</script>
I've got the same error in browser ...
The broker conguration for mosquitto, it's like this :
allow_anonymous false
password_file /mosquitto/config/passwd
#TCP
listener 1883
socket_domain ipv4
#SSL
listener 8883
socket_domain ipv4
cafile /mosquitto/config/tls/ca/ca-cert.pem
certfile /mosquitto/config/tls/server/server-cert.pem
keyfile /mosquitto/config/tls/server/server-key.pem
tls_version tlsv1.2
socket_domain ipv4
#WSS
listener 9883
socket_domain ipv4
protocol websockets
cafile /mosquitto/config/tls/ca/ca-cert.pem
certfile /mosquitto/config/tls/server/server-cert.pem
keyfile /mosquitto/config/tls/server/server-key.pem
tls_version tlsv1.2
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
log_timestamp_format %Y-%m-%dT%H:%M:%S
log_type all
I can't understand how can I solve it ? Thanks for your help
You can't use client side certs in the browser to authenticate the client (unless you load them into the browsers keystore, but even then I'm not convinced it will work unless there is only one cert/key for the browser to pick as javascript code won't normally prompt the user to pick the right one).
Also loading client certs over http from the server totally defeats the point of using a client cert as anybody can download them.
You need to remove all of the following from the options
keyPath: '../credentials/client-key.pem',
certPath: '../credentials/client-cert.pem',
rejectUnauthorized : false,
ca: ['../credentials/a-cert.pem'],
protocolId: 'MQTT',
Because the paths are meaningless in the browser (and for the reasons I mentioned earlier)
You should also be starting your broker URL with wss:// to make it clear you are trying to connect over secure WebSockets.

Making .local resolve to IP address AND port (mdns)

I'm using the multicast-dns node module to attempt making this work.
Looking up custom.local in the browser gives me the console message I setup, but I'm unable to see my actual server running (which is doing so at localhost:12345, where 12345 is a dynamic number). I want to be able to see my local server when visiting custom.local. Is this possible?
Here's some code:
mdns.on("query", query => {
if (query.questions[0] && query.questions[0].name === "custom.local") {
console.log(query);
mdns.respond({
answers: [
{
name: "custom.local",
type: "SRV",
data: {
port: n.get("p"), // dynamic port
weight: 0,
priority: 10,
target: ip // local IP
}
}, {
name: "custom.local",
type: "A",
data: ip,
ttl: 300
}
]
});
}
});
EDIT: I can connect to my local server just fine, that wasn't an issue.
Quoting cfreak:
You can't put port numbers in DNS. DNS is only for looking up an IP by name. For your browser to see it by the name alone you need a proxy program in front of your service or you need to run the service itself on port 80. Port numbers really shouldn't be dynamic. You should specify it in the setup of your service.
That answers my question and offers next steps. Thanks!
UPDATE: Figured out what I was trying to do. Here's some code!
FOUND A SOLUTION, WOOP WOOP!
I'm using this module, but tweaked the source a bit (only because I have dynamic ports, because I feel like it).
/* jshint undef: true, unused: true, esversion: 6, node: true */
"use strict";
//
// G E T
// P A C K A G E S
import express from "express";
import http from "http";
import local from "./server/local";
const n = express();
n.get("/", (req, res) => {
res.send("Welcome home");
});
//
// L A U N C H
const server = http.createServer(n);
server.listen(0, () => {
const port = server.address().port;
local.add(port, "custom.local");
});
Hope this helps you as well, future Internet searcher! :D
Don't let negative folks on other SE sites bring you down. :virtual fist bump:

URL is not a function node.js

I've been trying to use the url module for node js described here: https://nodejs.org/api/url.html#url_url, but I can't seem to get the simple examples to work. I'd like to be able to build a url, but with the following code,
const URL = require('url');
const apiUrl = new URL('myapi.com/');
apiUrl.searchParams.set('tickers', tickers);
console.log(apiUrl.href);
I run into the error that URL is not a function. I've tried this with the other way the site suggests initializing URL too, as
const { URL } = require('url');
But that causes syntax errors on the first open bracket.
How can I use the url module to actually manipulate urls?
Edit:
In light of MinusFour's suggestion, I'm now up to here:
const URL = require('url').Url;
const apiUrl = new URL('myapi.com/');
console.log(apiUrl);
apiUrl.search = 'tickers=[\'msft\']';
console.log(apiUrl.href);
This does compile and run without throwing an error, but logs
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: null,
query: null,
pathname: null,
path: null,
href: null }
null
Which isn't really what I had hoped for.
It's a property of the module:
const URL = require('url').URL;
If you're using Node 6.x then you have to use URL.parse instead.

Grunt redirect rest call to file

I am using grunt connect server with all those livereload plugins. Developing process was very fast till I added some rest calls. I decided to make some example JSON files which ll be rest calls answers.
So I need to redirect every rest call to some static folder(important I ll put it in target folder) so it ll be outside the Angular folder.
So I need some plugin which transfer calls like:
http.get(localhost:port/x/y/name) to target/jsons_examples/x/y/name.json
http.get(localhost:port/z/name) to target/jsons_examples/z/name.json
grunt file:(1 aplication server, 1 mocking webservices)
grunt.initConfig({
connect: {
all: {
options: {
port: 10100,
hostname: "0.0.0.0",
livereload: true
}
},
webservices_mock: {
options: {
port: 8081,
hostname: "0.0.0.0",
middleware: function(connect, options, middlewares) {
middlewares.unshift(function(req, res, next) {
var pattern = new RegExp('\/rest\/[a-zA-Z0-9\/.]+', 'i'),
matches = req.url.match(pattern);
if (!matches) {
return next();
}
req.setEncoding('utf8');
res.writeHead(200, {"Content-Type": "application/json"});
res.write(grunt.file.read(req.url.replace("/rest", "json_contracts") + "/example.json"));
res.end();
});
return middlewares;
}
}
}
},
...
And now i need in web services mock configuration change the path from json_contracts to path outside angular folder smth like: ././././target/json_contracts
You can use middleware option to inject your own URL parser. See the comments to understand how it works:
grunt.initConfig({
connect: {
all: {
options:{
port: 8080,
base: dir_to_angular_main_folder
hostname: "localhost",
middleware: function(connect, options, middlewares) {
middlewares.unshift(function(req, res, next) {
// pattern is a RegExp which is going to find the redirected url
var pattern = new RegExp('^/x/y/([0-9A-Z]+)$', 'i'),
// matches is a result which is
// - undefined when no match found
// - an array with two values when found:
// 0: the full string
// 1: the string inside of the brackets (the file name)
matches = req.url.match(pattern);
// if your url does not match skip the bottom part
if (!matches) return next();
// this runs only if match is found, set up the redirect header
// up to you to decide whether it is 301 or 302
// I would keep it 302 for dev purposes (browsers won't cache it)
res.writeHead(302, {
Location: '/target/jsons_examples/x/y/' + matches[1] + '.json'
});
// send the response
res.end();
});
return middlewares;
}
}
}
}
});
I guess you will still need to change the pattern to the one you need (x / y / target don't sound as real names).
One can say you can do it easier without matching like this ([0-9A-Z]+) and using the matches here '/target/jsons_examples/x/y/' + matches[1] + '.json' and he will be right. It was made with a name only because it is more flexible, e.g. when you have a folder in between x and y etc. Anyway, as it was said before, you can also make it simpler and just use the following:
res.writeHead(302, {
Location: '/target/jsons_examples' + req.url + '.json'
});
I could not test it, maybe it gives you some errors, but still I hope this is good enough to give an idea what and how to do.
EDIT
Well, according to the fact that your JSON files are not visible from the webserver side (the root folder is out of scope) you can do some kind of url rewriting instead of redirect:
var fs = require('fs');
grunt.initConfig({
connect: {
all: {
options:{
port: 8080,
base: dir_to_angular_main_folder
hostname: "localhost",
middleware: function(connect, options, middlewares) {
middlewares.unshift(function(req, res, next) {
// pattern is a RegExp which is going to find the redirected url
var pattern = new RegExp('^/x/y/([0-9A-Z]+)$', 'i'),
// matches is a result which is
// - undefined when no match found
// - an array with two values when found:
// 0: the full string
// 1: the string inside of the brackets (the file name)
matches = req.url.match(pattern);
// if your url does not match skip the bottom part
if (!matches) return next();
// this runs only if match is found, set up the redirect header
// reads the file content and sends as a response
res.end(fs.readFileSync('/<some-absolute-path>/target/jsons_examples/x/y/' + matches[1] + '.json', 'utf8'));
});
return middlewares;
}
}
}
}
});
Note that you need to include the Nodejs standard fs module on the top of your Gruntfile to make it work. This is again just a prototype, change the paths according to your requirements. Maybe you would also need to write the mime-type as a header of your response, there are already many answers on how to do it in Node as well.

Categories