Silverlight 4.0 - HttpWebRequest throwing ProtocolViolationException - silverlight

I am getting a "System.Net.ProtocolViolationException: Operation is not valid due to the current state of the object." error when trying to call
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.ContentType = "text/xml";
request.BeginGetRequestStream(RequestCompleted, request);

I suspect this may be because you are performing a BeginGetRequestStream on a request object for which you have specified the "GET" method.
When performing a "GET" the server will not be expecting an entity body in the request hence you should proceed straight to BeginGetResponse. Also specifying a ContentType on the request is not necessary, it specifies the type of content being sent in the entity body of the request but as stated a "GET" doesn't send any content it only gets content.

I disagree with AnthonyWJones answer. I find nothing in the HTTP spec that prohibits a "GET" request from containing a message body. I think this has unfortunately become the de facto understanding of how HTTP works since there is generally no need (or way) to include a message body. Having said that, he is correct as to the cause of this specific exception. However, I think the BCL should be changed to allow it.
If anyone can point it out I would be very interested to know where the spec precludes this:
HTTP RFC 2616

Related

How to get Content-Length from response headers in CN1?

I implemented this but the response headers don't include Content-Length, even though I make sure the server replies that bit specifically. I also verified the response outside CN1 and it includes Content-Length. The full list of headers captured in ReadHeaders is (as seen from Android): null,Alt-Svc,Cache-Control,Connection,Content-Type,Date,ETag,Server,Transfer-Encoding,Vary,X-Android-Received-Millis,X-Android-Response-Source,X-Android-Selected-Protocol,X-Android-Sent-Millis,X-Cloud-Trace-Context,X-Powered-By. Right now to estimate download sizes I (1) call endpoint to get total size (2) call endpoint to get actual download and use NetworkManager progress listener, but it would be nice to be able to track progress with only one request (by using Content-Length). The vanilla RequestBuilder doesn't expose response headers so a direct usage of ConnectionRequest with readHeaders is needed. But the Content-Length is missing from getHeaderFieldNames
Note:
The reason why this wasn't working is because by default Android/CN1 sends a request with the header Accept-Enconding:gzip. This returns a chunked response that doesn't include the length header. I can't guarantee that this behavior matches every server response, but it does in my case (Node.js + Express)
To force a server to return a non-chunked response, set the header to "compress", "identity", or "deflate"
Example:
Rest.post(url).header("Accept-Encoding", "compress").fetchAsJsonMap(resp -> {...

How can an HTTP 403 be returned from an apache web server input filter?

I have written an apache 2.x module that attempts to scan request bodies, and conditionally return 403 Forbidden if certain patterns match.
My first attempt used ap_hook_handler to intercept the request, scan it and then returned DECLINED to the real handler could take over (or 403 if conditions were met).
Problem with that approach is when I read the POST body of the request (using ap_get_client_block and friends), it apparently consumed body so that if the request was subsequently handled by mod_proxy, the body was gone.
I think the right way to scan the body would be to use an input filter, except an input filter can only return APR_SUCCESS or fail. Any return codes other than APR_SUCCESS get translated into HTTP 400 Bad Request.
I think maybe I can store a flag in the request notes if the input filter wants to fail the request, but I'm not sure which later hook to get that.
turned out to be pretty easy - just drop an error bucket into the brigade:
apr_bucket_brigade *brigade = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc);
apr_bucket *bucket = ap_bucket_error_create(403, NULL, f->r->pool,
f->r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
bucket = apr_bucket_eos_create(f->r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
ap_pass_brigade(f->next, brigade);

AppEngine Error Handling

All,
Is there a way to error out/exit execution out of a handler? For instance, if the incoming request doesn't contain the correct headers we want to send a 400 and exit/close the connection. However, whenever we use self.error(400) or self.response.set_status(400) any other code after it executes anyway So, for example:
class MyPastaHandler(webapp2.Handler):
def get():
if not self.request.headers.get('My-Custom-Header'):
self.error(400)
...
[more code]
self.response.out.write('{"success": "true"}')
When I submit a request w/o the said custom header, I get back a 400, but I also get the success json in the body of the response, which tells me that self.error(400) doesn't stop execution and neither does self.response.set_status(400).
So, the question is, is it possible to literally error out of a handler?
As it turns out, there is a simple way to exit after a 400 (or any custom error). As described by TheFluff in the AppEngine IRC channel, a simple, old-fashioned empty return after the self.error(400) will do the trick.
In webapp2 abort() is a shortcut to raise a HTTP exception: http://webapp-improved.appspot.com/guide/exceptions.html#abort

Retrieve Response Headers in Silverlight?

I'm issuing a HttpWebRequest in silverlight and attempting to read (amongst other things) the headers in the response. Unfortunately, while I can get the response object (HttpWebResponse) any attempt to access the Headers collection results in a "not implemented" exception. Any ideas of how to do this? I'm attempting to pull a large recordset from azure (~8k rows) and need to check the response header for the continuation token.
Thanks to #silverfighter, I have the answer. The trick was to tell SilverLight 3 to let the client (.NET) handle the call rather than the browser (the default). Once you do this, you have access to the response headers both via the WebClient and HttWebRequest approaches. More information here:
http://blogs.msdn.com/carlosfigueira/archive/2009/08/15/fault-support-in-silverlight-3.aspx
http://msdn.microsoft.com/en-us/library/dd470096(VS.95).aspx
http://blogs.msdn.com/silverlight_sdk/archive/2009/08/12/new-networking-stack-in-silverlight-3.aspx
The HttpWebRequest does not permit access to the response headers collection. Use the WebClient instead, which exposes a WebResponse.Headers property.
Unfortunately, while that property exists, it similarly returns a Not Implemented Exception.
I'm having a hard time believing that this is as difficult as it seems... I would imagine that many have the same requirement.
Response Headers are not supported in Browser Http Handling.
You must specify Client Http Handling before calling your HttpHandler:
bool httpResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(...);
The result headers will now be available on webClient object in the wc_OpenReadCompleted method.
Have a look at: http://msdn.microsoft.com/en-us/library/dd920295(v=vs.95).aspx

Specified method is not supported httpwebrequest - Silverlight

I am trying to use an HttpWebRequest object in Silverlight 2.0, to do a "POST".
Upon return from the BeginGetStream method I end up with the following error :
Message: "Specified method is not supported."
StackTrace: " at System.Net.BHWRAsyncResult.get_AsyncWaitHandle()"
Here's some sample code: Note I have used fiddler to see if anything is being sent across the wire and there is no network activity.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri("http://someurl"));
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.Accept = "text/plain, */*";
req.Headers["X-Requested-With"] = "XMLHttpRequest";
AsyncCallback callBack = new AsyncCallback(streamResponse);
req.BeginGetRequestStream(callBack, null);
Thanks,
Dave
I just found one solution for this problem. HTTP Client need to know Content-Length to fill the Content-Length HTTP header value. Client can'not start request before it length became known. When You get RequestStream WebRequest can'not know how much bytes you will send to server. You must Close stream to commit Content-Length and only after closing the RequestStream You can call BeginGetResponse. It is strange that this not done inside WebRequest.
Hope this helps,
Dmitry
I just ran into this a while ago. Off the top of my head:
1) clientaccesspolicy.xml / crossdomain.xml isn't around on the server you are calling. Like flash, silverlight won't talk to a domain that doesn't have one.
1.1) Does fiddler log 404 errors? If it doesn't, you won't see the failed attempts Silverlight is making trying to get those policy files.
2) Failing that, sending your custom header might be upsetting things.

Resources