I have a HTTP Basic server where i sometimes need a user to make a selection before logging in. I thought i'd do this by sending a HTTP response 401 with json contents in the HTTP body to provide the data the client needs to show to the user.
However, i cannot for the world understand how i get the response body content in the willSendRequestForAuthenticationChallenge method. Since i use Basic Auth and provide the usr/pwd directly as a http "Authorization" header, this method gets called whenever the user cannot login, or when he/she needs to make the selection i am talking about.
So... i have the NSURLAuthenticationChallenge, but i cannot see any way of reading the body from that object.
If anybody could help out i'd really appreciate it!
You cannot get the body data at that point in the request process, because the URL request potentially asks you to make a decision about whether to cancel and retry with authentication before it even downloads the body data. It's a timing issue.
What you can do is:
Allow the request to complete without a credential. This will cause the URL connection to download the response body (error message). Your support code can then recognize the 401 response, parse the body, and provide credentials in a retry.
Optionally wrap the above logic in a custom NSURLProtocol class so that it becomes transparent to the rest of your app
Alternatively:
Provide the additional data in a custom HTTP header. I think you can probably get an NSURLResponse object from the protection spaces's failureResponse method, and get the headers from there.
I'm not 100% certain that it is possible to get the header fields at that point, though. For sure, you can do it with an NSURLProtocol or with custom wrapper code as described earlier.
Related
I am using WebView2 and am looking to stop cookies from being stored when they are received in responses to third-party resource requests.
WebView2 exposes the CoreWebView2.WebResourceResponseReceived event which initially looked promising. However, the documentation states:
There is no guarantee about the order in which the WebView processes the response and the host app's handler runs. The app's handler will not block the WebView from processing the response.
Hence it is not possible to modify the response or delete the cookie in this event handler. I guess you could record the response and delete it 'later', but this seems like it could be awkward to do reliably.
Is there a way to block or reliably delete cookies received in a response when using WebView2?
There's currently no way to intercept and modify web responses.
I imagine as a workaround you might try like you suggest of running some code asynchronously later like during the corresponding NavigationCompleted event to remove the cookie using the CoreWebView2.CookieManager APIs.
Another work around might be to use the WebResourceRequested event to intercept requests, use the GetDeferral method on the eventargs to get a deferral while you perform the web request yourself in native code, receive the response in native code, modify the response as you like, and then provide that modified response back in the WebResourceRequested eventargs and complete the deferral. However this has the drawback that you would need to convert the WebView2s web resource request and response objects back and forth between the request and response objects of whichever HTTP stack you use.
Otherwise, you can file your feedback as a feature request on the WebView2 Feedback github project.
Is it possible to generate response headers and send them back to the client without the body?
send_headers
do stuff
render body
No, you cannot respond with headers to the client, perform an operation, and then respond with a body. (I'm not positive this is what you are asking)
If you want to respond to the client and then perform some operation, you could use a background processor, like Sidekiq, to perform the logic after responding to the user but you won't be able to respond again with a body.
To answer the question directly, the headers are a part of the response, so unless you were sending a HEAD request which would only return the headers, you're stuck waiting for the entire response to come back.
To answer the question of long timeouts, there is a common pattern used for dealing with long requests which involves connection polling and the 202 Accepted response code.
You should engineer an endpoint solution that sends a 202 Accepted response straight away and sets the processing chain in motion. With that, you can create a resource which can give a useful estimate of how long the request will take, and where the result will be, and send that in the body of the response.
Your ultimate goal should be to figure out why the request takes so long, but if it is ultimately designed to be a long and arduous response, either due to I/O or CPU time needed, or if it's a business requirement, then using 202 Accepted and setting up a form of connection polling would be your best option.
I'm using Ruby on Rails. Here is the requirement: the client (a native mobile app developed by me) will send a http post request to my Ruby code, my code will add some extra http headers (based on some business logic), then I need to "forward" or "redirect" this post request to another backend server (which has a REST service) and return its response back to the client.
I have been able to write a rack middleware to intercept the post request and add the extra headers. Originally I thought I could just use http redirect (status code: 307 for post request). But the problem is that the extra headers could NOT be submitted, which is the whole point of my code. So this isn't http redirect or forwarding per se, it's more like transforming a request.
I'm able to make a separate post request from my code using net http. This works. But I have to COPY data from the incoming request to my outgoing request (eg form data, http headers). This copying seems a bit tedious.
I would prefer some kind of simple "repackaging" (which is akin to http redirect or forwarding), that is I copy the whole incoming request to the outgoing request, slap on the extra headers and send it to the destination URL and be done with. I am not sure how to do this, and if doing it this way is even a good idea. For example, HTTP_USER_AGENT shows the OS, browser type of the client, when I'm making a new request, I probably don't need to send this on.
Alternatively, I can copy only the application specific data, because they're all the backend server (the destination of this "redirect") cares about. But I'm averse to hardcoding attributes in my code, causing close-coupling with the client (our native mobile app). Ideally I only copy application-specific data without hardcoding their attribute names. Is this possible? If so, how?
Any advice would be appreciated.
Thank you.
HTTP does not allow redirects for anything other than GET request.
(This is not technically correct but using HTTP 307 is kind of sketchy - see https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect)
If you need too send a POST request to another server for processing then using a proxy as you already seem to be doing is the correct solution.
Recreating the request in the proxy may seem tedious but it actually serves as a guarantee that you are calling the other servers "API" correctly.
While you can simply loop through the request headers:
uri = URI('http://www.example.com/todo.cgi')
req = Net::HTTP::Post.new(uri)
request.headers.each do |key, value|
req[key] = value
end
And pass the request form data:
req.set_form_data = request.request_parameters
You should ask yourself if it really is prudent to proxy everything.
See http://api.rubyonrails.org/classes/ActionDispatch/Request.html
Is it possible to send content body with get request in c# using HTTP 1.1(RFC 2616). I also Need How to implement this in c#. I am getting protocol violation exception:can't send content body with this verb type.
Not really, and it has nothing to do with C# or ASP.NET specifically.
Technically you may be able to include a request body in a GET request. If certain objects in .NET don't allow you, you can always craft such a request manually and work around those objects. However, that effort isn't going to get you very far, because GET requests aren't supposed to have request body content. So the server is most likely going to ignore it anyway, if it's not dropped by something in between.
The bottom line is, GET requests don't have a request body. Whatever you're trying to accomplish should be accomplished by some other means.
I got an eccentric problem. I am trying to automate visiting a web site by using WebRequest and WebClient. I have observed all the post request header key-value pairs and posted data string in Firebug(request Header and Post tab). Then I simulated such request with WebRequest and put all the header parameter and posted data there. However when I do GetResponse() from this request instance, I always got an error page back that says some sessionID is short of.
Actually I have taken care to put previously(first step to open the Logon page) responded session cookie in the Header's cookie field for the request. And I can get the correct response back by simulating requesting the logon page(the 1st page), but cannot get through this authentication page. My post data is like userid=John&password=123456789&domain=highmark.And the authentication page request that carried out by browser succeeds every time.
Am I missing something in the request that may not be shown by firebug.If yes, can you give me some recommendation for the tools that may examine the entire request sent by browser.
I have solved this issue. The problem is I set the httpWebRequest instance's AllowAutoRedirect=true. Thus the effect is when I got the first response from the server, the httpWebRequest would continually to make another request asking for a different url that is replied in the response header's Location field.
The defect of HttpWebRequest class is when it is getting redirected, it does not include the Set-Cookies(Response's Header Field)'s cookies in the next request header, thus the server would deny such page request and may redirect again to another different page.
And the httpWebRequest.GetResponse() method only return the last responsed page back under the setting AllowAutoRedirect=true. And I got the totally different response than I expected.
Also in this solving process, I need to thank to a distinguish Http Traffic examining tool:IEInspector Http Analyzer(http://www.ieinspector.com/httpanalyzer/). The great feature of this tool is it can examine not only the http traffic from browser but also what your process's httpWebRequest made. And also it can display in text format the raw stream of those request and response. Although it is a commercial software, you can try it for 15 days. I am quite happy with what it tells me(in well-formed details) and I like to buy it as well.