Java Servlet request.getRequestURL() logged abnormal string - networking

In one my servlet running in public domain, I got an abnormal string log from the request.getRequestURL() method. I keep logging the details and found an entry which is "http://answers.yahoo.com". Can some one help me in analyzing how this could have happened and also how to achieve it. Ideally the log should be the URL address in the browser using which a user or a device invokes the servlet.
For example if the registered name of the server mapped to the IP is http://www.alphabeta.com/x_serv?a=2, the logs should be alphabeta.com

What exactly do you want to log?
Use the method getServerName() from interface javax.servlet.ServletRequest if you only need a host name. It returns the host name of the server to which the request was sent.
Use in conjunction with getServerName() and the method getServletPath() if you want to get the URL without any parameters on which was caused by your servlet. The method getServletPath() from interface javax.servlet.http.HttpServletRequest returns the part of this request's URL that calls the servlet but does not include any extra path information or a query string.
And the following code fragment will determine your page's absolute URL:
String uri = request.getRequestURI();
if (request.getQueryString() != null) {
uri += '?' + request.getQueryString();
}
URL reconstructedUrl = new URL(request.getScheme(),
request.getServerName(),
request.getServerPort(),
uri);
logger.info("The full URL: " + reconstructedUrl.toString());
Where URL class is from the package java.net.

Related

Can I turn off ASP.NET MVC changing backslash in URL params to forward slash?

I have a WebAPI method to retrieve some user details based on an Windows Logon:
[Route("api/user/{username}/details")]
public IHttpActionResult(string username)
{
// ...
}
Suppose I am user arjan on the MYCORP domain, then some javascript on my webpage would issue a GET to http://myserver/api/user/MYCORP\arjan/details.
This route never gets correctly resolved, as IIS, ASP.NET or something will rewrite the \ to a / before routing.
I can see in Fiddler that the correct URL is requested, but errorpage returned from IIS, clearly states it didn't find http://myserver/api/user/MYCORP\arjan/details.
I'm using MVC 5/.NET 4.5/IIS 7.5/VS2015/Windows 7.
So: why is my webserver turning the request URI
http://myserver/api/user/MYCORP\arjan/details
Into
http://myserver/api/user/MYCORP/arjan/details
And how can I turn it off?
Percent-encoding the \ to %5C doesn't resolve the issue, the decoding seems to happen very early at the server.
Note that this is not a duplicate of Route parameter with slash "/" in URL, which asks about using / as a URL parameter. This question is about why IIS/ASP.NET changes \ to /.
One workaroud would be to change the route/method signature to
[Route("api/user/{domain}/{username}/details")]
public IHttpActionResult(string domain, string username)
{
// ...
}
as this would correctly handle the incomming request...

BufferedMediaTypeFormatter HttpContent does not contain all Headers sent in Request

Within my Owin Self hosted Web Api project I am trying to build a custom MediaTypeFormatter that inherits from BufferedMediaTypeFormatter.
But the problem is the HttpContent object passed into ReadFromStream(..) does not contain all the headers sent in the request.
How do you access ALL the headers that were sent in the request (I know this because I made the request), or access the original HttpRequestMessage in the ReadFromStream(..) method ?
This seams to be a major bug and I cannot think of any reason why all the Request headers are not provided.
Sounds like the ASP.NET Request object does not expose a property for the specific header field name you are looking for.
So it looks like first, you need the Request and to do that you might be able to override GetPerRequestFormatterInstance:
How do I retrieve the HTTP request method in an ASP.NET WebAPI MediaTypeFormatter?
Once you have the request object you can search for the specific header field name you are looking for like so:
IEnumerable<string> headerValues = request.Headers.GetValues("MyHeaderFieldName");
var id = headerValues.FirstOrDefault();
You can also get the raw request if needed:
Request.InputStream.Position = 0;
var input = new StreamReader(Request.InputStream).ReadToEnd();

Performing redirects in ServiceStack

I'm attempting to build a service in ServiceStack whose sole responsibility will be to interpret requests, and send a redirect response. Something like this:
[Route("/redirect/", "POST")
public class Redirect : IReturnVoid
{
public string Something { get; set; }
}
public class RedirectService : Service
{
public object Post(Redirect req)
{
// make some decisions about stuff
return new HttpResult(){ StatusCode = HttpStatusCode.Redirect, Headers = {{HttpHeaders.Location, "place"}}};
}
}
I did initial testing using fiddler, setting a content-type of application/json and creating an appropriate request body.This did exactly as expected: the service request gave a 302 response and redirected to the expected location.
I've also tested this by using a basic Html form post, with an action of http://myserviceuri/redirect/, which also works as expected and redirects appropriately.
However, i've hit an issue when attempting to use the SS c# client to call the same service. If I call the following code in an aspx code behind or an mvc controller
var client = new JsonServiceClient("uri);
client.post(new Redirect{Something = "something});
I get a 500 and the error message:
The remote certificate is invalid according to the validation procedure.
Which makes sense as it's a development server, with a self-cert. But I get the feeling that, as I can call the service successfully by other means, that this is a red herring.
Should I be using a different type of c# client to make the request, or setting any more custom headers, or something else? Am I fundamentally not understanding what i'm trying to do?
Please let me know if more info is needed. Thanks.
What's happening here is that the JsonServiceClient is happily following the redirect, doing more than what you've expected it to do.
I'll reference a related question and answer for posterity ( - hopefully you've resolved this issue a long time ago...).
POST to ServiceStack Service and retrieve Location Header
Essentially you'd use .net's WebRequest or the ServiceStack extensions mentioned in the answer to see the redirect and act as you see fit.

How to determine the server url and port in the Global.asax Application_Start event

Is there any way to determine the url on which a website is being hosted from the Global.asax's Application_Start event?
I'm trying to store the url so that my application can generate dynamic links that are emailed from a background process.
If I try to directly access the HttpApplication.Request object in this method, I get a runtime error:
System.Web.HttpException: Request is not available in this context
You may be able to get the url from the request with the following:
this.Context.Request.Url
From this you could determine the address including the port number for the application.
I ended up putting my code in the Global.asax's Application_BeginRequest event.
string url = this.Context.Request.Url.AbsoluteUri.Replace(this.Context.Request.Url.PathAndQuery, string.Empty) + this.Context.Request.ApplicationPath;
if (url[url.Length-1] != '/')
{
url = url + '/';
}

Get domain whatever local or webserver

I wrote an ASP.NET web application. My application created a request with returning URL other e-commerce server. I want to get this.
http://www.stackoverflow.com/question/ask --> http://www.stackoverflow.com
http://localhost/stackoverflow/question/ask --> http://localhost/stackoverflow
I used Request.Url.AbsoluteUri. But it's not OK for typing address by user.
How can this be done?
Look at the server variables collection. That is the source of this raw data that the HttpApplication gets from IIS.
I think the specific string you are looking for can be found with by "http://" + HttpContext.Current.Request.ServerVariables["SERVER_NAME"]
EDIT
Looking at your question again, this won't work for the "http://localhost/stackoverflow". This is because it doesn't follow the same convention. If you are using the convention that the public site is http://www.domainname.com/ and your development site is http://localhost/domainname, then you could write a function that gets the site name like
public static string GetDomainUrl(){
var servername = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
bool isLocalHost = serverName.ToLowerInvariant().Contains("localhost);
if(isLocalHost){
var domain = serverName.Split(new Char[]{'/'})[1];
return string.Format(#"http://localhost/{0}", domain);
}
return string.Format(#"http://{0}", serverName);
}
Note: I wrote this in the SO textbox, so check it.

Resources