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
- SpotLight.cs
- ToolStripSeparator.cs
- XmlNamespaceDeclarationsAttribute.cs
- SubclassTypeValidator.cs
- CreateUserWizardDesigner.cs
- TypeElement.cs
- ColumnResizeAdorner.cs
- FixedStringLookup.cs
- AssociationTypeEmitter.cs
- SqlCacheDependency.cs
- ProcessHost.cs
- SHA1Managed.cs
- TemplateContainer.cs
- CapabilitiesUse.cs
- DataListItemEventArgs.cs
- DbMetaDataColumnNames.cs
- ServiceMetadataContractBehavior.cs
- MembershipSection.cs
- FontCacheUtil.cs
- PartManifestEntry.cs
- WindowsContainer.cs
- EncryptedKey.cs
- TraceListener.cs
- FontNamesConverter.cs
- NullableFloatSumAggregationOperator.cs
- PassportAuthentication.cs
- GetKeyedHashRequest.cs
- SchemaMapping.cs
- SqlConnectionString.cs
- LocatorPart.cs
- SystemIcmpV6Statistics.cs
- UITypeEditor.cs
- ValueChangedEventManager.cs
- RuleRefElement.cs
- XsdDuration.cs
- DataObject.cs
- SqlCommandBuilder.cs
- ButtonPopupAdapter.cs
- PackWebRequest.cs
- ColorBlend.cs
- ModulesEntry.cs
- PropertyTabAttribute.cs
- MimeWriter.cs
- Literal.cs
- VisualTransition.cs
- ScriptIgnoreAttribute.cs
- BitmapEncoder.cs
- RawUIStateInputReport.cs
- DrawingDrawingContext.cs
- KeyInfo.cs
- XPathEmptyIterator.cs
- StaticExtension.cs
- httpstaticobjectscollection.cs
- PasswordTextNavigator.cs
- Propagator.JoinPropagator.cs
- ExpandedWrapper.cs
- TextCharacters.cs
- DataFormat.cs
- unsafenativemethodsother.cs
- ApplicationContext.cs
- AlternateView.cs
- _ContextAwareResult.cs
- ImageKeyConverter.cs
- StoreAnnotationsMap.cs
- NavigatingCancelEventArgs.cs
- NameTable.cs
- PointConverter.cs
- RenderDataDrawingContext.cs
- RpcResponse.cs
- GenericUriParser.cs
- SqlDataSourceCache.cs
- CompatibleComparer.cs
- DynamicQueryableWrapper.cs
- SafeNativeMethodsCLR.cs
- WindowsSspiNegotiation.cs
- XPathPatternParser.cs
- XmlNamedNodeMap.cs
- Math.cs
- HelpKeywordAttribute.cs
- FieldToken.cs
- IImplicitResourceProvider.cs
- MappingSource.cs
- DataBoundControlDesigner.cs
- EncoderParameter.cs
- BamlRecordWriter.cs
- WorkflowElementDialog.cs
- BaseDataList.cs
- Animatable.cs
- Type.cs
- LeftCellWrapper.cs
- SqlConnectionString.cs
- DataGridViewRowStateChangedEventArgs.cs
- UIElement.cs
- ClaimComparer.cs
- WindowsPen.cs
- OutputCacheSection.cs
- AbstractDataSvcMapFileLoader.cs
- Ops.cs
- ProjectedWrapper.cs
- Win32NamedPipes.cs