Dart Language: Get URI query parameters without server port - dart

The Dart documentation focuses on processing HTTP requests over a specific server port. So if the server is listening on port 4123, you should be fine by sending GET, POST or other requests to an URI like:
http://www.somedomain.com:4123/?q=something
However, query parameters sent to the server/domain without specifying the server port will not be handled, like:
http://www.somedomain.com/?q=something
So what should I do to handle query parameters sent to my server (address/domain) without specifying a server port?
EDIT 1:
Some possible solution would be to implement an "URI checker" at the main method and retrieve the query (if it's present), like so:
import 'dart:html';
void main() {
// Gets the URI in order to check it for any parameters.
var uri = Uri.parse(window.location.href);
// Check for the parameter presence in the URI.
if (uri.queryParameters["q"] != null) {
// Gets the parameter content and stores it.
var queryParamContent = uri.queryParameters["q"];
// Check if the parameter content is empty or not.
if (queryParamContent.isNotEmpty) {
// Do something with the query parameter.
} else {
// Warn the user about the empty query.
}
} else {
// There's nothing interesting to check in the URI.
}
}

If it doesn't work without a port create a bug report at http://dartbug.com/new.
As a workaround you can use port 80 which is the default value when no specific port is set.

Related

Access session value in gatling checks

I use gatling to send data to an ActiveMQ. The payload is generated in a separate method. The response should also be validated. However, how can I access the session data within the checks
check(bodyString.is()) or simpleCheck(...)? I have also thought about storing the current payload in a separate global variable, but I don't know if this is the right approach. My code's setup looks like this at the moment:
val scn = scenario("Example ActiveMQ Scenario")
.exec(jms("Test").requestReply
.queue(...)
.textMessage{ session => val message = createPayload(); session.set("payload", payload); message}
.check(simpleCheck{message => customCheck(message, ?????? )})) //access stored payload value, alternative: check(bodystring.is(?????)
def customCheck(m: Message, string: String) = {
// check logic goes here
}
Disclaimer: providing example in Java as you don't seem to be a Scala developper, so Java would be a better fit for you (supported since Gatling 3.7).
The way you want to do things can't possibly work.
.textMessage(session -> {
String message = createPayload();
session.set("payload", payload);
return message;
}
)
As explained in the documentation, Session is immutable, so in a function that's supposed to return the payload, you can't also return a new Session.
What you would have to do it first store the payload in the session, then fetch it:
.exec(session -> session.set("payload", createPayload()))
...
.textMessage("#{payload}")
Regarding writing your check, simpleCheck doesn't have access to the Session. You have to use check(bodyString.is()) and pass a function to is, again as explained in the documentation.

Does a service worker allow one to simply use long expiration headers on static assets?

Say I have a service worker that populates the cache with the following working code when its activated:
async function install() {
console.debug("SW: Installing ...");
const cache = await caches.open(CACHE_VERSION);
await cache.addAll(CACHE_ASSETS);
console.log("SW: Installed");
}
async function handleInstall(event) {
event.waitUntil(install());
}
self.addEventListener("install", handleInstall);
When performs cache.addAll(), will the browser use its own internal cache, or will it always download the content from the site? This is important, because it one creates a new service worker release, and there are new static assets, the old version maybe be cached by the service worker.
If not then I guess one still has to do named hashed/versioned static assets. Something I was hoping service workers would make none applicable.
cache.addAll()'s behavior is described in the service worker specification, but here's a more concise summary:
For each item in the parameter array, if it's a string and not a Request, construct a new Request using that string as input.
Perform fetch() on each request and get a response.
As long as the response has an ok status, call cache.put() to add the response to the cache, using the request as the key.
To answer your question, the most relevant step is 1., as that determines what kind of Request is passed to fetch(). If you just pass in a string, then there are a lot of defaults that will be used when implicitly constructing the Request. If you want more control over what's fetch()ed, then you should explicitly create a Request yourself and pass that to cache.addAll() instead of passing in strings.
For instance, this is how you'd explicitly set the cache mode on all the requests to 'reload', which always skip the browser's normal HTTP cache and go against the network for a response:
// Define your list of URLs somewhere...
const URLS = ['/one.css', '/two.js', '/three.js', '...'];
// Later...
const requests = URLS.map((url) => new Request(url, {cache: 'reload'}));
await cache.addAll(requests);

Change the browser URL bar text

I own a domain in a hosting provider (just the domain). This domain is pointing to another web address:
domain.com-->anotherdomain.dom/path
In another side, I have added my domain to my Cloudflare account, like this:
domain.com-->Cloudflare-->anotherdomain.dom/path
The issue is that after typing domain.dom, the URL text in the browser URL bar is anotherdomain.dom/path, and I need it to be domain.com.
Is it possible to have domain.com in the broswer URL bar? Do I have to write some code inside my .htaccess file or something inside anotherdomain.com? Do I have to do something inside Cloudflare (maybe with "workers")?
It sounds like currently, your domain domain.com is set up as a redirect. When a user visits domain.com in their browser, the server (Cloudflare) responds with a message saying: "Please go to anotherdomain.com/path instead." The browser then acts like the user actually typed anotherdomain.com/path in the address bar.
It sounds like what you want instead is for domain.com to be a proxy. When a request comes in for domain.com, you want Cloudflare to fetch the content from anotherdomain.com/path and then return that content in response to the original request.
In order to do this, you will need to use Workers. Cloudflare Workers allows you to write arbitrary JavaScript code to tell Cloudflare how to handle HTTP requests for your domain.
Here's a Worker script that implements the proxy behavior that you want:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
// Parse the original request URL.
let url = new URL(request.url);
// Change domain name.
url.host = "anotherdomain.org";
// Add path prefix.
url.pathname = "/path" + url.pathname;
// Create a new request with the new URL, but
// copying all other properties from the
// original request.
request = new Request(url, request);
// Send the new request.
let response = await fetch(request);
// Use the response to fulfill the original
// request.
return response;
}

jhipster with keycloak : error 401 not forwarded to login

I'm using Jhipster 4.13.3 with the Oauth2/OIDC option to generate a gateway connected keycloak.
When a service send a 401 status, redirection to /login doesn't executed.
An interceptor (auth-expired.interceptor.ts) is defined to handle the error, but it doesn't work correctly.
First question
In the if condition, error.json() doesn't contain path, so the condition is false and the redirection is never executed.
if (error.status === 401 && error.text() !== ''
&& error.json().path && !error.json().path.includes('/api/account')) {
const destination = this.stateStorageService.getDestinationState();
if (destination !== null) {
const to = destination.destination;
const toParams = destination.params;
if (to.name === 'accessdenied') {
this.stateStorageService.storePreviousState(to.name, toParams);
}
} else {
this.stateStorageService.storeUrl('/');
}
const loginService: LoginService = this.injector.get(LoginService);
loginService.login();
}
Somebody knows the correct condition ?
Second question
I disabled the check on "error.json().path...", the redirection is called but fails "often", it works sometimes, I didn't found a explanation. Even if I kill all sessions in the keycloak admin console, the browsers redirects to the home page, not the keycloak login form.
Does somebody have an explanation about this ?
Thanks,
Philippe
We kept getting HTTP 401 status code responses when the hostname stamped on the iss field of the bearer's/user's access token had a different case i.e. lowercase vs. uppercase than the hostname in the URL used to post an HTTP request to keycloak's token endpoint.
Any kind of hostname mismatch can cause 401 errors:
Short hostname alias vs. fully qualified hostname e.g. https://myhost:8080 vs. https://myhost.domain.com:8080
https://MYHOST:8080 vs. https://myhost:8080
https://Myhost:8080 vs. https://myhost:8080
etc.
This happened in a Microsoft Windows 10 version 1809 environment.

Grails controller service - src/groovy poll controller for property value

I'm basically trying to get the percentage of time a task is taking to display to the user on the screen in an overlay template.
I have a service that is calculating the process percentage:
def progressCalculation(requestsToSend, requestsSent, requestsFailed, progressPercentage) {
progressPercentage = 100 / requestsToSend * (requestsSent + requestsFailed)
progressPercentage = Math.round(progressPercentage * 1) / 1
MyController upCont = new MyController()
upCont.progress(progressReport.progressPercentage)
}
this continues to send progressReport.progressPercentage to the controller:
def progress(progressData) {
int statusToView = progressData
if (statusToView % 5==0) {
[statusToView: statusToView]
}
}
I have created a src/groovy file that is using websockets from here: https://github.com/vahidhedayati/grails-websocket-example/blob/master/README.md
My connection is working but I need to show the percentage on the view using the websocket which is working.
#OnMessage
public String handleMessage(String message) {
message = MyController.progressPercentage
String replyMessage = "echo "+message
return replyMessage
}
now what I'm trying to so here is return the progressPercentage value from the controller to the src/groovy file so that my view can continually updated with the latest property value whilst the task is completing.
MyController upCont = new MyController() seriously?
It is good idea to move the code that hosts and modifies progressPercentage variable to service layer and access it using service rather than controller.
myService.progressPercentage rather than MyController.progressPercentage
Also you must inject myService , not instantiate it as myService = new MyService(), services are singletons you can not instantiate them like this. They are managed by the spring container.
Actually if you do MyController upCont = new MyController()
and you try to access a property of upCont you will get this beautiful error message:
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
I put those instructions together so if I can help you in any way do let me know.
Websockets require as much frontend work as backend. so to get back the data via websockets you need to expand on the java script as well as expand on the backend websocket sending that information to the java script.
So if you had a button on the frontend gsp that rather than was a typical
You can take a look at some of my plugins that already do this. There is a ping/pong that happens discretely in https://github.com/vahidhedayati/jssh which if user defines within taglib the websocket connection triggers a pong that frontend javascript receives and sends ping - and they continue doing this..
Here is another example which is what you probably need to use:
This is the result back from websocket
https://github.com/vahidhedayati/grails-jenkins-plugin/blob/master/grails-app/views/jen/_process.gsp#L411
which when recieved updates this span or div id:
https://github.com/vahidhedayati/grails-jenkins-plugin/blob/master/grails-app/views/jen/_process.gsp#L213
so you need to get your websocket to send it back in some json format that your frontend javascript picks up the json request and if it is of a certain convention to look for a value and update a div on the frontend.
There is a good video I have done on wschat which shows you updating frontend using websocket client/server. it may help you understand it better
https://www.youtube.com/watch?v=xagMYM9n3l0 or https://www.youtube.com/watch?v=zAySkzNid3E
unsure which one it was in
E2A: it will need to be a service:
https://github.com/vahidhedayati/grails-wschat-plugin/blob/master/src/groovy/grails/plugin/wschat/WsChatEndpoint.groovy#L63 then the few lines ahead registers those services in the websocket endpoint. Now going back in the history of the code or if you follow onMessage to verifyAction - you will need to send something from frontend - or upon when a connection is made to then send a message to frontend https://github.com/vahidhedayati/grails-wschat-plugin/blob/75590bf10ea040c18548377dedc716fdab2aa820/src/groovy/grails/plugin/wschat/WsChatEndpoint.groovy#L148. You can use userSession to directly message the person making the socket connection. On webpage using javascript parse json and update div as mentioned above

Resources