How to do HttpWebRequests from a Windows Phone 7? - windows-phone-7

I've been looking for an answer to my problem for several days, but sadly had no luck. I hope you guys here can help me out.
So, what I want to do is just a simple call against the delicious.com API that returns me the recent bookmarks ("posts" in delicious terminology). Therefore you simply use the following URI and enter your credentials for logging in to delicious.com.
When I do this from a standard .NET4 Console Application with the magic of HttpWebRequest and setting the Credentials, it works as expected. Trying to do the same basic HttpWebRequest on the WP7 emulator leads to an WebException stating that "The remote server returned an error: NotFound.".
When diving deeper into this exception I can see that my Response has a StatusDescription of "Unauthorized". It seems like no authentication happend at all.
Next I tried - as I read that setting the Credentials sometiemes leads to problems - was to directly set the "Authorization" RequestHeader. Guess what, the result was the same.
I ended up with the following code and without ideas. I hope, somebody here is able to
help me out and point a way, how I can reach my bookmarks from my WP7.
public void RetrieveRecentBookmarks(string userName, string password)
{
HttpWebRequest request = HttpWebRequest.CreateHttp(requestString);
byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(userName + ":" + password)
string authInfo = Convert.ToBase64String(bytes);
request.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " + authInfo;
RequestState state = new RequestState(request);
IAsyncResult result = request.BeginGetResponse(GetResponseCallback, state);
}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
RequestState state = asynchronousResult.AsyncState as RequestState;
HttpWebRequest request = state.Request as HttpWebRequest;
// Here is where it breaks...
HttpWebResponse response = request.EndGetResponse(asynchronousResult) as HttpWebResponse;
}
Thanks in advance!

As I now know, my code is absolutely correct and working. What was not working was the Emulator communication, as already mentioned by Shawn Kendrot.
I set up a completely fresh Win7, installed the WP7.1 SDK (and 7.1.1 Update) and it works like expected. So it seems like something blocked my calls from the emulator. I've got no idea, what it was, but I must admit, I don't care too much as it is working now.
Thank you Shawn for pointing out that there are sometimes problems with the Emulator and the web, that kicked me into the right direction.

Related

google-drive-api method "drive.files.create" stopped working (V3 - 1.58.0.2859) and return nothing

We have a .Net app using Google Drive api to upload files to a g-drive. And it just stopped working days ago (Nov 29th). But we didn't remember doing anything changes during that time.
During the investigation, we could confirm the service account for calling the Google API are valid, since the same service account is also being used for calling other google APIs, and works fine. We also can confirm it's not a permission issue, since we even set the permission of the gdrive to allow "anyone" who has the link, to have edit permission, but the issue is still there.
Unfortunately, we cannot find any useful log, and the return message of the API call is NULL. No error code or error message returned.The only related info we saw is: on the chart of "Error by API method", it shows "drive.files.create" failed 100%.
One interesting thing is, if we disable the Google Drive API, then enable it again, it will work once, then will stop working again.
private string SaveFileToGoogleDrive(IFormFile file, string claimNumber)
{
try
{
var driveService = GetDriveServiceInstance();
var fileMetadata = new Google.Apis.Drive.v3.Data.File();
var mimeType = file.ContentType;
fileMetadata.Name = CreateFileName(file.FileName, claimNumber);
fileMetadata.MimeType = mimeType;
fileMetadata.Parents = new List { _googleSettings.GoogleDriveFolderId };
FilesResource.CreateMediaUpload request;
using (var stream = new MemoryStream())
{
file.CopyTo(stream);
request = driveService.Files.Create(fileMetadata, stream, mimeType);
request.Fields = "id";
request.Upload();
}
var googleFile = request.ResponseBody; \\The response body is always NULL, after the issue happened. :(
return googleFile.Id;
}
catch(Exception ex)
{
_logger.Error($"Google Drive exception {ex.Message} SACKTRACE: {(ex.StackTrace ?? "")} INNER EXCEPTION: {(ex.InnerException != null ? ex.InnerException.Message + "STACK TRACE:" + ex.InnerException.StackTrace ?? "" : "")}");
return string.Empty;
}
}
We found more details from the progress property in the response object, and saw the error message "The user's Drive storage quota has been exceeded.", but it does not make sense at all, since we are using "Enterprise edition" Google Workspace, which is supposed to have no limit. The service account and the key look good, GCP didn't complain at all. And that's the first thing we checked during troubleshooting.
Do you have any idea on what to do to solve the issue or what too look for when investigating this issue?
We found more details from the progress property in the response object, and saw the error message "The user's Drive storage quota has been exceeded.", but it's not make sense at all, since we are using "Enterprise editions" google workspace, which suppose has no limit. The service account and key look good, GCP didn't complain any thing. And that's the first thing we checked during troubleshooting. Anyway, the fix is: after create a new service account then use the new key of this new service account, the system back to work.

HttpClient->GetStringAsync() throws 0x000006F4 for https Uris

The code below works fine for me if I use an http URI, but fails for equivalent https alternative. It works fine when built and run on another machine or when I include it in another app.
GetStringAsync throws an exception: “Exception thrown at 0x770B5722 (KernelBase.dll) in .exe: 0x000006F4: A null reference pointer was passed to the stub. occurred”.
ThreadPool::RunAsync(ref new WorkItemHandler([this](IAsyncAction^ action)
{
HttpClient^ client = ref new HttpClient();
auto uri = ref new Uri(L"https://....");
auto t = create_task(client->GetStringAsync(uri));
t.then([](String^ response)
{
// response should be valid.
});
}));
Running netsh winsock reset to reset the network stack seems to fix the issue!
For me, network stack reset didn't help at all, even device reboot didn't help, but your own answer have pointed me in the right direction: it wasn't my code who suddendly went mad, it was Windows. So what actually helped in my case is starting app without debugger (that is, from Start menu) - after that app continues to work fine when started from Visual Studio. It have happened a few times now, and I can confirm that it always helps.

Gmail Gadget Error 406 being thrown on osapi.http.post

We have multiple marketplace Apps that use Gmail Contextual Gadgets. These have been running for years successfully.
We are now noticing the following intermittent error being thrown when calling out to an external web server using open social osapi.http.post
"{"id":"http.post","error":{"message":"Response not valid JSON","code":406}}"
We have checked and there is nothing wrong with our server. We can make the call directly to our server successfully without fail.
We can replicate the issue calling to multiple servers running different apps/gadgets. The only commonality appears to be the use of osapi.http.post.
Here is the post
osapi.http.post({
'body': postdata,
'href': serverUrl + 'iLinkStreamer.ashx?data=' + "" + setTimeStamp() + debugString,
'format': 'json',
'authz': 'signed',
'noCache': true
}).execute(displayStreamList);
which raises the 406 error as above
Has anybody else noticed this issue?? Not sure how we can address it?
I had the same issue for a while and finally found the problem. I was also invoking external resources using osapi.http.post. I read the new documentation and found that there is a new way to do the same.
Check this url for more details, but the idea is that now you'll need to use makeRequest API, it will look something like this:
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
gadgets.io.makeRequest("https://your.backend.com", on_response_function, params);
...
def on_response_function(response){ ... }
I hope this helps someone.
I'm not sure if I'm the only one, but I never received a notification message that the previous API will be deprecated. :(

Google Drive SDK 1.8.1 RedirectURL

Is there any way to provide RedirectURL then using GoogleWebAuthorizationBroker?
Here is the sample code in C#:
Task<UserCredential> credential = GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, scopes, GoogleDataStore.User, cancellationToken, dataStore);
Or we have to use different approach?
I have an "installed application" that runs on a user's desktop, not a website. By default, when I create an "installed application" project in the API console, the redirect URI seems to be set to local host by default.
What ends up happening is that after the authentication sequence the user gets redirected to localhost and receives a browser error. I would like to prevent this from happening by providing my own redirect URI: urn:ietf:wg:oauth:2.0:oob:auto
This seems to be possible using Python version of the Google Client API, but I find it difficult to find any reference to this with .NET.
Take a look in the implementation of PromptCodeReceiver, as you can see it contains the redirect uri.
You can implement your own ICodeReceiver with your prefer redirect uri, and call it from a WebBroker which should be similar to GoogleWebAuthorizationBroker.
I think it would be great to understand why can't you just use PrompotCodeReceiver or LocalServerCodeReceiver.
And be aware that we just released a new library last week, so you should update it to 1.9.0.
UPDATE (more details, Nov 25th 2014):
You can create your own ICodeReceiver. You will have to do the following:
* The code was never tested... sorry.
public class MyNewCodeReceiver : ICodeReceiver
{
public string RedirectUri
{
get { return YOU_REDIRECT_URI; }
}
public Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(
AuthorizationCodeRequestUrl url,
CancellationToken taskCancellationToken)
{
// YOUR CODE HERE FOR RECEIVING CODE FROM THE URL.
// TAKE A LOOK AT THE FOLLOWING:
// PromptCodeReceiver AND LocalServerCodeReceiver
// FOR EXAMPLES.
}
}
PromptCodeReceiver
and LocalServerCodeReceiver.
Then you will have to do the following
(instead of using the GoogleWebAuthorizationBroker.AuthorizeAsync method):
var initializer = new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets,
Scopes = scopes,
DataStore = new FileDataStore("Google.Apis.Auth");
};
await new AuthorizationCodeInstalledApp(
new GoogleAuthorizationCodeFlow(initializer),
new MyNewCodeReceiver())
.AuthorizeAsync(user, taskCancellationToken);
In addition:
I'll be happy to understand further why you need to set a different redirect uri, so we will be able to improve the library accordingly.
When I create an installed application the current PromptCodeReceiver and LocalServerCodeReceiver work for me, so I'm not sure what's the problem with your code.

Internet Explorer buggy when accessing a custom weblogic provider

I've created a custom Weblogic Security Authentication Provider on version 10.3 that includes a custom login module to validate users. As part of the provider, I've implemented the ServletAuthenticationFilter and added one filter. The filter acts as a common log on page for all the applications within the domain.
When we access any secured URLs by entering them in the address bar, this works fine in IE and Firefox. But when we bookmark the link in IE an odd thing happens. If I click the bookmark, you will see our log on page, then after you've successfully logged into the system the basic auth page will display, even though the user is already authenticated. This never happens in Firefox, only IE. It's also intermittent. 1 time out of 5 IE will correctly redirect and not show the basic auth window. Firefox and Opera will correctly redirect everytime. We've captured the response headers and compared the success and failures, they are identical.
final boolean isAuthenticated = authenticateUser(userName, password, req);
// Send user on to the original URL
if (isAuthenticated) {
res.sendRedirect(targetURL);
return;
}
As you can see, once the user is authenticated I do a redirect to the original URL. Is there a step I'm missing? The authenticateUser() method is taken verbatim from an example in Oracle's documents.
private boolean authenticateUser(final String userName, final String password, HttpServletRequest request) {
boolean results;
try {
ServletAuthentication.login(new CallbackHandler() {
#Override
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback nameCallback = (NameCallback) callback;
nameCallback.setName(userName);
}
if (callback instanceof PasswordCallback) {
PasswordCallback passwordCallback = (PasswordCallback) callback;
passwordCallback.setPassword(password.toCharArray());
}
}
}
}, request);
results = true;
} catch (LoginException e) {
results = false;
}
return results;
I am asking the question here because I don't know if the issue is with the Weblogic config or the code. If this question is more suited to ServerFault please let me know and I will post there.
It is odd that it works everytime in Firefox and Opera but not in Internet Explorer. I wish that not using Internet Explorer was an option but it is currently the company standard. Any help or direction would be appreciated. I have tested against IE 6 & 8 and deployed the custom provider on 3 different environments and I can still reproduce the bug.
We figured it out.
The fix was to disable auth cookies on the weblogic server. For some reason Internet Explorer would lose the cookie causing Weblogic to think the session was being hacked. That is what prompted the basic auth login.
We still don't know what was causing IE to lose the cookie but this provider is for an intranet so the fix won't harm our overall security.
I hope this helps someone else.

Resources