How to catch a slash-ending URL in spray-routing? - spray

Spray is kind of really easy, but I'm having problems getting to understand the routing. It's like a dog that sometimes fetches the bone, often times not. What am I missing?
Is there a way to see what routes Spray tries, and why it gives up on certain ones? That would essentially solve this. The logRequest I have below simply shows the request but doesn't tell me why a path failed to match it.
...
(get & logRequest("SAY AAA:")) {
path("results") {
complete("results")
} ~
path("results/") { // does not work
complete("results/")
} ~
complete("fallback")
}
Leads to:
"results/aaa" -> fallback
"results/" -> fallback
"results" -> results
How can I grab the "results/" case?
Slightly similar issues: 19556196
Addendum:
I got it to work with path("results" / ""). Why did the "results/" not work?

Okay, seems the right way to go is:
(pathPrefix("results") & pathEndOrSingleSlash) {
complete( "results[/]" )
}
This will match both results and results/ which is what I want.
Discussion on the background
pathEndOrSingleSlash doc with sample

Related

#FirestoreQuery Not returning list of documents in Collection

I'm using FirebaseFirestoreSwift and Swift5.5 on iOS15+
I have this query:
#FirestoreQuery(
collectionPath: "/Users/" + Auth.auth().currentUser!.uid + "/Pages/"
) var pages2: [PageItem]
And I'm trying to get the following:
The structure is: /Users/{userId}/Pages/{pageId}/{key/value pairs}
I even confirmed from Firestore that the path was matching with its own.
This is from the console: /Users/JuzWOzAf54a7oFlOlb09dhAuOjI3/Pages/LZQAmbb18tYtz8ypkd8p
and this is what my string concatenation produces: /Users/JuzWOzAf54a7oFlOlb09dhAuOjI3/Pages/
So I should be getting the Page LZQAmbb18tYtz8ypkd8p and 3 others in the response, but thus far it is empty. Am I checking too early?
I am printing it like so:
.onAppear {
print(pages2)
}
On a view in the same file.
I don't even think it's a problem with printing it too soon, since it's meant to update in real-time.
But just incase it never showed since it was onAppear,and could have been received after, I added the following:
List {
ForEach(pages2) { page2 in
Text(page2.name)
}
}
And still, it receives nothing.
Not really sure what I'm doing wrong, I've researched and all I can find is a few resources, but they all seem to be doing the same thing, however, mine is simply not working, or I might be confused.
Any help is greatly appreciated, thank you!
Edit
This is the official SDK file whose methods I'm using:
https://github.com/firebase/firebase-ios-sdk/blob/master/Firestore%2FSwift%2FSource%2FPropertyWrapper%2FFirestoreQuery.swift
I am doing exactly as they propose.

What is the best way to capture ambiguous segments of text?

What would be the best way to capture the inner text in the following case?
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >cdata_start %cdata_end ']]>';
The problem is, it seems like the cdata_end action fires several times due to the fact that inner_text could match ].
I found the solution. You need to handle non-determinism. It wasn't clear initially, but the correct solution is something like this:
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >text_begin %text_end ']]>' %cdata_end;
action text_begin {
text_begin_at = p;
}
action text_end {
text_end_at = p;
}
action cdata_end {
delegate.cdata(data.byteslice(text_begin_at, text_end_at-text_begin_at))
}
Essentially, you wait until you are sure you parsed a complete CDATA tag before firing the callback, using information you previously captured.
In addition, I found that some forms of non-determinism in Ragel need to be explicitly handled using priorities. While this seems a bit ugly, it is the only solution in some cases.
When dealing with a pattern such as (a+ >a_begin %a_end | b)* you will find that the events are called for every single a encountered, rather than at the longest sub-sequence. This ambiguity, in some cases, can be solved using the longest match kleene star **. What this does is it prefers to match the existing pattern rather than wrapping around.
What was surprising to me, is that this actually modifies the way events are called, too. As an example, this produces a machine which is unable to buffer more than one character at a time when invoking callbacks:
%%{
machine example;
action a_begin {}
action a_end {}
main := ('a'+ >a_begin %a_end | 'b')*;
}%%
Produces:
You'll notice that it calls a_begin and a_end every time.
In contrast, we can make the inner loop and event handling greedy:
%%{
machine example;
action a_begin {}
action a_end {}
main := ('a'+ >a_begin %a_end | 'b')**;
}%%
which produces:

firefox addon webrequest.addListener misbehaving

I want to examine http requests in an extension for firefox. To begin figuring out how to do what I want to do I figured I'd just log everything and see what comes up:
webRequest.onResponseStarted.addListener(
(stuff) => {console.log(stuff);},
{urls: [/^.*$/]}
);
The domain is insignificant, and I know the regex works, verified in the console. When running this code I get no logging. When I take out the filter parameter I get every request:
webRequest.onResponseStarted.addListener(
(stuff) => {console.log(stuff);}
);
Cool, I'm probably doing something wrong, but I can't see what.
Another approach is to manually filter on my own:
var webRequest = Components.utils.import("resource://gre/modules/WebRequest.jsm", {});
var makeRequest = function(type) {
webRequest[type].addListener(
(stuff) => {
console.log(!stuff.url.match(/google.com.*/));
if(!stuff.url.match(/google.com.*/))
return;
console.log(type);
console.log(stuff);
}
);
}
makeRequest("onBeforeRequest");
makeRequest("onBeforeSentHeaders");
makeRequest("onSendHeaders");
makeRequest("onHeadersReceived");
makeRequest("onResponseStarted");
makeRequest("onCompleted");
With the console.log above the if, I can see the regex returning true when I want it to and the code making it past the if. When I remove the console.log above the if the if no longer gets executed.
My question is then, how do I get the filtering parameter to work or if that is indeed broken, how can I get the code past the if to be executed? Obviously, this is a fire hose, and to begin searching for a solution I will need to reduce the data.
Thanks
urls must be a string or an array of match patterns. Regular expressions are not supported.
WebRequest.jsm uses resource://gre/modules/MatchPattern.jsm. Someone might get confused with the util/match-pattern add-on sdk api, which does support regular expressions.

How to fix JSLint insecure ^ error?

I have following function. What this does is filters character that is allowed in a subdomain. In JSLint I got following error. Is there any way I can do this without JSLint showing error. I know I can ignore error in JSLint settings but Is there any other way I can improve my code to not show JSLint error.
function filterSubDomain(value) {
return value.replace(/[^a-z0-9\-]/ig, '')
.replace(/^[\-]*/, '')
.replace(/[\-]*$/, '')
.toLowerCase();
}
I think this is easy enough -- just a quick head rethread. I'll repeat the comment from above quickly: JSLint wants you to say what you do want rather than what you don't, because saying what you don't want always leaves room for a superset of what you do want to sneak in. That is, JSLint's intention is to force you to code explicitly/precisely.
So instead of replace, you want to use match here. Here's one way, I believe (stealing from MDN's match code a little):
/*jslint sloppy:true, white:true, devel:true */
function filterSubDomain(value) {
var out = value,
re = /[a-z0-9\-]+/gi,
found;
found = value.match(re);
out = found.join("");
// There are better ways to `trim('-')`.
while (0 === out.indexOf("-")) {
out = out.substr(1);
}
while (out.length === out.lastIndexOf("-")+1) {
out = out.slice(0,out.length-1);
}
return out;
}
console.log(filterSubDomain('---For more inform--ation, - see Chapter 3.4.5.1---'));
// Formoreinform--ation-seeChapter3451
There are other ways to trim, but you get the point. No not's in JavaScript regular expressions with JSLint!

Using go-html-transform to preprocess HTML: Replace fails

Following on from this question on whitelisting HTML tags, I've been experimenting with Jeremy Wall's go-html-transform. In the hopes of improving searchable documentation I'm asking this here rather than pestering the author directly... hopefully this isn't too tool-specific for SO.
App Engine, latest SDK. Post.Body is a []byte. This works:
package posts
import (
// ...
"html/template"
"code.google.com/p/go-html-transform/html/transform"
"code.google.com/p/go-html-transform/h5"
)
// ...
// Pre-process post body, then return it to the template as HTML()
// to avoid html/template's escaping allowable tags
func (p *Post) BodyHTML() template.HTML {
doc, _ := transform.NewDoc(string(p.Body))
t := transform.NewTransform(doc)
// Add some text to the end of any <strong></strong> nodes.
t.Apply(transform.AppendChildren(h5.Text("<em>Foo</em>")), "strong")
return template.HTML(t.String())
}
Result:
<strong>Blarg.<em>Foo</em></strong>
However, if instead of AppendChildren() I use something like the following:
t.Apply(transform.Replace(h5.Text("<em>Foo</em>")), "strong")
I get an internal server error. Have I misunderstood the use of Replace()? The existing documentation suggests this sort of thing should be possible.
Running your transform code outside of App Engine, it panics and you can see a TODO in the source at that point. Then it's not too much harder to read the code and see that it's going to panic if given a root node.

Resources