I have a requirement to handle an application that is POSTing XML to a server and port. Unfortunately it is not possible for me to specify a path from this application and no way for me to change it.
So in Wireshark I can see it POSTing to
http://10.0.126.11:8082 <--- note the lack of trailing slash
If I set a test POST as follows in wfetch, I can route it just fine in grails. The following is what shows in Wireshare:
http://10.0.126.11:8082/ <--- trailing slash
I have the grails setup to route setup for the root path "/" in the UrlMappings and have setup the grails.app.context = "/" in the Config.groovy. Note that things just go badly if these are set to empty string.
Is there a way to go a step above the root path and respond to anything on the server:port? Can Grails respond to a request without a path?
This is the situation I'm trying to handle when recreating with wfetch (note that there is no path):
Related
I am developing a Clojure/ClojureScript SPA based on http-kit, compojure and tiny bits of hiccup on backend and mainly reagent on frontend. Project is done with leiningen, based on hand-wrecked chestnut template.
When I tried to make more complex URLs than just "/" the following setup created a mess for me:
When producing the initial hiccup to serve HTML and adding includes for CSS and JS files I followed the examples and added them as relative urls like
(include-css "css/style.css")
;and
(include-js "js/compiled/out/goog/base.js")
(include-js "js/compiled/myproject.js")
(note absence of slash in the beginning)
In the chestnut template I got default :asset-path option for cljsbuild set to "js/compiled/out"
Of course, when I tried to add a route to the same page with the http://my-domain/something URL in addition to root http://my-domain/ and load it, the thing failed to get any of my assets (trying to fetch them under e.g. /something/js/compiled/myproject.js).
I was able to fix this issue for explicitly included assets by making those urls relative to root (prepending a slash to each of them). It left me with the same problem with the script tag with src="js/compiled/out/cljs_deps.js" injected by cljsbuild, but this one I fixed by making :asset-path relative to root as well.
It all seems to work properly now, but the fact that I had to make some head-scratching and a surprisingly large amount of googling to finally resolve this makes me feel this is not the default approach. Hence the questions:
Did I do the right thing by converting all asset urls to relative-to-root ones? (Keeping in mind that I'm working on an SPA)
If yes, why isn't this a default approach and why I keep seeing relative-to-current location URLs everywhere (including all the examples on the web as well as lein templates)?
Update:
The relevant part of my app's compojure routes looks like this:
(defroutes home-routes
(resources "/")
(GET "/" _
(friend/authenticated
(html-response
(app-page))))
(GET "/something*" _
(friend/authenticated
(html-response
(app-page)))))
We're trying to pull files and folders from the locker, but the command (/d2l/api/le/(D2LVERSION: version)/locker/myLocker/(string: path)) doesn't like spaces in the file or folder name. It returns either Bad Request or Invalid Token depending on how we attempt to handle the spaces on our end (i.e. string replace with %20).
How would we retrieve files/folders with spaces in the name?
I can think of some possible problems you're encountering.
When you provide the API path to your D2LUserContext object, you need to pass in only the API path, with internal spaces, not escaped characters. So, a proper route to a file named test file name might look like this:
/d2l/api/le/1.0/locker/myLocker/firstFolderBelowRoot/test file name
to create the authenticated URL for this, you'd invoke
yourD2LUserContext.createAuthenticatedUri('/d2l/api/le/1.0/locker/myLocker/firstFolderBelowRoot/test file name', 'GET')
That would fashion an authenticated URL you can use to fetch that file named test file name from your locker. To fetch its containing folder:
yourD2LUserContext.createAuthenticatedUri('/d2l/api/le/1.0/locker/myLocker/firstFolderBelowRoot/', 'GET')
Note that when you want to identify a folder in the locker, the path parameter must end with a trailing slash. (If you're trying to fetch a folder, and you don't have the trailing slash, that might be a source of your issue.)
Once you have that URL, you'll need to use some sort of HTTP library to actually make the call. Our internal PHP devs have recommended using HttpRequest rather than cURL with PHP. Most notably, the URL you should make the call with should preserve the space in the file or folder name in the path component of the URL.
When I test against a 9.4.1 instance using the Python client to do fetches/puts from the locker, or to generate URLs using the user context object and then feeding those URLs into a browser, things seem to work fine. Testing against a 10.0.0 test instance using the Python client also seems to be working.
I have a web application that can be accessed either directly as http://host.foo.loc:8080/foo/ or via a secure reverse proxy as http://www.company.com/apps/foo/
By default, Grails will generate relative URLs with relative paths, for example:
<g:form action="bar">
will produce:
<form action="/foo/bar" method="post" >
This will be OK locally but the reverse proxy will not accept http://www.company.com/foo/bar (it's missing /apps/)
If I do:
<g:form action="bar" base=".">
it's fine. But I don't really want to specify it on each and every tag that generates a link.
The best way to deal with this would be to get Grails to generate relative paths in its relative URLs. Alternatively, I could live with setting a global "baseUrl" to "." but I don't know how to do that either.
Any idea ?
[edit] In fact, setting the "base" to "." doesn't work. The first page "/foo/controller/action" will generate the link as "./controller/nextaction" which the browser will translate as "/foo/controller/controller/action" => 404. I guess this is why they're using absolute paths: they're not paths.
I've never been able to make this kind of scenario work, so I always keep the proxied and unproxied context paths the same, i.e. I would put the app at http://host.foo.loc:8080/apps/foo. You can have a multi-level context path like this in Tomcat by naming the WAR file apps#foo.war.
Add grails.app.context = "/foo/bar" to your Config.groovy.
I'm trying to create a very simple Hello, world program in RoR, but when I go to view the url http://localhost:3000/say/hello I'm getting the error message No route matches: "say/hello"
I started with: rails generate controller Say hello goodbye
which lists route get "say/hello"
Also: I'm having this problem which is probably related. When I go to write some basic html in one of the files that is clearly listed as existing I get this:
I write this:
~/work/demo$ /app/views/say/hello.html.erb
Get this error message in return:
bash: /app/views/say/hello.html.erb: No such file or directory
What's going on here? I'm getting these instructions straight from Agile Development with Rails and it's so simple.
With the details you've given I'm not sure why your route can't be found.
However, I believe the reason you're experiencing the no such file or directory error is because you're typing /app/views/say/hello.html.erb. Try removing the leading slash, so that it reads app/views/say/hello.html.erb. Bash appears to be parsing the former path as an absolute path, instead of a path relative to your current working directory.
What is this command?
~/work/demo$ /app/views/say/hello.html.erb
you should be using your web browser: http://localhost:3000/say/hello
This GSP:
<g:link controller="book" action="show" id="5">Example</g:link>
results in this HTML:
Example
This is relative to the HTTP host. If your site is running at http://localhost:8080 that's fine.
During development, an app will more commonly be running at http://localhost:8080/appName.
In such cases, the above link will not work - it will result in an absolute URL of http://localhost:8080/book/show/5 instead of the required http://localhost:8080/appName/book/show/5
What changes are required of the above GSP for the app name to be present in the resulting anchor's href?
The configuration setting grails.app.context should be equal to the context where you want your application deployed. If it's not set, as in the default configuration, it defaults to your application name, like http://localhost:8080/appName. If you want to deploy your app in the root context (e.g. http://locahost:8080/), add this to your Config.groovy:
grails.app.context = "/"
If the context is properly set, the URLs generated by g:link tags will include the context before the controller name.
I found that the meta tag is very useful for getting information in GSP files.
For example, if you want your application name, you can get it like this:
<g:meta name="app.name"/>
You can get any property in your application.properties file like that.
And if you, like me, need to concatenate it to another value, here is my example. Remember that any tag can be used as a method without the g: namespace. For example:
<g:set var="help" value="http://localhost:8080/${meta(name:"app.name")}/help" />
Grails documentation about this is a little poor, but it is here.
For me the single best reason to use <g:link> is that it adds the context if there is one, or omits it if you're running at http://localhost:8080 or in prod at http://mycoolsite.com - it's trivial to just concatenate the parts together yourself otherwise.
The same goes for using g:resource with css, javascript, etc. - it lets you have one GSP that works regardless of what the context is (e.g. 'appName'), since it's resolved at runtime.
I think that is what grails.serverURL is for. You defined this config variable in the Config.groovy, check the configuration documentation for Grails for more details.
Hope this helps!
createLink tag includes your appname / context parameter automatically in the link.
Here is reference doc for it.