HTTP-like treatment for custom URI scheme, possible? - apache

I defined a new URI scheme on my Windows system (following this thread: how do I create my own URL protocol? (e.g. so://...))
I want the custom URI protocol to act like HTTP within Chrome/Firefox...
That is, I want: myprotocol://localhost/test.html
to act exactly like:
http://localhost/test.html
Is it possible, or does the browser insist on valid URI schemes, even if they are fully defined in the registry?
(This pertains to a local server and is required for personal application testing; I realise custom URI's are a bad standard and should not be used in production)

It is certainly possible to link a custom scheme to the browser of your choice. The challenge is to get the browser to treat your scheme exactly like http:// as it cannot possibly know it has to speak HTTP to the target resource. However, this answer suggests using an <iframe/> is a viable workaround.

Related

Should an optional, statically-defined resource that is unimplemented be defined as 403 or 501 (or something else)?

I have a device for which I am implementing an HTTP API and defining it via OpenAPI 3.0.
The following paths are defined:
/scan/inventory/start
/scan/location/start
/scan/direction/start
This API is designed to run on various devices, but not all of them implement the location or direction feature, but all do implement the inventory feature. The available features can be queried by GETing the /scan path.
For a device that does not support location my team has been waffling on the error code to return if someone attempts to use it. We want to provide useful feedback when this happens, so 404 seems ruled out, especially since the path is documented in our API. After reading and re-reading RFC-7231 and various summaries of it, 501 or 403 seemed like good choices.
At first, "501 Not Implemented" seemed like a good choice, but the 5XX class of errors seems to suggest a more serious server error.
Since we want to provide feedback, "403 Forbidden" seems good and puts the onus on the client for accessing a bad path.
I'm sure part of the problem is that we're attempting to use a specification (HTTP) that was not necessarily designed for arbitrary APIs.
What would you suggest we do?
This is a pretty straightforward 404.
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
403 isn't right, since that indicates that the user isn't "authorized" to access that resource. It implies that the issue lies on the client side. But in this case there simply is no resource.
501 isn't right, since that "indicates that the server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource." In this case the server has no problem supporting the request, it's just that the resource doesn't exist.
Note that "server" refers to the web server. The issue isn't whether or not your application as a whole supports some bit of functionality, it's whether the web server is capable of handling the HTTP request it was sent. It's not appropriate to use HTTP status codes to indicate that kind of high-level application state.
Also note that the status code isn't just a private contract between your application and its users. All actors in the web stack—loggers, intermediate caches, browsers, etc.—might change their behavior depending on the status code. That's why it's important to reserve things like 5xx for actual server errors.
To summarize, since the resource at that URI doesn't exist, the best way to provide useful feedback is to return a 404. If you want to distinguish between features that are never supported and those that are simply unsupported for that device you should use a mechanism other than the status code. Fortunately you're off to a good start by listing the available features at /scan.

Standard header for public address with an API Gateway

Let's say you are using an API gateway like Apigee or Amazon API Gateway and your public address for your API is http://my.public.dns.com/path/v1/articles. This gets routed through your gateway to an internal host http://some.internal.host.com/v1/articles. Now if your internal API returns relative links to itself then when they get served to the client they will be incorrect as they are based on its path not the actual public path. I know I can resolve this by transforming the response using the tools available in the respective gateway.
The question I have is; is there a standard way for a gateway to communicate the public path to the downstream component? I was thinking there might be a similar HTTP header to X-Forwarded-For.
There is no standard similar header.
Note that I think you mean if the back-end returns absolute links. If the links were relative, they'd already be correct. Relative links use no leading / thus are "relative" to the current directory -- whatever it may be - and so any external prefix is retained by the browser and the links transparently remain valid. Relative links can also backtrack a directory level with a ../ path prefix for each level.
Note also that API Gateway doesn't require any path prefix if you're using a custom domain name for your API This necessarily limits you to deploying a single "stage," but that's a reasonable tradeoff for a more flexible path... so the easiest solution might be to use a path in your API matching those internal paths.

How to obtain HttpServletRequest in AppservPasswordLoginModule (SSL)

In a customized Login Module I've developed for my application server (GlassFish 3.1.2.2), I'm using the following syntax to obtain the HttpServletRequest:
PolicyContext.getContext(HttpServletRequest.class.getName())
And it works fine.
But now I'm configuring the server to use only HTTPS and the same instruction returns null.
I guess this is a security restriction, but I'm not sure what needs to be changed in order to solve this issue (server.policy?).
To put this under context, I need to record the IP address of all login attempts, valid and invalid, and getting the request in the module seemed the most obvious solution.
Can someone help me to figure out a solution?
I can't help you directly with your question, but you may want to note that PolicyContext is a JACC class. It's spec'ed to work inside JACC policy providers. You may want to look at an article I wrote that explains this more in depth.
There is thus no specific guarantee that obtaining the HttpServletRequest works from inside a GlassFish proprietary login module, although I indeed have seen people using this more often and it typically works. The fact that it does not work when you switch to https sounds more like a bug or oversight to me than any specific security restriction.
A workaround for you could be to rewrite your login module as a Java EE standard auth module using JASPIC. I've also written an article about that subject which you could use for reference. In JASPIC you explicitly have access to the HttpServletRequest.

Should website & API have a different hostnames?

The webapp I'm making is medium-sized, and it's going to be a single-page static JS+HTML app (made with Backbone, and served by nginx) which accesses an API, hosted on a proper webserver.
Should the API be under a different hostname, or same hostname but different path? What could be possible pros & cons of these options? Both options are feasible, thanks to nginx.
I would suggest using an intuitive separated environment. Splitting the access location like example.com and api.example.com allow the hostnames to describe the purpose of each environment. Separating these keeps things organised and clear while using the same hostname for each could cause confusion as to what kind of request is being done.
Using example.com/api is possible as well, but could lead to future issues where directories are used for other things as well. E.g., would example.com/newfeature have a directory like example.com/newfeature/api as well?
In the end, it's all a matter of personal preference though. Pick something that works in a clear way for your environment.
I think your question is somewhat irrelevant, as long as your code is flexible about the base url of the api. Make sure you can configure your code (both javascript and back-end) so that all api URLs are relative to some single configuration parameter and you will have flexibility to put your api service anywhere you want or need to put it.
I tend to think it might be a good idea to have everything on the same hostname, because the user might have disabled 3rd party cookies, and so the API server won't be able to recognize you after you close your browser. Before anyone tells me I should have the main website serve the cookies instead, let me tell you that I'd like the main website to be completely static HTML/JS files, and so they have no ability to serve httpOnly cookies, which is the kind of cookies I like.

Can you modify http request headers in a Safari extension?

I can do this in FF and IE, and I know it doesn't exist in Chrome yet. Anybody know if you can do this in a Safari plugin? I can't find anything that says one way or another in the documentation.
Edit (November 2021): as pointed out in the comments, ParosProxy seems to no longer exist (and was last released ~2006 from what I can see). There are more modern options for debugging on Mac (outside of browser plugins on non-Safari browsers) like Proxyman. Rather than adding another list of links that might expire, I'll instead advise people to search for "debugging proxy" on their platform of choice instead.
Original Answer (2012):
The Safari "Develop" menu in advanced preferences allows you to partially customize headers (like the user agent), but it is quite limited.
However, if a particular browser or app does not allow you to alter the headers, just take it out of the equation. You can use things like Fiddler or ParosProxy (and many others) to alter the requests regardless of the application sending the request.
They also have the advantage of allowing you to make sure that you are sending the same headers regardless of the application in question and (depending on your requirements) potentially work across multiple browsers and apps without modification.
Safari has added extension support but its APIs don't let you have granular level control over Request & Response as compared to Chrome/Firefox/Edge.
To have granular level control over your Request and Response, you need setup a system wide proxy instead.
Requestly Desktop App automatically does this for you and on top of that, you can do various types of modifications too like:
Modify Request/Response Headers
Redirect URLs
Modify Response
Delay Network request
Insert Custom Scripts
Change User-Agent
Here's an article about header modification using requestly
https://requestly.io/feature/modify-request-response-headers/
Disclaimer: I work at Requestly