rest url - having '/' as a path VALUE - jersey

I think this is not possible, but I need confirmation before throwing it away...
I have a GET REST endpoint with this pattern
/networks/{networkId}/publishers/{publisherId}/ratings
the problem I am facing is, publisherId could have '/' in its id, like the id could be "opt/foo/bar" (we have not control over this id, it is given to us by our clients).
So
/networks/68/publishers/opt/foo/bar/ratings - obviously does not work, getting a url not fond error.
/networks/68/publishers/opt%2ffoo%2fbar/ratings - also does not work. same error.
I know passing it as a query param will work. But I want to know if there is a way to make it work having it as a path param?
Thanks!

URL encoding is the right way to go but it looks like your container is decoding the slash before Jersey receives it.
Assuming you are using Tomcat, you can attempt to persuade Tomcat to allow the encoding, try:
tomcat/bin/setenv.bat
set
CATALINA_OPTS="-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
I don't know if other containers have similar issues and settings.

I have not tried this, but theoretically this should work in Jersey:
#Path("/networks/{networkId}/publishers/")
#GET
public String get(#PathParam("networkId") String networkId, #Context UriInfo ui) {
java.util.List<PathSegment> segments = ui.getPathSegments();
// Last segment is "ratings", the rest is your publisherId.
}

Related

Insert into elasticsearch with an id that contains slashes

Hello I am trying to insert an object into elasticsearch using it's API, the problem is that the IDs of elements that I want to insert are like this : ee5z4d5/54zd15zd/5zd45
when I sent a post request to host/index/id with a body, I got an error because the request url is host/index/ee5z4d5/54zd15zd/5zd45
I am using spring boot with feign client to comminucate with elasticsearch, and my question is how I can solve this problem
You need to URL-encode your ID first, i.e. the URL must look like this
host/index/ee5z4d5%2F54zd15zd%2F5zd45
I don't know Feign but this issue might provide some insights on how to solve your issue.
Tldr;
This is not an Elastic issue but more a web issue.
What you need to do, is encode the special char in the url.
Look at the solution below to find out what it means.
Solution
POST /73690410/_doc/ee5z4d5%2F54zd15zd%2F5zd45
{
"data": "my id has some slash"
}

Ruby on Sinatra: Imitate a request based on a parameter

I am currently developing a Ruby API based on Sinatra. This API mostly receives GET requests from an existing social platform which supports external API integration.
The social platform fires off GET requests in the following format (only relevant parameters shown):
GET /{command}
Parameters: command and text
Where text is a string that the user has entered.
In my case, params[:text] is in fact a series of commands, delimited by a space. What I want to achieve is, for example: If params[:text]="corporate finance"
Then I want my API to interpret the request as a GET request to
/{command}/corporate/finance
instead of requesting /{command} with a string as a parameter containing the rest of the request.
Can this be achieved on my side? Nothing can be changed in terms of the initial request from the social platform.
EDIT: I think a better way of explaining what I am trying to achieve is the following:
GET /list?text=corporate finance
Should hit the same endpoint/route as
GET /list/corporate/finance
This must not affect the initial GET request from the social platform as it expects a response containing text to display to the user. Is there a neat, best practice way of doing this?
get "/" do {
text = params[:text].split.join "/"
redirect "#{params[:command]}/#{text}"
end
might do the trick. Didn't check though.
EDIT: ok, the before filter was stupid. Basically you could also route to "/" and then redirect. Or, even better:
get "/:command" do {
text = params[:text].split.join "/"
redirect "#{params[:command]}/#{text}"
}
There a many possible ways of achieving this. You should check the routes section of the sinatra docs (https://github.com/sinatra/sinatra)
The answer by three should do the trick, and to get around the fact that the filter will be invoked with every request, a conditional like this should do:
before do
if params[:text]
sub_commands = params[:text].split.join "/"
redirect "#{params[:command]}/#{sub_commands}"
end
end
I have tested it in a demo application and it seems to work fine.
The solution was to use the call! method.
I used a regular expression to intercept calls which match /something with no further parameters (i.e. /something/something else). I think this step can be done more elegantly.
From there, I split up my commands:
get %r{^\/\w+$} do
params[:text] ? sub_commands="/"+params[:text].split.join("/") : sub_commands=""
status, headers, body = call! env.merge("PATH_INFO" => "/#{params[:command]}#{sub_commands}")
[status, headers, body]
end
This achieves exactly what I needed, as it activates the correct endpoint, as if the URL was typed it the usual format i.e. /command/subcommand1/subcommand2 etc.
Sorry, I completely misunderstood your question, so I replace my answer with this:
require 'sinatra'
get '/list/?*' do
"yep"
end
like this, the following routes all lead to the same
You need to add a routine for each command or replace the command with a * and depend your output based on a case when.
The params entered by the user can be referred by the params hash.
http://localhost:4567/list
http://localhost:4567/list/corporate/finance
http://localhost:4567/list?text=corporate/finance

Pass encrypted email in url in nop commerece

I want to pass encrypted email in url,but its not working on server,
while it is working on localhost.
I check the encrypted email- It contains some specific character like + , =
all those url which contains + sign are not working on server. but it working on localhost.
for example-
url format - {controllername}/{methodname}/{encrypted email}/{bool}
working url-
www.test.com/home/index/IZoc1QJlukTro7XN4kTaRDoy7mPNS-14YjKeZsXeyt3XsL4tXbLUPQ==/false
not working url-
www.test.com/home/index/KV6UWqy5fN7FY+lZuMAQ5nvA0+X4f8sQyB0la+-bSawUPEY1TIHK-C2bUdZUBRA6/false
not working url gives error like
404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.
Thoughts ?
You should pass it as an url encoded query string parameter and not as part of the route:
http://www.test.com/home/index?email=IZoc1QJlukTro7XN4kTaRDoy7mPNS-14YjKeZsXeyt3XsL4tXbLUPQ%3D%3D%2Ffalse
If you want to pass some string as part of the route you should ensure that it doesn't contain dangerous characters which is your case. Scott Hanselman wrote a nice and detailed blog post on the difficulties that you might encounter if you attempt to pass such strings as part of the route here: http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx
I will quote his conclusion if you don't want to go through the entire post:
After ALL this effort to get crazy stuff in the Request Path, it's
worth mentioning that simply keeping the values as a part of the Query
String (remember WAY back at the beginning of this post?) is easier,
cleaner, more flexible, and more secure.

Need to `location.href` value in JSTL(or JSP)

All I need is just <script>location.href</script> value in JSTL(or JSP).
Just same as the web browswers display. But it's not that easy.
I'm using Tiles2 and request.getRequestURL() shows tiles base jsp location like /WEB-INF/tiles/base.jsp...
And I found <%=request.getAttribute("javax.servlet.forward.request_uri")%> shows what I want.
https://stackoverflow.com/a/11387378/411615
But still it's not enough. it's not showing protocol and domain.
And I searched again.
http://${pageContext.request.localName}<%=request.getAttribute("javax.servlet.forward.request_uri")%>
It looks dirty and does not contain parameters. I would make it like this...
Map<String, String[]> parameters = request.getParameterMap();
for(String parameter : parameters.keySet()) {
...
}
But it's weird. In javascript it's so simple, but in JSP it's very tough.
Is there any neat way?
My environment isSpring 3.1, Tiles2.
The Request object is all you get on the server side. There's no way to know what was in the original href link because the browser sends the fully assembled URL to the server. Your options are 1) use some javascript trickery on the client side to send the original href as a parameter or header value, or 2) poke around in the Request object to get what you need. 2) is better.

Doing a URL rewrite in a ServletFilter using Jetty

I need to do a URL rewrite in a ServletFilter so that "foo.domain.com" gets rewritten to "foo.domain.com/foo". I'm using Jetty, which has a handy way of modifying requests: just cast the request to a Jetty Request object and you get a bunch of setters which allow you to modify it. Here's my code (which doesn't work):
String subdom = Util.getSubDomain(req);
org.eclipse.jetty.server.Request jettyReq = (Request) req;
String oldUri = jettyReq.getRequestURI();
String newUri = "/" + subdom + oldUri;
jettyReq.setRequestURI(newUri);
My purpose is to serve files out of the /foo directory, which lives at /webapps/root/foo.
I'm guessing that I also need to call things like setContextPath(), setPathInfo(), setURI(), setServletPath(), and who knows what else.
What's the magic combination that will make it look like the original request was for /foo?
Edit: to clarify, the reason I say the code doesn't work is that files are still being served out of /webapps/root, not /webapps/root/foo.
Just use the rewrite handler, we have support for what you're trying to do:
http://wiki.eclipse.org/Jetty/Feature/Rewrite_Handler
Answering my own question: I was missing
jettyReq.setServletPath(newUri);
Add that and everything works.

Resources