Beispiel #1
0
        protected virtual void OnAfterCompleted(ServiceOperationEventArgs e)
        {
            object request = null;

            lock (asyncRequests)
            {
                if (asyncRequests.ContainsKey(e.MsnServiceState))
                {
                    request = asyncRequests[e.MsnServiceState];
                    asyncRequests.Remove(e.MsnServiceState);
                }
            }

            if (e.MsnServiceState.AddToAsyncList)
            {
                lock (asyncStates)
                    asyncStates.Remove(e.MsnServiceState);
            }

            if (e.AsyncCompletedEventArgs.Cancelled)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                                  "Async method cancelled:\r\n" +
                                  "Service:         " + e.WebService.ToString() + "\r\n" +
                                  "MethodName:      " + e.MsnServiceState.MethodName + "\r\n" +
                                  "PartnerScenario: " + e.MsnServiceState.PartnerScenario);
            }
            else if (e.AsyncCompletedEventArgs.Error != null)
            {
                BeforeRunAsyncMethodEventArgs reinvokeArgs = null;
                if (e.AsyncCompletedEventArgs.Error is WebException)
                {
                    WebException    webException = e.AsyncCompletedEventArgs.Error as WebException;
                    HttpWebResponse webResponse  = webException.Response as HttpWebResponse;

                    if (webResponse != null && request != null)
                    {
                        if (webResponse.StatusCode == HttpStatusCode.MovedPermanently)
                        {
                            DeltasList deltas = NSMessageHandler.ContactService.Deltas;
                            if (deltas == null)
                            {
                                throw new MSNPSharpException("Deltas is null.");
                            }

                            string redirctURL       = webResponse.Headers[HttpResponseHeader.Location];
                            string preferredHostKey = e.WebService.ToString() + "." + e.MsnServiceState.MethodName;

                            lock (deltas.SyncObject)
                            {
                                deltas.PreferredHosts[preferredHostKey] = FetchHost(redirctURL);
                                deltas.Save();
                            }

                            e.WebService.Url = redirctURL;

                            reinvokeArgs = new BeforeRunAsyncMethodEventArgs(e.WebService, e.ServiceType, e.MsnServiceState, request);
                        }
                    }
                }

                if (reinvokeArgs == null)
                {
                    OnServiceOperationFailed(this, new ServiceOperationFailedEventArgs(e.MsnServiceState.MethodName, e.AsyncCompletedEventArgs.Error));
                }
                else
                {
                    RunAsyncMethod(reinvokeArgs);
                }
            }
            else
            {
                // HandleServiceHeader
                if (NSMessageHandler.MSNTicket != MSNTicket.Empty &&
                    (e.ServiceType == MsnServiceType.AB || e.ServiceType == MsnServiceType.Sharing))
                {
                    HandleServiceHeader(e.WebService, e.ServiceType, e.MsnServiceState);
                }

                // Fire event
                if (AfterCompleted != null)
                {
                    AfterCompleted(this, e);
                }
            }
        }
Beispiel #2
0
        protected void ChangeCacheKeyAndPreferredHostForSpecifiedMethod(SoapHttpClientProtocol ws, MsnServiceType st, MsnServiceState ss, object request)
        {
            if (st == MsnServiceType.AB ||
                st == MsnServiceType.Sharing ||
                st == MsnServiceType.Storage)
            {
                DeltasList deltas = NSMessageHandler.ContactService.Deltas;
                if (deltas == null)
                {
                    throw new MSNPSharpException("Deltas is null.");
                }

                string       methodName       = ss.MethodName;
                string       preferredHostKey = ws.ToString() + "." + methodName;
                CacheKeyType keyType          = (st == MsnServiceType.Storage) ? CacheKeyType.StorageServiceCacheKey : CacheKeyType.OmegaContactServiceCacheKey;

                string originalUrl  = ws.Url;
                string originalHost = FetchHost(ws.Url);
                bool   needRequest  = false;

                lock (deltas.SyncObject)
                {
                    needRequest = (deltas.CacheKeys.ContainsKey(keyType) == false ||
                                   deltas.CacheKeys[keyType] == string.Empty ||
                                   (deltas.CacheKeys[keyType] != string.Empty &&
                                    (deltas.PreferredHosts.ContainsKey(preferredHostKey) == false ||
                                     deltas.PreferredHosts[preferredHostKey] == String.Empty)));
                }

                if (needRequest)
                {
                    try
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, ws.GetType().ToString() + " is requesting a cachekey and preferred host for calling " + methodName);

                        switch (keyType)
                        {
                        case CacheKeyType.OmegaContactServiceCacheKey:
                            ws.Url = ws.Url.Replace(originalHost, MSNService.ContactServiceRedirectionHost);
                            break;

                        case CacheKeyType.StorageServiceCacheKey:
                            ws.Url = ws.Url.Replace(originalHost, MSNService.StorageServiceRedirectionHost);
                            break;
                        }

                        ws.GetType().InvokeMember(methodName, System.Reflection.BindingFlags.InvokeMethod,
                                                  null, ws,
                                                  new object[] { request });
                    }
                    catch (Exception ex)
                    {
                        bool getHost = false;
                        if (ex.InnerException is WebException && ex.InnerException != null)
                        {
                            WebException    webException = ex.InnerException as WebException;
                            HttpWebResponse webResponse  = webException.Response as HttpWebResponse;

                            if (webResponse != null)
                            {
                                if (webResponse.StatusCode == HttpStatusCode.Moved ||
                                    webResponse.StatusCode == HttpStatusCode.MovedPermanently ||
                                    webResponse.StatusCode == HttpStatusCode.Redirect ||
                                    webResponse.StatusCode == HttpStatusCode.RedirectKeepVerb)
                                {
                                    string redirectUrl = webResponse.Headers[HttpResponseHeader.Location];

                                    if (!string.IsNullOrEmpty(redirectUrl))
                                    {
                                        getHost = true;

                                        lock (deltas.SyncObject)
                                            deltas.PreferredHosts[preferredHostKey] = FetchHost(redirectUrl);

                                        Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Get redirect URL by HTTP error succeed, method " + methodName + ":\r\n " +
                                                          "Original: " + FetchHost(ws.Url) + "\r\n " +
                                                          "Redirect: " + FetchHost(redirectUrl) + "\r\n");
                                    }

                                    #region Fetch CacheKey

                                    try
                                    {
                                        XmlDocument errdoc       = new XmlDocument();
                                        string      errorMessage = ex.InnerException.Message;
                                        string      xmlstr       = errorMessage.Substring(errorMessage.IndexOf("<?xml"));
                                        xmlstr = xmlstr.Substring(0, xmlstr.IndexOf("</soap:envelope>", StringComparison.InvariantCultureIgnoreCase) + "</soap:envelope>".Length);

                                        //I think the xml parser microsoft used internally is just a super parser, it can ignore everything.
                                        xmlstr = xmlstr.Replace("&amp;", "&");
                                        xmlstr = xmlstr.Replace("&", "&amp;");

                                        errdoc.LoadXml(xmlstr);

                                        XmlNodeList findnodelist = errdoc.GetElementsByTagName("CacheKey");
                                        if (findnodelist.Count > 0 && !String.IsNullOrEmpty(findnodelist[0].InnerText))
                                        {
                                            deltas.CacheKeys[keyType] = findnodelist[0].InnerText;
                                        }
                                    }
                                    catch (Exception exc)
                                    {
                                        Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                                          "An error occured while getting CacheKey:\r\n" +
                                                          "Service:    " + ws.GetType().ToString() + "\r\n" +
                                                          "MethodName: " + methodName + "\r\n" +
                                                          "Message:    " + exc.Message);
                                    }

                                    #endregion
                                }
                            }
                        }

                        if (!getHost)
                        {
                            Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                              "An error occured while getting CacheKey and Preferred host:\r\n" +
                                              "Service:    " + ws.GetType().ToString() + "\r\n" +
                                              "MethodName: " + methodName + "\r\n" +
                                              "Message:    " + ex.Message);

                            lock (deltas.SyncObject)
                                deltas.PreferredHosts[preferredHostKey] = originalHost; //If there's an error, we must set the host back to its original value.
                        }
                    }
                    deltas.Save();
                }

                lock (deltas.SyncObject)
                {
                    if (originalHost != null && originalHost != String.Empty)
                    {
                        if (deltas.PreferredHosts.ContainsKey(preferredHostKey))
                        {
                            ws.Url = originalUrl.Replace(originalHost, FetchHost(deltas.PreferredHosts[preferredHostKey]));
                        }
                        else
                        {
                            //This means the redirection URL returns respond content.
                            lock (deltas.SyncObject)
                            {
                                deltas.PreferredHosts[preferredHostKey] = ws.Url;
                                deltas.Save();
                            }

                            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "The redirect URL returns correct result, use " + ws.Url + " for " + preferredHostKey);
                        }
                    }

                    // Set cache key
                    if (st == MsnServiceType.AB)
                    {
                        ((ABServiceBinding)ws).ABApplicationHeaderValue.CacheKey = deltas.CacheKeys[keyType];
                    }
                    else if (st == MsnServiceType.Sharing)
                    {
                        ((SharingServiceBinding)ws).ABApplicationHeaderValue.CacheKey = deltas.CacheKeys[keyType];
                    }
                    else if (st == MsnServiceType.Storage)
                    {
                        ((StorageService)ws).AffinityCacheHeaderValue.CacheKey = deltas.CacheKeys[keyType];
                    }
                }
            }
        }