Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / HTTP / HttpChannelHelper.cs / 1305376 / HttpChannelHelper.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: HttpChannelHelper.cs // // Summary: Implements helper methods for http client and server channels. // //========================================================================= using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Globalization; namespace System.Runtime.Remoting.Channels.Http { internal static class HttpChannelHelper { private const String _http = "http://"; #if !FEATURE_PAL private const String _https = "https://"; #endif private static char[] s_semicolonSeparator = new char[]{';'}; // Determine if the url starts with "http://" #if !FEATURE_PAL // or "https://" #endif internal static int StartsWithHttp(String url) { int urlLength = url.Length; if (StringHelper.StartsWithAsciiIgnoreCasePrefixLower(url, _http)) return _http.Length; #if !FEATURE_PAL else if (StringHelper.StartsWithAsciiIgnoreCasePrefixLower(url, _https)) return _https.Length; #endif else return -1; } // StartsWithHttp // Used by http channels to implement IChannel::Parse. // It returns the channel uri and places object uri into out parameter. internal static String ParseURL(String url, out String objectURI) { // Set the out parameters objectURI = null; int separator = StartsWithHttp(url); if (separator == -1) return null; // find next slash (after end of scheme) separator = url.IndexOf('/', separator); if (-1 == separator) { return url; // means that the url is just "tcp://foo:90" or something like that } // Extract the channel URI which is the prefix String channelURI = url.Substring(0, separator); // Extract the object URI which is the suffix (leave the slash) objectURI = url.Substring(separator); InternalRemotingServices.RemotingTrace("HTTPChannel.Parse URI in: " + url); InternalRemotingServices.RemotingTrace("HTTPChannel.Parse channelURI: " + channelURI); InternalRemotingServices.RemotingTrace("HTTPChannel.Parse objectURI: " + objectURI); return channelURI; } // ParseURL internal static String GetObjectUriFromRequestUri(String uri) { // We assume uri may be in one of the following forms // http://myhost.com/myobject.rem #if !FEATURE_PAL // https://myhost.com/myobject.rem #endif // /myobject.rem // /myobject // myobject.rem // In all cases, myobject is considered to be the object URI (.rem might be absent) int start, end; // range of characters to use int index; start = 0; end = uri.Length; // first see if uri starts with http:// #if !FEATURE_PAL // or https:// #endif // and remove up to next slash if it does start = StartsWithHttp(uri); if (start != -1) { // remove domain name as well index = uri.IndexOf('/', start); if (index != -1) start = index + 1; else start = end; // uri will end up being "" } else { // remove "/" if this is an absolute path start = 0; if (uri[start] == '/') start++; } // remove query string if present ('?' and everything past it) index = uri.IndexOf('?'); if (index != -1) end = index; if (start < end) return CoreChannel.RemoveApplicationNameFromUri(uri.Substring(start, end - start)); else return ""; } // GetObjectURIFromRequestURI internal static void ParseContentType(String contentType, out String value, out String charset) { charset = null; if (contentType == null) { value = null; return; } String[] parts = contentType.Split(s_semicolonSeparator); // the actual content-type value is always first value = parts[0]; // examine name value pairs and look for charset if (parts.Length > 0) { foreach (String part in parts) { int index = part.IndexOf('='); if (index != -1) { String key = part.Substring(0, index).Trim(); if (String.Compare(key, "charset", StringComparison.OrdinalIgnoreCase) == 0) { if ((index + 1) < part.Length) { // we had to make sure there is something after the // equals sign. charset = part.Substring(index + 1); } else { charset = null; } return; } } } // foreach } } // ParseContentType internal static String ReplaceChannelUriWithThisString(String url, String channelUri) { // NOTE: channelUri is assumed to be scheme://machinename:port // with NO trailing slash. String oldChannelUri; String objUri; oldChannelUri = HttpChannelHelper.ParseURL(url, out objUri); InternalRemotingServices.RemotingAssert(oldChannelUri != null, "http url expected."); InternalRemotingServices.RemotingAssert(objUri != null, "non-null objUri expected."); return channelUri + objUri; } // ReplaceChannelUriWithThisString // returns url with the machine name replaced with the ip address. internal static String ReplaceMachineNameWithThisString(String url, String newMachineName) { String objectUri; String channelUri = ParseURL(url, out objectUri); // find bounds of machine name int index = StartsWithHttp(url); if (index == -1) return url; int colonIndex = channelUri.IndexOf(':', index); if (colonIndex == -1) colonIndex = channelUri.Length; // machine name is between index and up to but not including colonIndex, // so we will replace those characters with the ip address. String newUrl = url.Substring(0, index) + newMachineName + url.Substring(colonIndex); return newUrl; } // ReplaceMachineNameWithIpAddress // Decodes a uri while it is in byte array form internal static void DecodeUriInPlace(byte[] uriBytes, out int length) { int percentsFound = 0; int count = uriBytes.Length; length = count; int co = 0; while (co < count) { if (uriBytes[co] == (byte)'%') { // determine location to write to (we skip 2 character for each percent) int writePos = co - (percentsFound * 2); // decode in place by collapsing bytes "%XY" (actual byte is 16*Dec(X) + Dec(Y)) uriBytes[writePos] = (byte) (16 * CharacterHexDigitToDecimal(uriBytes[co + 1]) + CharacterHexDigitToDecimal(uriBytes[co + 2])); percentsFound++; length -= 2; // we eliminated 2 characters from the length co += 3; } else { if (percentsFound != 0) { // we have to copy characters back into place since we will skip some characters // determine location to write to (we skip 2 character for each percent) int writePos = co - (percentsFound * 2); // copy character back into place uriBytes[writePos] = uriBytes[co]; } co++; } } } // DecodeUri // reading helper functions internal static int CharacterHexDigitToDecimal(byte b) { switch ((char)b) { case 'F': return 15; case 'E': return 14; case 'D': return 13; case 'C': return 12; case 'B': return 11; case 'A': return 10; default: return b - (byte)'0'; } } // CharacterHexDigitToDecimal internal static char DecimalToCharacterHexDigit(int i) { switch (i) { case 15: return 'F'; case 14: return 'E'; case 13: return 'D'; case 12: return 'C'; case 11: return 'B'; case 10: return 'A'; default: return (char)(i + (byte)'0'); } } // DecimalToCharacterHexDigit } // class HttpChannelHelper internal static class HttpEncodingHelper { internal static String EncodeUriAsXLinkHref(String uri) { if (uri == null) return null; // uses modified encoding rules from xlink href spec for encoding uri's. // http://www.w3.org/TR/2000/PR-xlink-20001220/#link-locators byte[] uriBytes = Encoding.UTF8.GetBytes(uri); StringBuilder sb = new StringBuilder(uri.Length); // iterate over uri bytes and build up an encoded string. foreach (byte b in uriBytes) { if (!EscapeInXLinkHref(b)) { sb.Append((char)b); } else { // the character needs to be encoded as %HH sb.Append('%'); sb.Append(HttpChannelHelper.DecimalToCharacterHexDigit(b >> 4)); sb.Append(HttpChannelHelper.DecimalToCharacterHexDigit(b & 0xF)); } } return sb.ToString(); } // EncodeUriAsXLinkHref internal static bool EscapeInXLinkHref(byte ch) { if ((ch <= 32) || // control characters and space (ch >= 128) || // non-ascii characters (ch == (byte)'<') || (ch == (byte)'>') || (ch == (byte)'"')) { return true; } return false; } // EscapeInXLinkHref internal static String DecodeUri(String uri) { byte[] uriBytes = Encoding.UTF8.GetBytes(uri); int length; HttpChannelHelper.DecodeUriInPlace(uriBytes, out length); String newUri = Encoding.UTF8.GetString(uriBytes, 0, length); return newUri; } // DecodeUri } // class HttpEncodingHelper } // namespace System.Runtime.Remoting.Channels.Http // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: HttpChannelHelper.cs // // Summary: Implements helper methods for http client and server channels. // //========================================================================= using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Globalization; namespace System.Runtime.Remoting.Channels.Http { internal static class HttpChannelHelper { private const String _http = "http://"; #if !FEATURE_PAL private const String _https = "https://"; #endif private static char[] s_semicolonSeparator = new char[]{';'}; // Determine if the url starts with "http://" #if !FEATURE_PAL // or "https://" #endif internal static int StartsWithHttp(String url) { int urlLength = url.Length; if (StringHelper.StartsWithAsciiIgnoreCasePrefixLower(url, _http)) return _http.Length; #if !FEATURE_PAL else if (StringHelper.StartsWithAsciiIgnoreCasePrefixLower(url, _https)) return _https.Length; #endif else return -1; } // StartsWithHttp // Used by http channels to implement IChannel::Parse. // It returns the channel uri and places object uri into out parameter. internal static String ParseURL(String url, out String objectURI) { // Set the out parameters objectURI = null; int separator = StartsWithHttp(url); if (separator == -1) return null; // find next slash (after end of scheme) separator = url.IndexOf('/', separator); if (-1 == separator) { return url; // means that the url is just "tcp://foo:90" or something like that } // Extract the channel URI which is the prefix String channelURI = url.Substring(0, separator); // Extract the object URI which is the suffix (leave the slash) objectURI = url.Substring(separator); InternalRemotingServices.RemotingTrace("HTTPChannel.Parse URI in: " + url); InternalRemotingServices.RemotingTrace("HTTPChannel.Parse channelURI: " + channelURI); InternalRemotingServices.RemotingTrace("HTTPChannel.Parse objectURI: " + objectURI); return channelURI; } // ParseURL internal static String GetObjectUriFromRequestUri(String uri) { // We assume uri may be in one of the following forms // http://myhost.com/myobject.rem #if !FEATURE_PAL // https://myhost.com/myobject.rem #endif // /myobject.rem // /myobject // myobject.rem // In all cases, myobject is considered to be the object URI (.rem might be absent) int start, end; // range of characters to use int index; start = 0; end = uri.Length; // first see if uri starts with http:// #if !FEATURE_PAL // or https:// #endif // and remove up to next slash if it does start = StartsWithHttp(uri); if (start != -1) { // remove domain name as well index = uri.IndexOf('/', start); if (index != -1) start = index + 1; else start = end; // uri will end up being "" } else { // remove "/" if this is an absolute path start = 0; if (uri[start] == '/') start++; } // remove query string if present ('?' and everything past it) index = uri.IndexOf('?'); if (index != -1) end = index; if (start < end) return CoreChannel.RemoveApplicationNameFromUri(uri.Substring(start, end - start)); else return ""; } // GetObjectURIFromRequestURI internal static void ParseContentType(String contentType, out String value, out String charset) { charset = null; if (contentType == null) { value = null; return; } String[] parts = contentType.Split(s_semicolonSeparator); // the actual content-type value is always first value = parts[0]; // examine name value pairs and look for charset if (parts.Length > 0) { foreach (String part in parts) { int index = part.IndexOf('='); if (index != -1) { String key = part.Substring(0, index).Trim(); if (String.Compare(key, "charset", StringComparison.OrdinalIgnoreCase) == 0) { if ((index + 1) < part.Length) { // we had to make sure there is something after the // equals sign. charset = part.Substring(index + 1); } else { charset = null; } return; } } } // foreach } } // ParseContentType internal static String ReplaceChannelUriWithThisString(String url, String channelUri) { // NOTE: channelUri is assumed to be scheme://machinename:port // with NO trailing slash. String oldChannelUri; String objUri; oldChannelUri = HttpChannelHelper.ParseURL(url, out objUri); InternalRemotingServices.RemotingAssert(oldChannelUri != null, "http url expected."); InternalRemotingServices.RemotingAssert(objUri != null, "non-null objUri expected."); return channelUri + objUri; } // ReplaceChannelUriWithThisString // returns url with the machine name replaced with the ip address. internal static String ReplaceMachineNameWithThisString(String url, String newMachineName) { String objectUri; String channelUri = ParseURL(url, out objectUri); // find bounds of machine name int index = StartsWithHttp(url); if (index == -1) return url; int colonIndex = channelUri.IndexOf(':', index); if (colonIndex == -1) colonIndex = channelUri.Length; // machine name is between index and up to but not including colonIndex, // so we will replace those characters with the ip address. String newUrl = url.Substring(0, index) + newMachineName + url.Substring(colonIndex); return newUrl; } // ReplaceMachineNameWithIpAddress // Decodes a uri while it is in byte array form internal static void DecodeUriInPlace(byte[] uriBytes, out int length) { int percentsFound = 0; int count = uriBytes.Length; length = count; int co = 0; while (co < count) { if (uriBytes[co] == (byte)'%') { // determine location to write to (we skip 2 character for each percent) int writePos = co - (percentsFound * 2); // decode in place by collapsing bytes "%XY" (actual byte is 16*Dec(X) + Dec(Y)) uriBytes[writePos] = (byte) (16 * CharacterHexDigitToDecimal(uriBytes[co + 1]) + CharacterHexDigitToDecimal(uriBytes[co + 2])); percentsFound++; length -= 2; // we eliminated 2 characters from the length co += 3; } else { if (percentsFound != 0) { // we have to copy characters back into place since we will skip some characters // determine location to write to (we skip 2 character for each percent) int writePos = co - (percentsFound * 2); // copy character back into place uriBytes[writePos] = uriBytes[co]; } co++; } } } // DecodeUri // reading helper functions internal static int CharacterHexDigitToDecimal(byte b) { switch ((char)b) { case 'F': return 15; case 'E': return 14; case 'D': return 13; case 'C': return 12; case 'B': return 11; case 'A': return 10; default: return b - (byte)'0'; } } // CharacterHexDigitToDecimal internal static char DecimalToCharacterHexDigit(int i) { switch (i) { case 15: return 'F'; case 14: return 'E'; case 13: return 'D'; case 12: return 'C'; case 11: return 'B'; case 10: return 'A'; default: return (char)(i + (byte)'0'); } } // DecimalToCharacterHexDigit } // class HttpChannelHelper internal static class HttpEncodingHelper { internal static String EncodeUriAsXLinkHref(String uri) { if (uri == null) return null; // uses modified encoding rules from xlink href spec for encoding uri's. // http://www.w3.org/TR/2000/PR-xlink-20001220/#link-locators byte[] uriBytes = Encoding.UTF8.GetBytes(uri); StringBuilder sb = new StringBuilder(uri.Length); // iterate over uri bytes and build up an encoded string. foreach (byte b in uriBytes) { if (!EscapeInXLinkHref(b)) { sb.Append((char)b); } else { // the character needs to be encoded as %HH sb.Append('%'); sb.Append(HttpChannelHelper.DecimalToCharacterHexDigit(b >> 4)); sb.Append(HttpChannelHelper.DecimalToCharacterHexDigit(b & 0xF)); } } return sb.ToString(); } // EncodeUriAsXLinkHref internal static bool EscapeInXLinkHref(byte ch) { if ((ch <= 32) || // control characters and space (ch >= 128) || // non-ascii characters (ch == (byte)'<') || (ch == (byte)'>') || (ch == (byte)'"')) { return true; } return false; } // EscapeInXLinkHref internal static String DecodeUri(String uri) { byte[] uriBytes = Encoding.UTF8.GetBytes(uri); int length; HttpChannelHelper.DecodeUriInPlace(uriBytes, out length); String newUri = Encoding.UTF8.GetString(uriBytes, 0, length); return newUri; } // DecodeUri } // class HttpEncodingHelper } // namespace System.Runtime.Remoting.Channels.Http // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProfilePropertySettingsCollection.cs
- VScrollBar.cs
- EntityReference.cs
- Lease.cs
- SoapHeaderException.cs
- WebPartDisplayModeCollection.cs
- Typography.cs
- XmlWriterTraceListener.cs
- Rectangle.cs
- TableRowGroup.cs
- ParameterToken.cs
- ClosureBinding.cs
- EntityClientCacheEntry.cs
- ObjectListSelectEventArgs.cs
- ClientProtocol.cs
- _Rfc2616CacheValidators.cs
- SettingsBase.cs
- MemberRelationshipService.cs
- UriTemplatePathSegment.cs
- ArgumentReference.cs
- AssemblyInfo.cs
- EncodingStreamWrapper.cs
- TypeGeneratedEventArgs.cs
- SchemaMerger.cs
- CachedPathData.cs
- LOSFormatter.cs
- MultiByteCodec.cs
- BaseAutoFormat.cs
- ZipPackagePart.cs
- DetailsViewCommandEventArgs.cs
- Util.cs
- PrivateFontCollection.cs
- ClientSponsor.cs
- BezierSegment.cs
- ByteRangeDownloader.cs
- Hyperlink.cs
- UICuesEvent.cs
- BasePattern.cs
- EditorPartCollection.cs
- VisualTarget.cs
- login.cs
- OleDbConnection.cs
- RealizationDrawingContextWalker.cs
- SeverityFilter.cs
- OLEDB_Util.cs
- ToolStripButton.cs
- ComponentSerializationService.cs
- PersonalizationProvider.cs
- OracleInfoMessageEventArgs.cs
- COM2Properties.cs
- WebPermission.cs
- mactripleDES.cs
- PackageDigitalSignatureManager.cs
- UIElement.cs
- GridViewColumnCollectionChangedEventArgs.cs
- XmlSignificantWhitespace.cs
- ApplyImportsAction.cs
- DataControlField.cs
- ObjectNotFoundException.cs
- ActiveXSite.cs
- entitydatasourceentitysetnameconverter.cs
- EdmPropertyAttribute.cs
- XmlQualifiedNameTest.cs
- BindingNavigatorDesigner.cs
- ItemContainerGenerator.cs
- Delegate.cs
- ISCIIEncoding.cs
- UrlMapping.cs
- InitializeCorrelation.cs
- ValidatedControlConverter.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- MethodBuilder.cs
- FieldToken.cs
- Dispatcher.cs
- HotSpot.cs
- AttachedPropertyBrowsableAttribute.cs
- Renderer.cs
- ClientConfigurationSystem.cs
- LingerOption.cs
- SpeechDetectedEventArgs.cs
- PropertyToken.cs
- FontStretchConverter.cs
- WizardStepBase.cs
- XmlnsDictionary.cs
- InfoCardSymmetricCrypto.cs
- LayoutEvent.cs
- DataGridDesigner.cs
- CompModSwitches.cs
- GatewayDefinition.cs
- _DigestClient.cs
- DesignerInterfaces.cs
- InvalidOleVariantTypeException.cs
- SerializerDescriptor.cs
- ImageMetadata.cs
- TextElementCollection.cs
- CodeSubDirectoriesCollection.cs
- PathSegment.cs
- NamedPermissionSet.cs
- BitmapEffectInput.cs
- FieldMetadata.cs