Sample code for WebDAV PROPFIND - webdav

Is there any site or some one can provide me a sample PROFIND request please.
I tried the PROFIND code sample from MSDN but getting 400 Bad request.
Unable to understand why this is happening.
Previously posted the question at Getting 400 Bad request from WebDav Server
Any suggestions will be greatly helpfull.
Edit
#Julian,
Have updated my request body to the following:
strBody = "<?xml version='1.0' encoding='utf-8'?>"
+ "<propfind xmlns='DAV:'>"
+ "<allprop/>"
+ "</propfind>";
as explained at RFC 4918, Section 9.1
But I am still getting the 400 Bad request Error. M I missing any Headers . Please suggest I am setting the following Header Information:
System.Net.HttpWebRequest Request;
Request.Credentials = MyCredentialCache;
Request.Method = "PROPFIND";
bytes = Encoding.UTF8.GetBytes((string)strBody);
Request.ContentType = "text/xml";
Do I need to set or specify something additional. The full code is in my Previosu Question.
Thanks,
Subhen

Ok I was missing the Depth Header and for that reason the webserver was returning Method Not allowed error.
MSDN clearlystates that
A PROPFIND with depth value of "infinity" is not supported in the public store that is accessible to MAPI clients such as Microsoft Outlook.
And the Bad request 404 error was generated because I was not using proxy. So What I did I commented the line which was not using any proxy and added the Depth Header.
// Request.Proxy = GlobalProxySelection.GetEmptyWebProxy();
Request.Headers.Add("Depth", "1");

Related

CORS Error on Chrome

I don't see myself making a cross domain AJAX request. However, I am still getting a CROSS related error. This happens only on Chrome. Firefox and Safari work fine.
Error:
"Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
The setup is:
AngularJS SPA
Nginx to serve static web content and as reverse proxy to forward https AJAX request as http request to local jettty/spring application
Api exposed as part of spring application is protected using shiro library
General
Request URL:https://domainName.com/api/path
Request Method:OPTIONS
Status Code:401
Request Headers
:authority:domainName.com
:method:OPTIONS
:path:/api/path
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
access-control-request-headers:accept, authorization, content-type
access-control-request-method:POST
origin:https://www.domainName.com
Response Headers:
content-length:0
date:Tue, 12 Jul 2016
server:nginx
status:401
www-authenticate:BASIC realm="application"
Any idea for the CORS error?
This is basically due to a pre flight Op OPTIONS request that Chrome makes . It may be annoying at times . Better you use a library called Xdomain that is a CORS alternative. And it has Angular JS wrapper also . It is really an elegant solution for problems like this . Have a look https://github.com/jpillora/xdomain . Let me know if that helped you :) .
Finally, I got it fixed on the back-end side by providing the jetty server with a Cross Origin Filter configuration class. Some sample code below:
DispatcherServlet dS = new DispatcherServlet();
dS.setContextClass(AnnotationConfigWebApplicationContext.class);
dS.setContextConfigLocation(String.format("%s",ApplicationConfig.class.getCanonicalName()));
final ServletHolder servletHolder = new ServletHolder(dS);
final ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.addServlet(servletHolder, "/");
// cors
{
FilterHolder h = new FilterHolder(CrossOriginFilter.class);
h.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM,"https://*.domainName");
h.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM,"GET,POST,HEAD,OPTIONS");
h.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM,"*");
h.setInitParameter(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM,"300");
h.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM,"true");
h.setInitParameter(CrossOriginFilter.EXPOSED_HEADERS_PARAM,"");
h.setInitParameter(CrossOriginFilter.CHAIN_PREFLIGHT_PARAM,"false");
h.setInitParameter(CrossOriginFilter.ALLOWED_TIMING_ORIGINS_PARAM,"https://*.domainName");
context.addFilter(h,"/*",EnumSet.of(DispatcherType.REQUEST));
}

Google Fit Api 403 Error from remote client

I have a web app hosted on IIS 7 that is doing Http calls using the Google Fit API, I'm able to successfully send a POST and retrieve an access token, after which I do a GET for the following uri:
"https://www.googleapis.com/fitness/v1/users/me/dataSources/raw:com.google.weight:com.google.android.apps.fitness:user_input/datasets/00-1427209862000000000"
Here's how I build a request and look at the response:
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.ContentLength = 0;
request.Accept = "application/json";
request.Headers.Add("Authorization", "Bearer " + dict["access_token"]);
response = (HttpWebResponse)request.GetResponse();
respStream = response.GetResponseStream();
sResponse = new StreamReader(respStream).ReadToEnd();
respStream.Close();
Response.Write(sResponse);
When I run this app on a browser on the host server, I successfully get a json object (it isn't the json I expect, but that's another issue). However, when I try to access the site on a remote client, I get a 403 error pointing to when I try to retrieve the response. Any ideas?
It probably depends how you got the access_token value.
How long after retrieving the access token are you making this request? It's only valid for an hour, so you may need to fetch a new one using the refresh token.
There's some more resources on access/refresh tokens this question:
Google OAuth2 Refresh_token expires when Access_token does
Update: This turned out to be a permissions issue. I was trying to access a data source that I didn't have scopes for, the fact that it didn't return a 403 when accessing on the host threw me off the trail. Still strange that it didn't return a 403 (it just returned an empty json object) when requested on the host server though...if you see this and have an idea why, feel free to comment. I'm curious.

Return error/exception when requested web api formatter is missing

Using the following code in my web api initialization I have disabled XmlFormatter so that only json is supported:
config.Formatters.Remove(config.Formatters.XmlFormatter);
Now when a client is making a request using the Accept : application/xml header it will get back json instead of XML. I find this behavior wrong. If a client asks for XML and this is not supported then it should get an UnsupportedMediaType error.
Do you know how I can achieve this in global level in my application?
By default, if Web API cannot determine a formatter using Accept or Content-Type headers, it will fall back to the first formatter that can serialize your current DTO type - and out of the box, JSON formatter is configured to work with all types, so it will always be the "last resort" fallback.
You can disable that fallback by modifying the DefaultContentNegotiator.
var config = new HttpConfiguration();
var negotiator = new DefaultContentNegotiator(excludeMatchOnTypeOnly: true);
config.Services.Replace(typeof(IContentNegotiator), negotiator);
Once you set excludeMatchOnTypeOnly to true, Web API will start to issue a 406 response (Not Acceptable) to requests for which the formatter cannot be determined - such as the one in your example. This is in line with RFC 2616 which states:
HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable)
status codes for enabling agent-driven negotiation when the server is
unwilling or unable to provide a varying response using server-driven
negotiation.
You can find a sample VS solution here.

The remote server returned an error (400) Bad Request using webrequest

When I execute HttpWebRequest.GetResponse on URL, GetResponse returns "The remote server returned an error: (400) Bad Request." instead of response.
The strange thing is that when I run this url at the browser I get the right response.
doesn't webrequest need to return the same values as the browser?
the following code return bad request
// Create a request for the URL.
WebRequest request = WebRequest.Create(
"http://someUrl/api/v5/basicAuth");
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
reader.Close();
response.Close();
also tried using WebClient with same results.
any idea how to get the proper response same as the browser?
The title says you're getting a 400 bad request, but in your question you say 404 Not Found. Those are very different. For a 404, I'd be troubleshooting the URL itself and how the request is being routed, DNS, etc. if it's a 400, then I would use something like Fiddler to capture how my request looks when using a browser, then see what the request looks like when coming from the program and see what's different/missing. It could be that some HTTP headers are needed, such as the content-type, or handling of cookies, etc etc. But something like Fiddler could at least get you started.

AccessToken for Windows Push Notifications returns Bad Request 400

PLEASE HELP!! Can't figure out why this simple code given by MSDN doesn't work....
I am using the following code in GetAccessToken() as given in the this MSDN article to get the access token to be used in windows notifications, but it returns "Bad Request 400"
PACKAGE_SECURITY_IDENTIFIER, CLIENT_SECRET are the values obtained when the app was registered with the Windows Store Dashboard
string urlEncodedSid = HttpUtility.UrlEncode(PACKAGE_SECURITY_IDENTIFIER);
string urlEncodedSecret = HttpUtility.UrlEncode(CLIENT_SECRET);
string body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);
string response;
using (WebClient client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
response = client.UploadString("https://login.live.com/accesstoken.srf", body);
}
Any help would be highly appreciated.......
I suspect the problem has to do with either an incorrect package identifier, and / or incorrect client secret.
From the MSDN page Push notification service request and response headers:
RESPONSE DESCRIPTION
--------------- --------------------------
200 OK The request was successful.
400 Bad Request The authentication failed.
Update - I ran the code from the question, using FAKE credentials.
Here is the RAW HTTP request:
POST https://login.live.com/accesstoken.srf HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: login.live.com
Content-Length: 88
Expect: 100-continue
Connection: Keep-Alive
grant_type=client_credentials&client_id=test&client_secret=test&scope=notify.windows.com
Here is the server's RAW response:
HTTP/1.1 400 Bad Request
Cache-Control: no-store
Content-Length: 66
Content-Type: application/json
Server: Microsoft-IIS/7.5
X-WLID-Error: 0x80045A78
PPServer: PPV: 30 H: BAYIDSLGN2A055 V: 0
Date: Thu, 21 Mar 2013 12:34:19 GMT
Connection: close
{"error":"invalid_client","error_description":"Invalid client id"}
You will note that the response is a 400. There is also some json that indicates the type of error. In my case, the error is Invalid client id. You probably want to take a look at your response - it will give you an indication of what happened.
I used Fiddler to debug the request/ response.
I found the reason for the error response. In fact it is the wrong PACKAGE_SECURITY_IDENTIFIER and CLIENT_SECRET.
DO NOT type the values. Because associated ASCII values differ. Therefore it is always better to copy and paste directly.
You will probably will get the access token with the simple code snippet.
Cheers
If you're using the new HttpClient API and you're sure you've copied and pasted the SID/secret values correct, you might be experiencing this issue because of encoding, provided you're using the FormUrlEncodedContent class as the content of your POST operation.
Contrary to the examples in the MSDN documentation, you don't want to URL encode the SID and secret values before adding them to the KeyValuePair collection. This is because encoding is implied by the FormUrlEncodedContent class, though I'm not seeing any documentation for this behavior. Hopefully this saves someone some time because I've been wrestling with this all night...

Resources