On the server side when I received an http request, I am adding a new cookie like this:
HttpContext.Response.Cookies.Add(it);
If I immediately query the HttpContext.Request.Cookies for the name of the cookie I just added, I get it back, although I think I Shouldn't since I am not even done with my request handling, did not send the response to client yet.
Should the Request's and Response's cookie collections be different of each other? Just like http request/response cookie headers.
thanks
This is expected and well documented behavior. See HttpResponse.Cookies :
After you add a cookie by using the HttpResponse.Cookies collection, the cookie is immediately available in the HttpRequest.Cookies collection, even if the response has not been sent to the client.
Related
I have a solution with two ASP.NET Core MVC projects. One project (Client) is making a request to the other (Server) using HttpClient. When the action in Server receives the request, I want to get the URL of the thing that sent it. Every article I have read purports Request.Headers["Referer"] as the solution, but in my case Headers does not contain a "referer" key (or "referrer").
When receiving the request in Server, how should I find the URL of the Client that sent it?
That is how you you get the referring url for a request. But the referer isn't the thing that sent the request. The referer gets set in the headers by the browser when a person clicks on a link from one website to go to another website. When that request is made by the browser to the new website the request will typically have the Referer header which will contain the url of the prior website.
The receiving server can't get the url of the "client" making the request, remember a typical web browser client isn't at any url. All the receiving server can get is the IP address of the client typically.
Since you have control of the client software, if you wanted you could have the client put whatever info you want in the header of the request before it's sent to the server and the server could then get that info out of the header.
If you're using HttpClient, then it is up to the site making the request to add that header. It isn't added automatically in this case. So: change the code - or request that the code is changed - so as to add the header and value that you expect. If you are proxying through a request, you might get the value from the current request's Referer header, and add that.
Even in the general case of a browser making the request as part of a normal page cycle, you can't rely on it: the Referer header is often deliberately not sent; depending on the browser version, configuration, whether you're going between different domains, whether it is HTTPS or not, and rel markers on a <a href=... such as "noreferrer".
I've hit a strange bit of behaviour and I'm pretty sure is related to my code rather than the RTC instance I'm working with.
I've got a web request setup and configured:
var cookies = new CookieContainer();
var request = (HttpWebRequest)WebRequest.Create(getCreationFactoryUri);
var xmlString = getRDF.ToString();
request.CookieContainer = cookies;
request.Accept = "application/rdf+xml";
request.Method = "POST";
request.ContentType = "application/rdf+xml";
request.Headers.Add("OSLC-Core-Version", "2.0");
request.Timeout = 40000;
request.KeepAlive = true;
byte[] bytes = Encoding.ASCII.GetBytes(xmlString);
request.ContentLength = bytes.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(bytes, 0, bytes.Length);
dataStream.Close();
This is passed to another method wrote based on an RTC example using forms authentication for RTC.
Under the OSLC v2 spec, I'm using a creation factory URL to post to. I know the URL is fine because I've setup a call using RESTClient in Firefox. Added the headers that are needed (Content-Type: application/rdf+xml, Accept: application/rdf+xml, OSLC-Core-Version: 2.0) and used the generated XML that my code is trying to pass. My manual call works perfectly and the ticket is created.
In my logs I captured the response from RTC, which is a list of tickets rather than a response showing my ticket as being created. I can re-create this behavior by doing a GET on the creation factory URL I'm using to create an event ticket.
So although I know I'm sending a POST to the creation factory (I debugged to check that my web request method was 100% set to 'POST') RTC instead returns a list of tickets and I can only conclude somewhere my request is treated as a 'GET'.
As a test I changed my request to use PUT instead of POST. This isn't permitted for use on the creation factory URL and in testing it indeed throws an error. So I'm totally miffed as to why RTC isn't creating my ticket, but instead treating my request as a GET and returning a list of tickets.
Anyone have any ideas?
Thanks.
If the server using form authentication, as you state, then I expect what is happening is that the POST is resulting in an HTTP redirection to the authentication form. Even if your other code is handling that authentication (which it sounds like it is), the result of that authentication will be an HTTP redirection to the URL of the original request. However, that redirection is likely to result in a GET to that URL, not the original POST. (Also, I don't believe the redirection after authentication is 100% reliable, if your requests are multi-threaded).
The jazz.net information on form authentication says "After authentication succeeded, you always have to replay the original request at least once to get to the protected resource. More replays may be required if the first replay led to another set of redirections and the original request had a non-GET method."
So if your code received an authentication challenge, you will need to re-send the original POST.
I believe the reason why the RESTClient plug-in in your browser is working first time is that it is sending the cookies from your previous log-in to the RTC web UI in the browser. (I had this experience recently, and also found it very confusing).
Also, if you are not preserving cookies between requests to RTC in your client app, then you will meet an auth challenge for every request. If you preserve cookies between calls from your client app (how you do that will depend on your client library - I'm not familiar with the code in your examples) then my experience is that you won't receive an auth challenge for every request. (However, you still need to be able to handle an auth challenge on every request - including POSTs - otherwise it may fail intermittently if the session times out just before you send a POST).
I'm having a problem in my application, where the browser is sending me a: If-None-Match header, and my server is not being able to fetch it.
Here is my confirmation:
And in here you can see, that, in fact, the header is being sent on the request:
("Encabezados de solicitud" is "Request's Headers" in spanish)
Do you guys know what is probably the issue here? I'm out of ideas
Edit
I'm caching my OkNegotiatedContentResult in a MemoryCache in the server. The Http Cache is done afterwards, so it probably fetch the IHttpActionResult from the cache.
Therefore, the RequestMessage property is from the serialized IHttpActionResult.
Maybe, IfNoneMatch header is not serializable and therefore it was deserialized as null?.
Can this be confirmed?
Ok so, here was the deal.
As I said, I was caching the whole IHttpActionResult. This was WRONG. Because, that also meant I was caching the RequestMessage of that result.
Therefore, when I got the cached IHttpActionResult from the memory pool, I got the first IHttpActionResult with the first request that was cached.
That request may or may not have the IfNoneMatch header and is totally different from the browser's request I was inspecting, it was a past request.
I use both of these many times in my code and don't really know what the difference is , if a cookie is set shouldn't it be exactly the same in request and response? and is request going to the the most up to date , or response?
EDIT:
ok , I get the difference between a request and a response, but if I type
string a = HttpContext.Current.Request.Cookie["a"].Value;
it is most of the time the same as
string a = HttpContext.Current.Response.Cookie["a"].Value;
but I am wondering what is the difference between using the two.
As everyone says Request.Cookies are supposed to be cookies coming from client (browser) and Response.Cookies are cookies that will be send back to client (browser).
There is black magic well documented* code that copies values from Response cookies to Request.Cookies when you add cookies to Response. As result it looks like you have same cookies in both Request and Response. Note that these copied cookies did not come from the client... so beware of making wrong decisions.
Here is a link to discussion about the code: http://forums.asp.net/t/1279490.aspx. In particular, cookies added in the following way will show up in the Request.Cookies collection:
Response.Cookies.Add(HttpCookie("MyCookie", "MyValue"))
*The behavior of cookies getting copied from Response.Cookies is documented in the HttpResponse.Cookies article:
After you add a cookie by using the HttpResponse.Cookies collection, the cookie is immediately available in the HttpRequest.Cookies collection, even if the response has not been sent to the client.
The request cookie is what is send from the client to the server (thus what the browser provides). The response cookie are the cookies that you want to place in the browser. The next connection from the browser that accepted the cookie from the response object will provide the cookie in the request object.
The word Response is used in Asp.net to send data from the server to the client and the Request is used to get the data from the client ( in the form of cookies, query string ) etc.
Example:
Response.Write("will write the content on the form which will return to the client");
// Response.Cookies will send the cookie to the client browser.
Response.Cookies.Add(HttpCookie("MyCookie", "MyValue"))
//and Request.Cookies is used to get the cookie value which is already present in the clinet browswer
and as you mentioned
string a = HttpContext.Current.Request.Cookie["a"].Value;
// I think this will check the cookie which is present in the client browser [ If client has sent the cookie to the server ]
string a = HttpContext.Current.Response.Cookie["a"].Value;
// and this will see the only Response object. If the cookie present in the response object then it will return you otherwise not.
Depends on what context.
Request is the data that gets sent to the server with every http request. Response is the response after the request by the server to the client.
I set a cookie like this in one page:
Request.Cookies["lang"].Value = "en-US";
Request.Cookies["lang"].Expires = DateTime.Now.AddDays(50);
On another page I try and read the cookie:
string lang = Server.HtmlEncode(Request.Cookies["lang"].Value);
The cookie is not null but the value is an empty string. What am I doing wrong?
You should be using Response.Cookies to set the cookie, and Request.Cookies to read any cookies sent back from the client.
The code in your question is setting the cookie in the Request object, not the Response.
Are cookies enabled on the client? The fact that you set a cookie doesn't mean that the client supports them and will send them back.
Remember, you're dealing with two disconnected systems; your server doesn't keep state and you know little about the client.
If I remember correctly I think you should be using response instead of request as request is what is being sent to you. Response is when you want to set something back to the client browser.
EDIT: What you are doing is modifying the cookies in that particular request which would make sense why you are not seeing on subsequent pages. That is not saving them back to the client.