/// <inheritdoc /> public int Serialize(ref byte[] bytes, int offset, HttpResponseMessage response, IFormatterResolver formatterResolver) { if (response is null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } int startOffset = offset; offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, 5); // Version: offset += MessagePackBinary.WriteString(ref bytes, offset, response.Version.ToString()); // Status Code offset += MessagePackBinary.WriteUInt16(ref bytes, offset, (ushort)response.StatusCode); // ReasonPhrase offset += MessagePackBinary.WriteString(ref bytes, offset, response.ReasonPhrase); // Headers KeyValuePair <string, IEnumerable <string> >[] headers = response.Headers.ToArray(); offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, headers.Length); foreach (KeyValuePair <string, IEnumerable <string> > kvp in headers) { // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 Header names are not case-sensitive // so we normalize to lower case offset += MessagePackBinary.WriteString(ref bytes, offset, kvp.Key.ToLowerInvariant()); string[] values = kvp.Value.ToArray(); offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, values.Length); foreach (string v in values) { offset += MessagePackBinary.WriteString(ref bytes, offset, v); } } // NOTE we don't serialize the request, as we substitute with the supplied one in the Recording. // Content offset += HttpContentFormatter.Serialize(ref bytes, offset, response.Content); return(offset - startOffset); }
/// <inheritdoc /> public int Serialize(ref byte[] bytes, int offset, HttpRequestMessage request, IFormatterResolver formatterResolver) { if (request is null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } int startOffset = offset; offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, 5); // RequestPart.Version: offset += MessagePackBinary.WriteString(ref bytes, offset, request.Version.ToString()); // RequestPart.Uri: offset += MessagePackBinary.WriteString(ref bytes, offset, request.RequestUri.ToString()); // RequestPart.Method: offset += MessagePackBinary.WriteString(ref bytes, offset, request.Method.Method); // RequestPart.Headers: KeyValuePair <string, IEnumerable <string> >[] headers = request.Headers.ToArray(); offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, headers.Length); foreach (KeyValuePair <string, IEnumerable <string> > kvp in headers) { // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 Header names are not case-sensitive // so we normalize to lower case offset += MessagePackBinary.WriteString(ref bytes, offset, kvp.Key.ToLowerInvariant()); string[] values = kvp.Value.ToArray(); offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, values.Length); foreach (string v in values) { offset += MessagePackBinary.WriteString(ref bytes, offset, v); } } // RequestPart.Content: offset += HttpContentFormatter.Serialize(ref bytes, offset, request.Content); return(offset - startOffset); }
/// <inheritdoc /> public int Serialize(ref byte[] bytes, int offset, HttpRequestMessage request, IFormatterResolver formatterResolver) { if (request is null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } int startOffset = offset; Uri uri = request.RequestUri; offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, _parts.Count + 1); // Add the parts into the key output, to further mangle the hash and prevent collisions. offset += MessagePackBinary.WriteUInt16(ref bytes, offset, (ushort)Parts); foreach (RequestPart part in _parts) { switch (part) { case RequestPart.Version: offset += MessagePackBinary.WriteString(ref bytes, offset, request.Version.ToString()); break; case RequestPart.UriScheme: offset += MessagePackBinary.WriteString(ref bytes, offset, uri.Scheme); break; case RequestPart.UriUserInfo: offset += MessagePackBinary.WriteString(ref bytes, offset, uri.UserInfo); break; case RequestPart.UriHost: offset += MessagePackBinary.WriteString(ref bytes, offset, uri.Host); break; case RequestPart.UriPort: int port = uri.Port; // Note -1 is returned for a protocol with no default port and no port specified, this // should never really happen in practice. Also port numbers should never exceed 65535. // For these edge case we treat as the default port and we store 0, which is a special port // That we should never explicitly use in a Http request. if (port < 1 || port > ushort.MaxValue) { port = 0; } offset += MessagePackBinary.WriteUInt16(ref bytes, offset, (ushort)port); break; case RequestPart.UriPath: // Strip the preceding '/' from path. offset += MessagePackBinary.WriteString(ref bytes, offset, uri.AbsolutePath.Substring(1)); break; case RequestPart.UriQuery: // Strip the preceding '?' from path. offset += MessagePackBinary.WriteString(ref bytes, offset, uri.Query.Substring(1)); break; case RequestPart.Method: offset += MessagePackBinary.WriteString(ref bytes, offset, request.Method.Method); break; case RequestPart.Headers: KeyValuePair <string, IEnumerable <string> >[] headers = request.Headers.ToArray(); offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, headers.Length); foreach (KeyValuePair <string, IEnumerable <string> > kvp in headers) { // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 Header names are not case-sensitive // so we normalize to lower case offset += MessagePackBinary.WriteString(ref bytes, offset, kvp.Key.ToLowerInvariant()); string[] values = kvp.Value.ToArray(); offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, values.Length); foreach (string v in values) { offset += MessagePackBinary.WriteString(ref bytes, offset, v); } } break; case RequestPart.Content: offset += HttpContentFormatter.Serialize(ref bytes, offset, request.Content); break; default: throw new ArgumentOutOfRangeException(); } } return(offset - startOffset); }