Google Storage API 1.8.1 - Item getting issue - google-api

I am not able to get an item through Google Storage Service API:
Google.Apis.Storage.v1.StorageService service;
// ...
Google.Apis.Storage.v1.ObjectsResource.GetRequest request = service.Objects.Get(bucketName, uri);
request.Alt = StorageBaseServiceRequest<GCSObject>.AltEnum.Json;
Google.Apis.Storage.v1.Data resp = request.Execute();
I am getting GoogleApiException
"An Error occurred, but the error response could not be deserialized."
regardless of there specified item exist or not in the storage.
"request.ExecuteAsStream()" returns "Not Found" text only.
The same issue occurs when trying to set ObjectAccessControl through service.ObjectAccessControls.Insert() method.
Do you have any suggestions?
P.S. I am able to upload an item though without any problem.

Check if your URI/Object contains characters that need escaping like '/'.
It might lead (in .NET4) to response not found 404, meaning the object not found on Google cloud.
The google api for .net cannot serialize this error, so you get this useless message ("error response could not be deserialized").
To fix it, add to the web config:
<uri>
<schemeSettings>
<add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
I explained the scenario here: Slash, Google Cloud Storage & .NET4.

Related

WebRequest to Shoutcast throws "invalid or unrecognized response" exception

I'm trying to read metadata from shoutcast stream using ASP.net WebAPI, .net core 2.1. All I need is the headers and not the audio data.
I found out that Shoutcast servers 2+ give stats xml page, but for compatibility reasons, I need to work this out so I can support v1 too. The /7.html does not give the title and genre.
Following is piece of relevant code:
HttpWebRequest request = null;
HttpWebResponse response = null;
request = (HttpWebRequest)WebRequest.Create(server);
request.Headers.Clear();
request.Headers.Add("GET", "/ HTTP/1.0");
// needed to receive metadata information
request.Headers.Add("Icy-MetaData", "1");
request.UserAgent = "WinampMPEG/5.09";
response = (HttpWebResponse)request.GetResponse();
info.Title=response.Headers["icy-name"];
info.Genre=response.Headers["icy-genre"];
When I run this code on IIS Express, or publish and run on IIS, I get this error:
An unhandled exception occurred while processing the request.
HttpRequestException: The server returned an invalid or unrecognized response.
System.Net.Http.HttpConnection.ThrowInvalidHttpResponse()
WebException: The server returned an invalid or unrecognized response.
System.Net.HttpWebRequest.GetResponse()
I have tried WebClient and StreamReader as well but the issue seems to be consistent.
However I tried the same code in Console Application and it seems to work just fine.
How can I get this to work through a WebAPI on IIS?
I had same issue. I used HttpClient and PostAsync to fix the issue.
It is to note that I initially tried my code with dot net framework rather than dot net core and it was working fine, so I think HttpWebResponse is not compatible with dot net core in some cases.
Have a look on below links, if using HttpClient still does not fix your issue. I hope it helps.
https://github.com/dotnet/corefx/issues/14897
https://github.com/dotnet/corefx/issues/30040

Trying to stop Google Directory API push notifications with a client returns 404

Using the documentation at https://developers.google.com/admin-sdk/directory/v1/guides/push#creating-notification-channels I subscribed to a notification using something like:
service = build('admin', 'directory_v1', credentials=credentials)
watch_data = {
'id': str(uuid.uuid1()),
'type': 'web_hook',
'address': 'https://example.appspot.com/push/user',
'payload': True,
}
subscription = service.users().watch(domain=domain, event='update', body=watch_data).execute()
# 'subscription' is stored
I got a proper reply and everything seem fine to that point.
Until I try to stop the notification with the following code:
# 'subscription' is retrieved from the storage
service = build('admin', 'directory_v1', credentials=credentials)
stop_data = {
'id': subscription.id,
'resourceId': subscription.resource_id
}
request = service.channels().stop(body=stop_data)
request.execute()
This raises an 'HttpError' 404 exception:
Response: <HttpError 404 when requesting https://www.googleapis.com/admin/directory/v1/admin/directory_v1/channels/stop? returned "Not Found">
Interestingly, using the same parameters (known good 'id' and 'resourceId' from the same user), the API explorer gadget at https://developers.google.com/admin-sdk/directory/v1/reference/channels/stop fails in the same way.
I've also been unable to find this endpoint in the full blown API explorer.
I believe that the discovery somewhat misbehaves.
The URI built by the client is: 'https://www.googleapis.com/admin/directory/v1/admin/directory_v1/channels/stop'
whereas the documentation states it should be:
'https://www.googleapis.com/admin/directory/v1/channels/stop'.
Could this be a bug in the API?
I'll try to make a "manual" authenticated request ASAP to check this hypothesis.
Edit 2016-11-09:
Tried a manual request using the following code:
# 'subscription' is retrieved from the storage
stop_data = {
'id': subscription.id,
'resourceId': subscription.resource_id
}
http = httplib2.Http()
http = credentials.authorize(http)
url = 'https://www.googleapis.com/admin/directory/v1/channels/stop'
method = 'POST'
response, content = http.request(url, method, body=json.dumps(stop_data),
headers={'content-type': 'application/json'})
I still get a 404 as a result. So I guess that the problem is not the endpoint URI.
If someone from Google reads this, can you please look into it?
It's not super critical but I'd like to not have dangling notification subscriptions.
Edit 2 2016-11-09:
Thanks to #Mr.Rebot for pointing out the reports API bug report.
Upon closer inspection, the problem here is exactly the same.
Using the manual request code above but adjusting the URI with an underscore, I'm finally able to make a successful request (returns 204).
url = 'https://www.googleapis.com/admin/directory_v1/channels/stop'
So there's definitely a bug somewhere and the following documentation pages have the wrong endpoint URI:
https://developers.google.com/admin-sdk/directory/v1/guides/push#stopping-notifications
https://developers.google.com/admin-sdk/directory/v1/reference/channels/stop
Also found this related post: Google Admin SDK Channel Stop endpoint is broken in client libraries
To those that wonders in the Google Docs hell for the past two years, and counting.
The wrong/right URL is:
https://www.googleapis.com/admin/reports_v1/channels/stop
And the Scope to use this URL is:
https://www.googleapis.com/auth/admin.reports.audit.readonly
I hope this helps someone :)

%2F is not working for "/" but %3F is working for "?" in Web API uri

I am using custom function in Restful API to get the specific result.
to get the string with name "ABC?" i am sending below GET request URI
https://localhost:44372/route/V1/Values/ExistsValue(Name='ABC%3F')/
this is working fine. but to get the name as "ABC/" i am sending below GET request URI
https://localhost:44372/route/V1/Values/ExistsValue(Name='ABC%2F')/
but this doesn't work. it showing error like below
IIS 10.0 Detailed Error - 404.0 - Not Found
How to handle this?
Thanks in advance....

Error using Json-feed for login: ACS50011

I have an RP for which I've built a login page using the Json feed from ACS. The IP images are linked to the .LoginUrl attribute of the feed and when I click on one of the images it correctly jumps to that IP's page.
Entering my credentials, however, I'm redirected to a page on the appfabriclabs.com site with the following error:
HTTP Error Code: 400
Message: ACS50000: There was an error issuing a token.
ACS50011: The RP ReplyTo address is missing. Either the RP ReplyToAddresses
are not configured or an invalid wreply 'https://www.skillscore.it/' was received
in the sign-in request.
the RP is configured in the App Labs site with a returnUrl of:
https://www.skillscore.it/Home/FederationResult
and in looking at the wreply parameter in the feed, I see:
https%3a%2f%2fskillscore.accesscontrol.appfabriclabs.com%3a443%2fv2%2fwsfederation
According to some SO articles like [this one] the return url of the app should be a prefix of the wreply parameter - which is clearly not the case here.
so... what have I done wrong now?
e
p.s. one interesting bit of info: in the Application Integration page of ACS there is a link to the ACS-hosted login page. the link used there seems to differ from the one I'm given in the feed; in particular, the ACS-hosted page uses a wctx of:
pr%3dwsfederation%26rm%3dhttps%253a%252f%252fwww.skillscore.it%252f
whereas the feed gives me:
pr%3dwsfederation%26rm%3dhttps%253a%252f%252fwww.skillscore.it%252f%26ry%3dhttps%253a%252f%252fwww.skillscore.it%252f
so I don't know what that's worth but maybe it's a clue to what's wrong.
* update *
decoded, that last string is:
pr=wsfederation
&rm=https%3a%2f%2fwww.skillscore.it%2f
&ry=https%3a%2f%2fwww.skillscore.it%2f
which clearly shows the Json feed is providing an ry that is not present in the ACS-hosted page... meaning anything to anyone?
ok. my bad. apparently, when I was fetching the Json feed, the URL I used did not have the reply_to set correctly.

NETWORK_ERROR: XMLHttpRequest Exception 101

I am getting this Error
NETWORK_ERROR: XMLHttpRequest Exception 101
when trying to get XML content from one site.
Here is my code:
var xmlhttp;
if(window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
if (xmlhttp==null) {
alert ("Your browser does not support XMLHTTP!");
return;
}
xmlhttp.onReadyStateChange=function() {
if(xmlhttp.readyState==4) {
var value =xmlhttp.responseXML;
alert(value);
}
}
xmlhttp.open("GET",url,false);
xmlhttp.send();
//alert(xmlhttp.responseXML);
}
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
Does any one have a solution?
If the url you provide is located externally to your server, and the server has not allowed you to send requests, you have permission problems. You cannot access data from another server with a XMLHttpRequest, without the server explicitly allowing you to do so.
Update: Realizing this is now visible as an answer on Google, I tried to find some documentation on this error. That was surprisingly hard.
This article though, has some background info and steps to resolve. Specifically, it mentions this error here:
As long as the server is configured to allow requests from your web application's origin, XMLHttpRequest will work. Otherwise, an INVALID_ACCESS_ERR exception is thrown
An interpretation of INVALID_ACCESS_ERR seems to be what we're looking at here.
To solve this, the server that receives the request, must be configured to allow the origin. This is described in more details at Mozilla.
The restriction that you cannot access data from another server with a XMLHttpRequest can apply even if the url just implies a remote server.
So:
url = "http://www.myserver.com/webpage.html"
may fail,
but:
url = "/webpage.html"
succeed - even if the request is being made from www.myserver.com
Request aborted because it was cached or previously requested? It seems the XMLHttpRequest Exception 101 error can be thrown for several reasons. I've found that it occurs when I send an XMLHttpRequest with the same URL more than one time. (Changing the URL by appending a cache defeating nonsense string to the end of the URL allows the request to be repeated. -- I wasn't intending to repeat the request, but events in the program caused it to happen and resulted in this exception).
Not returning the correct responseText or responseXML in the event of a repeated request is a bug (probably webKit).
When this exception occurred, I did get an onload event with readyState==4 and the request object state=0 and responseText=="" and responseXML==null. This was a cross domain request, which the server permits.
This was on an Android 2.3.5 system which uses webKit/533.1
Anyone have documentation on what the exception is supposed to mean?
Something like this happened with me when I returned incorrect XML (I put an attribute in the root node). In case this helps anyone.
xmlhttp.open("GET",url, true);
set the async part to true
I found a very nice article with 2 diferent solutions.
The first one implementing jQuery and JSONP, explaining how simple it is.
The second approach, it's redirecting trough a PHP call. Very simple and very nice.
http://mayten.com.ar/blog/42-ajax-cross-domain
Another modern method of solving this problem is Cross Origin Ressource Sharing.
HTML5 offers this feature. You can "wrap" your XMLhttp request in this CORS_request and
if the target browser supports this feature, you can use it and wont have no problems.
EDIT:
Additionaly i have to add that there are many reasons which can cause this Issue.
Not only a Cross Domain Restriction but also simply wrong Settings in your WEB.CONFIG of your Webservice.
Example IIS(.NET):
To enable HTTP access from external sources ( in my case a compiled Phonegap app with CORS request ) you have to add this to your WEB.CONFIG
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Another scenario:
I got two webservices running... One on Port 80 and one on Port 90. This also gave me an XML HTTP Request Error. I even dont know why :). Nevertheless i think this can help many not well experienced readers.

Resources