コード例 #1
0
        public static async Task <PythonProcess> AttachAsync(Uri uri, bool warnAboutAuthenticationErrors, TextWriter debugLog, CancellationToken ct)
        {
            string debugOptions = "";

            if (uri.Query != null)
            {
                // It is possible to have more than one opt=... in the URI - the debug engine will always supply one based on
                // the options that it gets from VS, but the user can also explicitly specify it directly in the URI when doing
                // ptvsd attach (this is currently the only way to enable some flags when attaching, e.g. Django debugging).
                // ParseQueryString will automatically concat them all into a single value using commas.
                var queryParts = HttpUtility.ParseQueryString(uri.Query);
                debugOptions = queryParts[AD7Engine.DebugOptionsKey] ?? "";
            }

            var debugConn = await ConnectAsync(uri, warnAboutAuthenticationErrors, debugLog, ct);

            try
            {
                var response = await debugConn.SendRequestAsync(new LDP.RemoteDebuggerAttachRequest()
                {
                    debugOptions = debugOptions,
                });

                if (!response.accepted)
                {
                    throw new ConnectionException(ConnErrorMessages.RemoteAttachRejected);
                }

                var langVer = (PythonLanguageVersion)((response.pythonMajor << 8) | response.pythonMinor);
                if (!Enum.IsDefined(typeof(PythonLanguageVersion), langVer))
                {
                    langVer = PythonLanguageVersion.None;
                }

                PythonRemoteProcess process = new PythonRemoteProcess(response.processId, uri, langVer, debugLog);
                process.Connect(debugConn);
                debugConn = null;
                return(process);
            }
            catch (IOException ex)
            {
                throw new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
            }
            finally
            {
                if (debugConn != null)
                {
                    debugConn.Dispose();
                }
            }
        }
コード例 #2
0
        public static PythonProcess Attach(Uri uri, bool warnAboutAuthenticationErrors)
        {
            string debugOptions = "";

            if (uri.Query != null)
            {
                // It is possible to have more than one opt=... in the URI - the debug engine will always supply one based on
                // the options that it gets from VS, but the user can also explicitly specify it directly in the URI when doing
                // ptvsd attach (this is currently the only way to enable some flags when attaching, e.g. Django debugging).
                // ParseQueryString will automatically concat them all into a single value using commas.
                var queryParts = HttpUtility.ParseQueryString(uri.Query);
                debugOptions = queryParts[AD7Engine.DebugOptionsKey] ?? "";
            }

            var stream = Connect(uri, warnAboutAuthenticationErrors);

            try {
                stream.Write(AttachCommandBytes);
                stream.WriteString(debugOptions);

                string attachResp = stream.ReadAsciiString(Accepted.Length);
                if (attachResp != Accepted)
                {
                    throw new ConnectionException(ConnErrorMessages.RemoteAttachRejected);
                }

                int pid       = stream.ReadInt32();
                int langMajor = stream.ReadInt32();
                int langMinor = stream.ReadInt32();
                int langMicro = stream.ReadInt32();
                var langVer   = (PythonLanguageVersion)((langMajor << 8) | langMinor);
                if (!Enum.IsDefined(typeof(PythonLanguageVersion), langVer))
                {
                    langVer = PythonLanguageVersion.None;
                }

                var process = new PythonRemoteProcess(pid, uri, langVer);
                process.Connect(stream);
                stream = null;
                return(process);
            } catch (IOException ex) {
                throw new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
            } finally {
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }
コード例 #3
0
        public static PythonProcess Attach(Uri uri, bool warnAboutAuthenticationErrors)
        {
            var stream = Connect(uri, warnAboutAuthenticationErrors);

            try {
                stream.Write(AttachCommandBytes);

                string attachResp = stream.ReadAsciiString(Accepted.Length);
                if (attachResp != Accepted)
                {
                    throw new ConnectionException(ConnErrorMessages.RemoteAttachRejected);
                }

                int pid       = stream.ReadInt32();
                int langMajor = stream.ReadInt32();
                int langMinor = stream.ReadInt32();
                int langMicro = stream.ReadInt32();
                var langVer   = (PythonLanguageVersion)((langMajor << 8) | langMinor);
                if (!Enum.IsDefined(typeof(PythonLanguageVersion), langVer))
                {
                    langVer = PythonLanguageVersion.None;
                }

                var process = new PythonRemoteProcess(pid, uri, langVer);
                process.Connect(stream);
                stream = null;
                return(process);
            } catch (IOException ex) {
                throw new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
            } finally {
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }
コード例 #4
0
ファイル: PythonRemoteProcess.cs プロジェクト: omnimark/PTVS
        public static PythonProcess Attach(Uri uri, bool warnAboutAuthenticationErrors) {
            string debugOptions = "";
            if (uri.Query != null) {
                // It is possible to have more than one opt=... in the URI - the debug engine will always supply one based on
                // the options that it gets from VS, but the user can also explicitly specify it directly in the URI when doing
                // ptvsd attach (this is currently the only way to enable some flags when attaching, e.g. Django debugging).
                // ParseQueryString will automatically concat them all into a single value using commas.
                var queryParts = HttpUtility.ParseQueryString(uri.Query);
                debugOptions = queryParts[AD7Engine.DebugOptionsKey] ?? "";
            }

            var stream = Connect(uri, warnAboutAuthenticationErrors);
            try {
                stream.Write(AttachCommandBytes);
                stream.WriteString(debugOptions);

                string attachResp = stream.ReadAsciiString(Accepted.Length);
                if (attachResp != Accepted) {
                    throw new ConnectionException(ConnErrorMessages.RemoteAttachRejected);
                }

                int pid = stream.ReadInt32();
                int langMajor = stream.ReadInt32();
                int langMinor = stream.ReadInt32();
                int langMicro = stream.ReadInt32();
                var langVer = (PythonLanguageVersion)((langMajor << 8) | langMinor);
                if (!Enum.IsDefined(typeof(PythonLanguageVersion), langVer)) {
                    langVer = PythonLanguageVersion.None;
                }

                var process = new PythonRemoteProcess(pid, uri, langVer);
                process.Connect(stream);
                stream = null;
                return process;
            } catch (IOException ex) {
                throw new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
            } finally {
                if (stream != null) {
                    stream.Close();
                }
            }
        }
コード例 #5
0
        public static PythonRemoteDebugProcess Connect(PythonRemoteDebugPort port)
        {
            PythonRemoteDebugProcess process = null;

            // Connect to the remote debugging server and obtain process information. If any errors occur, display an error dialog, and keep
            // trying for as long as user clicks "Retry".
            while (true)
            {
                Stream stream = null;
                ConnectionException connEx = null;
                try {
                    // Process information is not sensitive, so ignore any SSL certificate errors, rather than bugging the user with warning dialogs.
                    stream = PythonRemoteProcess.Connect(port.Uri, false);
                } catch (ConnectionException ex) {
                    connEx = ex;
                }

                using (stream) {
                    if (stream != null)
                    {
                        try {
                            stream.Write(PythonRemoteProcess.InfoCommandBytes);
                            int    pid      = stream.ReadInt32();
                            string exe      = stream.ReadString();
                            string username = stream.ReadString();
                            string version  = stream.ReadString();
                            process = new PythonRemoteDebugProcess(port, pid, exe, username, version);
                            break;
                        } catch (IOException ex) {
                            connEx = new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
                        }
                    }

                    if (connEx != null)
                    {
                        string errText;
                        switch (connEx.Error)
                        {
                        case ConnErrorMessages.RemoteUnsupportedServer:
                            errText = string.Format("Remote server at {0} is not a Python Tools for Visual Studio remote debugging server, or its version is not supported.", port.Uri);
                            break;

                        case ConnErrorMessages.RemoteSecretMismatch:
                            errText = string.Format("Secret '{0}' did not match the server secret at {1}. Make sure that the secret is specified correctly in the Qualifier textbox, e.g. tcp://secret@localhost.",
                                                    port.Uri.UserInfo, new UriBuilder(port.Uri)
                            {
                                UserName = null, Password = null
                            }.Uri);
                            break;

                        case ConnErrorMessages.RemoteSslError:
                            // User has already got a warning dialog and clicked "Cancel" on that, so no further prompts are needed.
                            return(null);

                        default:
                        {
                            // Azure uses HTTP 503 (Service Unavailable) to indicate that websocket connections are not supported. Show a special error message for that.
                            var wsEx = connEx.InnerException as WebSocketException;
                            if (wsEx != null)
                            {
                                var webEx = wsEx.InnerException as WebException;
                                if (webEx != null)
                                {
                                    var httpResponse = webEx.Response as HttpWebResponse;
                                    if (httpResponse != null && httpResponse.StatusCode == HttpStatusCode.ServiceUnavailable)
                                    {
                                        errText = string.Format("Could not connect to remote Python process at {0}. Make sure that web sockets are enabled for the corresponding web site in Azure portal.", port.Uri);
                                        break;
                                    }
                                }
                            }

                            errText = string.Format("Could not connect to remote Python process at {0}. Make sure that the process is running, and has called ptvsd.enable_attach().", port.Uri);
                            for (var ex = connEx.InnerException; ex != null; ex = ex.InnerException)
                            {
                                if (ex.InnerException == null)
                                {
                                    errText += "\r\n\r\nAdditional information:\r\n" + ex.Message;
                                }
                            }
                            break;
                        }
                        }

                        DialogResult dlgRes = MessageBox.Show(errText, null, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                        if (dlgRes != DialogResult.Retry)
                        {
                            break;
                        }
                    }
                }
            }

            return(process);
        }
コード例 #6
0
        public static async Task <PythonRemoteDebugProcess> ConnectAsync(PythonRemoteDebugPort port, TextWriter debugLog, CancellationToken ct)
        {
            PythonRemoteDebugProcess process = null;

            // Connect to the remote debugging server and obtain process information. If any errors occur, display an error dialog, and keep
            // trying for as long as user clicks "Retry".
            while (true)
            {
                DebugConnection     debugConn = null;
                ConnectionException connEx    = null;
                try {
                    // Process information is not sensitive, so ignore any SSL certificate errors, rather than bugging the user with warning dialogs.
                    debugConn = await PythonRemoteProcess.ConnectAsync(port.Uri, false, debugLog, ct);
                } catch (ConnectionException ex) {
                    connEx = ex;
                }

                using (debugConn) {
                    if (debugConn != null)
                    {
                        try {
                            var response = await debugConn.SendRequestAsync(new LDP.RemoteDebuggerInfoRequest(), ct);

                            process = new PythonRemoteDebugProcess(port, response.processId, response.executable, response.user, response.pythonVersion);
                            break;
                        } catch (IOException ex) {
                            connEx = new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
                        } catch (FailedRequestException ex) {
                            connEx = new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
                        }
                    }

                    if (connEx != null)
                    {
                        string errText;
                        switch (connEx.Error)
                        {
                        case ConnErrorMessages.RemoteUnsupportedServer:
                            errText = Strings.RemoteUnsupportedServer_Host.FormatUI(port.Uri);
                            break;

                        case ConnErrorMessages.RemoteSecretMismatch:
                            errText = Strings.RemoteSecretMismatch_Host.FormatUI(new UriBuilder(port.Uri)
                            {
                                UserName = null, Password = null
                            }.Uri);
                            break;

                        case ConnErrorMessages.RemoteSslError:
                            // User has already got a warning dialog and clicked "Cancel" on that, so no further prompts are needed.
                            return(null);

                        default:
                        {
                            // Azure uses HTTP 503 (Service Unavailable) to indicate that websocket connections are not supported. Show a special error message for that.
                            var wsEx = connEx.InnerException as WebSocketException;
                            if (wsEx != null)
                            {
                                var webEx = wsEx.InnerException as WebException;
                                if (webEx != null)
                                {
                                    var httpResponse = webEx.Response as HttpWebResponse;
                                    if (httpResponse != null && httpResponse.StatusCode == HttpStatusCode.ServiceUnavailable)
                                    {
                                        errText = Strings.RemoteAzureServiceUnavailable_Host.FormatUI(port.Uri);
                                        break;
                                    }
                                }
                            }

                            errText = Strings.RemoteServiceUnavailable_Host.FormatUI(port.Uri);
                            for (var ex = connEx.InnerException; ex != null; ex = ex.InnerException)
                            {
                                if (ex.InnerException == null)
                                {
                                    errText += "\r\n\r\n{0}\r\n{1}".FormatUI(Strings.AdditionalInformation, ex.Message);
                                }
                            }
                            break;
                        }
                        }

                        DialogResult dlgRes = MessageBox.Show(errText, Strings.ProductTitle, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                        if (dlgRes != DialogResult.Retry)
                        {
                            break;
                        }
                    }
                }
            }

            return(process);
        }
コード例 #7
0
        public static PythonRemoteDebugProcess Connect(PythonRemoteDebugPort port)
        {
            PythonRemoteDebugProcess process = null;

            // Connect to the remote debugging server and obtain process information. If any errors occur, display an error dialog, and keep
            // trying for as long as user clicks "Retry".
            while (true)
            {
                Stream stream = null;
                ConnectionException connEx = null;
                try {
                    // Process information is not sensitive, so ignore any SSL certificate errors, rather than bugging the user with warning dialogs.
                    stream = PythonRemoteProcess.Connect(port.Uri, false);
                } catch (ConnectionException ex) {
                    connEx = ex;
                }

                using (stream) {
                    if (stream != null)
                    {
                        try {
                            stream.Write(PythonRemoteProcess.InfoCommandBytes);
                            int    pid      = stream.ReadInt32();
                            string exe      = stream.ReadString();
                            string username = stream.ReadString();
                            string version  = stream.ReadString();
                            process = new PythonRemoteDebugProcess(port, pid, exe, username, version);
                            break;
                        } catch (IOException ex) {
                            connEx = new ConnectionException(ConnErrorMessages.RemoteNetworkError, ex);
                        }
                    }

                    if (connEx != null)
                    {
                        string errText;
                        switch (connEx.Error)
                        {
                        case ConnErrorMessages.RemoteUnsupportedServer:
                            errText = Strings.RemoteUnsupportedServer_Host.FormatUI(port.Uri);
                            break;

                        case ConnErrorMessages.RemoteSecretMismatch:
                            errText = Strings.RemoteSecretMismatch_Host.FormatUI(new UriBuilder(port.Uri)
                            {
                                UserName = null, Password = null
                            }.Uri);
                            break;

                        case ConnErrorMessages.RemoteSslError:
                            // User has already got a warning dialog and clicked "Cancel" on that, so no further prompts are needed.
                            return(null);

                        default:
                        {
                            // Azure uses HTTP 503 (Service Unavailable) to indicate that websocket connections are not supported. Show a special error message for that.
                            var wsEx = connEx.InnerException as WebSocketException;
                            if (wsEx != null)
                            {
                                var webEx = wsEx.InnerException as WebException;
                                if (webEx != null)
                                {
                                    var httpResponse = webEx.Response as HttpWebResponse;
                                    if (httpResponse != null && httpResponse.StatusCode == HttpStatusCode.ServiceUnavailable)
                                    {
                                        errText = Strings.RemoteAzureServiceUnavailable_Host.FormatUI(port.Uri);
                                        break;
                                    }
                                }
                            }

                            errText = Strings.RemoteServiceUnavailable_Host.FormatUI(port.Uri);
                            for (var ex = connEx.InnerException; ex != null; ex = ex.InnerException)
                            {
                                if (ex.InnerException == null)
                                {
                                    errText += "\r\n\r\n{0}\r\n{1}".FormatUI(Strings.AdditionalInformation, ex.Message);
                                }
                            }
                            break;
                        }
                        }

                        DialogResult dlgRes = MessageBox.Show(errText, Strings.ProductTitle, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                        if (dlgRes != DialogResult.Retry)
                        {
                            break;
                        }
                    }
                }
            }

            return(process);
        }