Exemple #1
0
        /*++

        Routine Description:

            Assembles the status line for an HTTP request
             specifically to a proxy...

        Arguments:

            headersSize - size of the Header string that we send after
                this request line

        Return Value:

            int - number of bytes written out

        --*/
        private int GenerateProxyRequestLine(int headersSize) {
            //
            // Handle Proxy Case, i.e. "GET http://hostname-outside-of-proxy.somedomain.edu:999"
            // consider handling other schemes
            //
            // Note that we will take the scheme off the URI, hence may issue other but http request
            // through the proxy on redirect. While this is not allowed by RFC,
            // this it used to work in IE and we have already tested permissions for that destination Uri.
            if ((object)_Uri.Scheme == (object)Uri.UriSchemeFtp) {
                // FTP
                return GenerateFtpProxyRequestLine(headersSize);
            }
            // HTTP
            int offset = 0;
            string scheme = _Uri.GetComponents(UriComponents.Scheme | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
            HostHeaderString host = new HostHeaderString(GetSafeHostAndPort(false, true));
            string path = _Uri.GetComponents(UriComponents.Path | UriComponents.Query, UriFormat.UriEscaped);

            int writeBufferLength = CurrentMethod.Name.Length +
                                    scheme.Length +
                                    host.ByteCount +
                                    path.Length +
                                    RequestLineConstantSize +
                                    headersSize;
            _WriteBuffer = new byte[writeBufferLength];

            offset = Encoding.ASCII.GetBytes(CurrentMethod.Name, 0, CurrentMethod.Name.Length, WriteBuffer, 0);
            WriteBuffer[offset++] = (byte)' ';
            offset += Encoding.ASCII.GetBytes(scheme, 0, scheme.Length, WriteBuffer, offset);
            host.Copy(WriteBuffer, offset);
            offset += host.ByteCount;
            offset += Encoding.ASCII.GetBytes(path, 0, path.Length, WriteBuffer, offset);
            WriteBuffer[offset++] = (byte)' ';
            return offset;
        }
Exemple #2
0
        private int GenerateFtpProxyRequestLine(int headersSize) {
            // Special handling for FTP via HTTP proxy
            int offset = 0;
            string scheme = _Uri.GetComponents(UriComponents.Scheme | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
            string userInfo = _Uri.GetComponents(UriComponents.UserInfo | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
            HostHeaderString host = new HostHeaderString(GetSafeHostAndPort(false, true));
            string path = _Uri.GetComponents(UriComponents.Path | UriComponents.Query, UriFormat.UriEscaped);

            if (userInfo == "") {
                // No userinfo so see if we can add from Credentials
                string username = null;
                string password = null;
                NetworkCredential networkCreds = Credentials.GetCredential(_Uri, "basic");
                if (networkCreds != null
                    && (object)networkCreds
                       != (object)FtpWebRequest.DefaultNetworkCredential)
                {
                    username = networkCreds.InternalGetDomainUserName();
                    password = networkCreds.InternalGetPassword();
                    password = (password == null) ? string.Empty : password;
                }
                if (username != null) {
                    // For FTP proxy we don't escape the username and password strings
                    // Since some servers don't seem to support it
                    // Only escape the absolute minimum that is required for
                    // a valid Uri which is (: \ / ? # %)
                    username = username.Replace(":",  "%3A");
                    password = password.Replace(":",  "%3A");
                    username = username.Replace("\\", "%5C");
                    password = password.Replace("\\", "%5C");
                    username = username.Replace("/",  "%2F");
                    password = password.Replace("/",  "%2F");
                    username = username.Replace("?",  "%3F");
                    password = password.Replace("?",  "%3F");
                    username = username.Replace("#",  "%23");
                    password = password.Replace("#",  "%23");
                    username = username.Replace("%",  "%25");
                    password = password.Replace("%",  "%25");
                    username = username.Replace("@",  "%40");
                    password = password.Replace("@",  "%40");

                    // build complete userinfo
                    userInfo = username + ":" + password + "@";
                }
            }

            // construct request line from components
            int writeBufferLength = CurrentMethod.Name.Length +
                                    scheme.Length +
                                    userInfo.Length +
                                    host.ByteCount +
                                    path.Length +
                                    RequestLineConstantSize +
                                    headersSize;
            _WriteBuffer = new byte[writeBufferLength];

            offset = Encoding.ASCII.GetBytes(CurrentMethod.Name, 0, CurrentMethod.Name.Length, WriteBuffer, 0);
            WriteBuffer[offset++] = (byte)' ';
            offset += Encoding.ASCII.GetBytes(scheme, 0, scheme.Length, WriteBuffer, offset);
            offset += Encoding.ASCII.GetBytes(userInfo, 0, userInfo.Length, WriteBuffer, offset);
            host.Copy(WriteBuffer, offset);
            offset += host.ByteCount;
            offset += Encoding.ASCII.GetBytes(path, 0, path.Length, WriteBuffer, offset);
            WriteBuffer[offset++] = (byte)' ';
            return offset;
        }
Exemple #3
0
        /*++

        Routine Description:

            Assembles the status line for an HTTP request
             specifically for CONNECT style verbs, that create a pipe

        Arguments:

            headersSize - size of the Header string that we send after
                this request line

        Return Value:

            int - number of bytes written out

        --*/
        private int GenerateConnectRequestLine(int headersSize) {
            int offset = 0;

            HostHeaderString host = new HostHeaderString(GetSafeHostAndPort(true, true));

            //
            // Handle Connect Case, i.e. "CONNECT hostname.domain.edu:999"
            //

            int writeBufferLength = CurrentMethod.Name.Length +
                                    host.ByteCount +
                                    RequestLineConstantSize +
                                    headersSize;
            _WriteBuffer = new byte[writeBufferLength];
            offset = Encoding.ASCII.GetBytes(CurrentMethod.Name, 0, CurrentMethod.Name.Length, WriteBuffer, 0);
            WriteBuffer[offset++] = (byte)' ';
            host.Copy(WriteBuffer, offset);
            offset += host.ByteCount;
            WriteBuffer[offset++] = (byte)' ';
            return offset;
        }