public void Parse183SessionProgress() { const string HexData = "5349502f322e30203138332053657373696f6e2050726f67726573730d0a416c6c6f773a20494e564954452c4259452c52454749535445522c41434b2c4f5054494f4e532c43414e43454c2c494e464f2c5355425343524942452c4e4f544946592c52454645522c5550444154450d0a43616c6c2d49443a2033646534363232302d343038622d343065302d386164612d3436393366616530386437394031302e302e352e32350d0a436f6e746163743a203c7369703a31353439394031302e302e382e34343a353036303e0d0a436f6e74656e742d547970653a206d756c7469706172742f6d697865643b626f756e646172793d756e697175652d626f756e646172792d310d0a435365713a203220494e564954450d0a46726f6d3a203c7369703a31313939323937313732314031302e302e352e32353a353036303b757365723d70686f6e653e0d0a526571756972653a2031303072656c0d0a525365713a20310d0a53657373696f6e2d49443a2030316538316263313366363434356262646130313161633866376431323564330d0a537570706f727465643a2074696d65722c7265706c616365730d0a546f3a203c7369703a31353439394031302e302e382e34343a353036303b757365723d70686f6e653e3b7461673d363833312d463133330d0a5669613a205349502f322e302f5544502031302e302e352e32353a353036303b72656365697665643d31302e302e352e32353b6272616e63683d7a39684734624b3766653864316366323864333831383631660d0a436f6e74656e742d4c656e6774683a203430380d0a0d0a2d2d756e697175652d626f756e646172792d310d0a436f6e74656e742d547970653a206170706c69636174696f6e2f7364700d0a0d0a763d300d0a6f3d2d2039203020494e204950342031302e302e382e34340d0a733d2d0d0a633d494e204950342031302e302e382e34340d0a743d3020300d0a6d3d617564696f203130303136205254502f4156502038203130310d0a613d7274706d61703a382050434d412f383030300d0a613d7274706d61703a3130312074656c6570686f6e652d6576656e742f383030300d0a613d666d74703a31303120302d31350d0a613d7074696d653a32340d0a613d73656e64726563760d0a0d0a2d2d756e697175652d626f756e646172792d310d0a436f6e74656e742d547970653a206170706c69636174696f6e2f495355503b76657273696f6e3d6974752d7439322b3b626173653d6e7876330d0a436f6e74656e742d446973706f736974696f6e3a207369676e616c3b68616e646c696e673d6f7074696f6e616c0d0a0d0a06120001290101000d0a2d2d756e697175652d626f756e646172792d312d2d0d0a"; var binaryData = HexData.ToByteArray().ToArray(); SipMessage.Parse(binaryData); }
public void Shall_parse_response_bytes() { const string str = "SIP/2.0 200 OK\r\nContent-Length: 0\r\n" + "\r\n"; var response = (SipResponse)SipMessage.Parse(Encoding.UTF8.GetBytes(str)); Assert.That(response.Version, Is.EqualTo("SIP/2.0")); Assert.That(response.StatusCode, Is.EqualTo(200)); Assert.That(response.ReasonPhrase, Is.EqualTo("OK")); }
public void Shall_clone_request() { const string str = "INVITE sip:[email protected] SIP/2.0\r\n" + "From: John Smith <sip:[email protected]>\r\n" + "To: Joe Shmoe <sip:[email protected]>\r\n\r\n"; var original = (SipRequest)SipMessage.Parse(str); var cloned = original.DeepClone(); original.Method = "REGISTER"; Assert.That(cloned.ToString(), Does.Contain("INVITE")); Assert.That(original.Method, Does.Contain("REGISTER")); }
public void Shall_clone_response() { const string str = "SIP/2.0 200 OK\r\nContent-Length: 0\r\n" + "\r\n"; var original = (SipResponse)SipMessage.Parse(str); var cloned = original.DeepClone(); original.StatusCode = 183; original.ReasonPhrase = "Session Progress"; Assert.That(cloned.ToString(), Does.Contain("200 OK")); Assert.That(original.ToString(), Does.Contain("183 Session Progress")); }
public void Shall_set_level() { try { TraceEvent traceEvent = null; Trace.SetLogger(e => { traceEvent = e; }); Trace.SetLevel(TraceLevel.Fatal); SipMessage.Parse("INVITE sip:[email protected] SIP/0.0\r\n\r\n"); Assert.That(traceEvent, Is.Null); } finally { Trace.SetLogger(null); } }
public void Shall_intercept_trace() { try { TraceEvent traceEvent = null; Trace.SetLogger(e => { traceEvent = e; }); SipMessage.Parse("INVITE sip:[email protected] SIP/0.0\r\n\r\n"); Assert.That(traceEvent.FileName, Is.EqualTo("osip_message_parse.c")); Assert.That(traceEvent.LineNumber, Is.EqualTo(168)); Assert.That(traceEvent.Level, Is.EqualTo(TraceLevel.Error)); Assert.That(traceEvent.Message, Is.EqualTo("Wrong version number\n")); } finally { Trace.SetLogger(null); } }
public void Shall_byteify_response() { var response = new SipResponse { Version = "SIP/2.0", StatusCode = 200, ReasonPhrase = "OK" }; var buffer = new byte[ushort.MaxValue]; response.TryCopyTo(buffer, 0, out int length); var response2 = (SipResponse)SipMessage.Parse(new ArraySegment <byte>(buffer, 0, length)); Assert.That(response2.ToString(), Is.EqualTo( "SIP/2.0 200 OK\r\nContent-Length: 0\r\n" + "\r\n")); }
public void DeserializeInviteMessageWithIsupAndSdp(bool includeIsup, bool includeSdp) { MediaGateway.RegisterCodec(MediaGateway.AudioCodec.G711Alaw, () => new AlawMediaCodec(null, null)); const string CallId = "ABC"; const string LocalIp = "127.0.0.1"; Contact to = "[email protected]:5060;user=phone"; var @from = new Contact( "[email protected]:5060", null, new[] { new KeyValuePair <string, string>("user", "phone") }); Contact callerContact = "[email protected]:5060"; var invite = new InviteMessage(CallId, to, @from, @from); var port = MediaGateway.GetNextPort(); if (includeSdp) { invite.SdpData = new Sdp(); invite.SdpData.AddParameter("o", string.Format("- {0} 0 IN IP4 {1}", 10, LocalIp)) .AddParameter("s", "-") .AddParameter("c", "IN IP4 " + LocalIp) .AddParameter("t", "0 0") .AddParameter("m", string.Format("audio {0} RTP/AVP 8 101", port)) .AddParameter("a", "rtpmap:8 PCMA/8000") .AddParameter("a", "rtpmap:101 telephone-event/8000") .AddParameter("a", "fmtp:101 0-15").AddParameter("a", "sendrecv"); } if (includeIsup) { var isup = new IsupInitialAddress(); invite.IsupData = isup; isup.ForwardCallIndicator.LoadParameterData(new byte[] { 0x20, 0x01 }); isup.CallingPartyCategory.CategoryFlags = CallingPartyCategory.Category.Unknown; isup.NatureOfConnectionIndicator.EchoControlIncluded = false; isup.NatureOfConnectionIndicator.ContinuityCheckIndicator = NatureOfConnection.ContinuityCheckIndicatorFlags.NotRequired; isup.NatureOfConnectionIndicator.SatelliteIndicator = NatureOfConnection.SatelliteIndicatorFlags.One; isup.CalledNumber.Number = new string(invite.To.Address.TakeWhile(a => a != '@').ToArray()); isup.CalledNumber.NumberingFlags = NAIFlags.RoutingNotAllowed | NAIFlags.Isdn; isup.CalledNumber.Flags = PhoneFlags.NAINationalNumber; var callingNumber = invite.IsupData.AddOptionalParameter(new IsupPhoneNumberParameter(IsupParameterType.CallingPartyNumber) { Number = invite.From.Address.Split('@').FirstOrDefault() }); callingNumber.NumberingFlags |= NAIFlags.ScreeningVerifiedAndPassed | NAIFlags.NetworProvided; isup.AddOptionalParameter(new IsupPhoneNumberParameter(IsupParameterType.OriginalCalledNumber) { Number = callerContact.Address.Split('@').FirstOrDefault(), Flags = callingNumber.Flags, NumberingFlags = NAIFlags.PresentationRestricted | NAIFlags.Isdn }); isup.AddOptionalParameter(new IsupPhoneNumberParameter(IsupParameterType.RedirectingNumber) { Number = callerContact.Address.Split('@').FirstOrDefault(), Flags = callingNumber.Flags, NumberingFlags = NAIFlags.PresentationRestricted | NAIFlags.Isdn }); isup.AddOptionalParameter(new RedirectInfo { RedirectReason = RedirReason.NoReply, RedirectCounter = 1, RedirectIndicatorFlags = RedirectInfo.RedirectIndicator.CallDiverted }); } if (includeSdp) { invite.Headers["Via"] = string.Format("SIP/2.0/UDP {0}:5060;branch=z9hG4bK7fe{1}", LocalIp, DateTime.Now.Ticks.ToString("X8").ToLowerInvariant()); } var bytes = invite.Serialize(); var deserialized = SipMessage.Parse(bytes) as InviteMessage; Assert.IsNotNull(deserialized, "message isn't an invite"); Assert.That(invite.Contact, Is.EqualTo(deserialized.Contact)); Assert.AreEqual(invite.Contact.ToString(), deserialized.Contact.ToString()); Assert.AreEqual(invite.From, deserialized.From); Assert.AreEqual(invite.To, deserialized.To); if (includeSdp) { Assert.AreEqual(invite.SdpData.ContentText, deserialized.SdpData.ContentText); } if (includeIsup) { Assert.AreEqual(invite.IsupData.GetByteArray().ToHex().ToUpper(), deserialized.IsupData.GetByteArray().ToHex().ToUpper()); } Assert.AreEqual(invite.Method, deserialized.Method); }
public void Shall_byteify_request() { var request = new SipRequest { Version = "SIP/2.0", Method = "INVITE", RequestUri = SipUri.Parse("sip:[email protected]"), From = NameAddressHeader.Parse("John Smith <sip:[email protected]>"), To = NameAddressHeader.Parse("Joe Shmoe <sip:[email protected]>"), CallId = CallIdHeader.Parse("*****@*****.**"), CSeq = CSeqHeader.Parse("1 INVITE"), ContentType = ContentTypeHeader.Parse("text/plain"), MimeVersion = ContentLengthHeader.Parse("1.0") }; request.Vias.Add(ViaHeader.Parse("SIP/2.0/UDP foo.bar.com")); request.RecordRoutes.Add(NameAddressHeader.Parse("Tommy Atkins <sip:[email protected]>")); request.Routes.Add(NameAddressHeader.Parse("John Doe <sip:[email protected]>")); request.Contacts.Add(NameAddressHeader.Parse("Prisoner X <sip:[email protected]>")); request.Authorizations.Add(AuthorizationHeader.Parse("Digest username=\"Alice\"")); request.WwwAuthenticates.Add(WwwAuthenticateHeader.Parse("Digest realm=\"abc.com\"")); request.ProxyAuthenticates.Add(WwwAuthenticateHeader.Parse("Digest realm=\"xyz.com\"")); request.ProxyAuthorizations.Add(AuthorizationHeader.Parse("Digest username=\"Bob\"")); request.CallInfos.Add(CallInfoHeader.Parse("<http://www.abc.com/photo.png>;purpose=icon")); request.Allows.Add(ContentLengthHeader.Parse("INVITE, ACK, BYE")); request.ContentEncodings.Add(ContentLengthHeader.Parse("deflate")); request.AlertInfos.Add(CallInfoHeader.Parse("<http://www.abc.com/sound.wav>")); request.ErrorInfos.Add(CallInfoHeader.Parse("<sip:[email protected]>")); request.Accepts.Add(ContentTypeHeader.Parse("application/sdp")); request.AcceptEncodings.Add(AcceptEncodingHeader.Parse("gzip")); request.AcceptLanguages.Add(AcceptEncodingHeader.Parse("en")); request.AuthenticationInfos.Add(AuthenticationInfoHeader.Parse("nextnonce=\"abc\"")); request.ProxyAuthenticationInfos.Add(AuthenticationInfoHeader.Parse("nextnonce=\"def\"")); request.OtherHeaders.Add(new GenericHeader("P-Asserted-Identity", "sip:[email protected]")); request.Bodies.Add(SipBody.Parse("Hello world!")); var buffer = new byte[ushort.MaxValue]; var success = request.TryCopyTo(buffer, 0, out int length); Assert.That(success, Is.True); var request2 = SipMessage.Parse(new ArraySegment <byte>(buffer, 0, length)); Assert.That(request2.ToString(), Is.EqualTo( "INVITE sip:[email protected] SIP/2.0\r\n" + "Via: SIP/2.0/UDP foo.bar.com\r\n" + "Record-Route: Tommy Atkins <sip:[email protected]>\r\n" + "Route: John Doe <sip:[email protected]>\r\n" + "From: John Smith <sip:[email protected]>\r\n" + "To: Joe Shmoe <sip:[email protected]>\r\n" + "Call-ID: [email protected]\r\n" + "CSeq: 1 INVITE\r\n" + "Contact: Prisoner X <sip:[email protected]>\r\n" + "Authorization: Digest username=\"Alice\"\r\n" + "WWW-Authenticate: Digest realm=\"abc.com\"\r\n" + "Proxy-Authenticate: Digest realm=\"xyz.com\"\r\n" + "Proxy-Authorization: Digest username=\"Bob\"\r\n" + "Call-Info: <http://www.abc.com/photo.png>;purpose=icon\r\n" + "Content-Type: text/plain\r\n" + "Mime-Version: 1.0\r\n" + "Allow: INVITE\r\n" + "Allow: ACK\r\n" + "Allow: BYE\r\n" + "Content-Encoding: deflate\r\n" + "Alert-Info: <http://www.abc.com/sound.wav>\r\n" + "Error-Info: <sip:[email protected]>\r\n" + "Accept: application/sdp\r\n" + "Accept-Encoding: gzip\r\n" + "Accept-Language: en\r\n" + "Authentication-Info: nextnonce=\"abc\"\r\n" + "Proxy-Authentication-Info: nextnonce=\"def\"\r\n" + "P-asserted-identity: sip:[email protected]\r\n" + "Content-Length: 12\r\n" + "\r\n" + "Hello world!")); }
public void Shall_parse_request_bytes() { const string str = "INVITE sip:[email protected] SIP/2.0\r\n" + "Via: SIP/2.0/UDP foo.bar.com\r\n" + "Record-Route: Tommy Atkins <sip:[email protected]>\r\n" + "Route: John Doe <sip:[email protected]>\r\n" + "From: John Smith <sip:[email protected]>\r\n" + "To: Joe Shmoe <sip:[email protected]>\r\n" + "Call-ID: [email protected]\r\n" + "CSeq: 1 INVITE\r\n" + "Contact: Prisoner X <sip:[email protected]>\r\n" + "Authorization: Digest username=\"Alice\"\r\n" + "WWW-Authenticate: Digest realm=\"abc.com\"\r\n" + "Proxy-Authenticate: Digest realm=\"xyz.com\"\r\n" + "Proxy-Authorization: Digest username=\"Bob\"\r\n" + "Call-Info: <http://www.abc.com/photo.png>;purpose=icon\r\n" + "Content-Type: text/plain\r\n" + "Mime-Version: 1.0\r\n" + "Allow: INVITE, BYE\r\n" + "Content-Encoding: deflate\r\n" + "Alert-Info: <http://www.abc.com/sound.wav>\r\n" + "Error-Info: <sip:[email protected]>\r\n" + "Accept: application/sdp\r\n" + "Accept-Encoding: gzip\r\n" + "Accept-Language: en\r\n" + "Authentication-Info: nextnonce=\"abc\"\r\n" + "Proxy-Authentication-Info: nextnonce=\"def\"\r\n" + "P-Asserted-Identity: sip:[email protected]\r\n" + "Content-Length: 12\r\n" + "\r\n" + "Hello world!"; var request = (SipRequest)SipMessage.Parse(Encoding.UTF8.GetBytes(str)); Assert.That(request.Version, Is.EqualTo("SIP/2.0")); Assert.That(request.Method, Is.EqualTo("INVITE")); Assert.That(request.RequestUri.ToString(), Is.EqualTo("sip:[email protected]")); Assert.That(request.Vias[0].ToString(), Is.EqualTo("SIP/2.0/UDP foo.bar.com")); Assert.That(request.RecordRoutes[0].ToString(), Is.EqualTo("Tommy Atkins <sip:[email protected]>")); Assert.That(request.Routes[0].ToString(), Is.EqualTo("John Doe <sip:[email protected]>")); Assert.That(request.From.ToString(), Is.EqualTo("John Smith <sip:[email protected]>")); Assert.That(request.To.ToString(), Is.EqualTo("Joe Shmoe <sip:[email protected]>")); Assert.That(request.CallId.ToString(), Is.EqualTo("*****@*****.**")); Assert.That(request.CSeq.ToString(), Is.EqualTo("1 INVITE")); Assert.That(request.Contacts[0].ToString(), Is.EqualTo("Prisoner X <sip:[email protected]>")); Assert.That(request.Authorizations[0].ToString(), Is.EqualTo("Digest username=\"Alice\"")); Assert.That(request.WwwAuthenticates[0].ToString(), Is.EqualTo("Digest realm=\"abc.com\"")); Assert.That(request.ProxyAuthenticates[0].ToString(), Is.EqualTo("Digest realm=\"xyz.com\"")); Assert.That(request.ProxyAuthorizations[0].ToString(), Is.EqualTo("Digest username=\"Bob\"")); Assert.That(request.CallInfos[0].ToString(), Is.EqualTo("<http://www.abc.com/photo.png>;purpose=icon")); Assert.That(request.ContentType.ToString(), Is.EqualTo("text/plain")); Assert.That(request.MimeVersion.ToString(), Is.EqualTo("1.0")); Assert.That(request.Allows.Count, Is.EqualTo(2)); Assert.That(request.Allows[0].ToString(), Is.EqualTo("INVITE")); Assert.That(request.Allows[1].ToString(), Is.EqualTo("BYE")); Assert.That(request.ContentEncodings[0].ToString(), Is.EqualTo("deflate")); Assert.That(request.AlertInfos[0].ToString(), Is.EqualTo("<http://www.abc.com/sound.wav>")); Assert.That(request.ErrorInfos[0].ToString(), Is.EqualTo("<sip:[email protected]>")); Assert.That(request.Accepts[0].ToString(), Is.EqualTo("application/sdp")); Assert.That(request.AcceptEncodings[0].ToString(), Is.EqualTo("gzip")); Assert.That(request.AcceptLanguages[0].ToString(), Is.EqualTo("en")); Assert.That(request.AuthenticationInfos[0].ToString(), Is.EqualTo("nextnonce=\"abc\"")); Assert.That(request.ProxyAuthenticationInfos[0].ToString(), Is.EqualTo("nextnonce=\"def\"")); Assert.That(request.OtherHeaders[0].Name, Is.EqualTo("p-asserted-identity")); Assert.That(request.OtherHeaders[0].Value, Is.EqualTo("sip:[email protected]")); Assert.That(request.ContentLength.ToString(), Is.EqualTo("12")); Assert.That(request.Bodies[0].ToString(), Is.EqualTo("Hello world!")); }
public void SipResponse_Serialize() { SipResponse response; string input; string output; input = @"SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.1.200 Content-Length: 0 "; response = (SipResponse)SipMessage.Parse(Helper.ToUTF8(input), true); Assert.AreEqual("SIP/2.0", response.SipVersion); Assert.AreEqual(SipStatus.OK, response.Status); Assert.AreEqual("OK", response.ReasonPhrase); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", response[SipHeader.Via].Text); Assert.AreEqual("0", response[SipHeader.ContentLength].Text); output = response.ToString(); Assert.AreEqual(input, output); CollectionAssert.AreEqual(Helper.ToUTF8(input), response.ToArray()); // Header continuation input = @"SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.1.200 Content-Length: 0 "; response = (SipResponse)SipMessage.Parse(Helper.ToUTF8(input), true); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", response[SipHeader.Via].Text); Assert.AreEqual("0", response[SipHeader.ContentLength].Text); // Data with Content-Length header input = @"SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.1.200 Content-Length: 4 "; response = (SipResponse)SipMessage.Parse(Helper.Concat(Helper.ToUTF8(input), new byte[] { 0, 1, 2, 3 }), true); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", response[SipHeader.Via].Text); Assert.AreEqual("4", response[SipHeader.ContentLength].Text); Assert.AreEqual(4, response.ContentLength); CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3 }, response.Contents); // Data with no Content-Length header input = @"SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.1.200 "; response = (SipResponse)SipMessage.Parse(Helper.Concat(Helper.ToUTF8(input), new byte[] { 0, 1, 2, 3 }), true); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", response[SipHeader.Via].Text); Assert.IsNull(response[SipHeader.ContentLength]); Assert.AreEqual(4, response.ContentLength); CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3 }, response.Contents); }
public void Parse100Trying(string msg) { var bytes = Encoding.Default.GetBytes(msg); SipMessage.Parse(bytes); }
public void SipRequest_Serialize() { SipRequest request; string input; string output; input = @"INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 192.168.1.200 Content-Length: 0 "; request = (SipRequest)SipMessage.Parse(Helper.ToUTF8(input), true); Assert.AreEqual("SIP/2.0", request.SipVersion); Assert.AreEqual("INVITE", request.MethodText); Assert.AreEqual(SipMethod.Invite, request.Method); Assert.AreEqual("sip:[email protected]", request.Uri); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", request[SipHeader.Via].Text); Assert.AreEqual("0", request[SipHeader.ContentLength].Text); output = request.ToString(); Assert.AreEqual(input, output); CollectionAssert.AreEqual(Helper.ToUTF8(input), request.ToArray()); // Header continuation input = @"invite sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 192.168.1.200 Content-Length: 0 "; request = (SipRequest)SipMessage.Parse(Helper.ToUTF8(input), true); Assert.AreEqual("SIP/2.0", request.SipVersion); Assert.AreEqual("INVITE", request.MethodText); Assert.AreEqual(SipMethod.Invite, request.Method); Assert.AreEqual("sip:[email protected]", request.Uri); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", request[SipHeader.Via].Text); Assert.AreEqual("0", request[SipHeader.ContentLength].Text); // Data with Content-Length header input = @"register sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 192.168.1.200 Content-Length: 4 "; request = (SipRequest)SipMessage.Parse(Helper.Concat(Helper.ToUTF8(input), new byte[] { 0, 1, 2, 3 }), true); Assert.AreEqual("REGISTER", request.MethodText); Assert.AreEqual(SipMethod.Register, request.Method); Assert.AreEqual("SIP/2.0", request.SipVersion); Assert.AreEqual("sip:[email protected]", request.Uri); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", request[SipHeader.Via].Text); Assert.AreEqual("4", request[SipHeader.ContentLength].Text); Assert.AreEqual(4, request.ContentLength); CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3 }, request.Contents); // Data with no Content-Length header input = @"INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 192.168.1.200 "; request = (SipRequest)SipMessage.Parse(Helper.Concat(Helper.ToUTF8(input), new byte[] { 0, 1, 2, 3 }), true); Assert.AreEqual("INVITE", request.MethodText); Assert.AreEqual(SipMethod.Invite, request.Method); Assert.AreEqual("SIP/2.0", request.SipVersion); Assert.AreEqual("sip:[email protected]", request.Uri); Assert.AreEqual("SIP/2.0/UDP 192.168.1.200", request[SipHeader.Via].Text); Assert.IsNull(request[SipHeader.ContentLength]); Assert.AreEqual(4, request.ContentLength); CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3 }, request.Contents); }