Add more microbenchmarks.
This commit is contained in:
parent
537b06f025
commit
0404bcc58c
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||
{
|
||||
[Config(typeof(CoreConfig))]
|
||||
public class FrameParsingOverhead
|
||||
{
|
||||
private const int InnerLoopCount = 512;
|
||||
|
||||
public ReadableBuffer _buffer;
|
||||
public Frame<object> _frame;
|
||||
|
||||
[Setup]
|
||||
public void Setup()
|
||||
{
|
||||
var connectionContext = new MockConnection(new KestrelServerOptions());
|
||||
connectionContext.ListenerContext.ServiceContext.HttpParserFactory = frame => NullParser.Instance;
|
||||
|
||||
_frame = new Frame<object>(application: null, context: connectionContext);
|
||||
}
|
||||
|
||||
[Benchmark(Baseline = true, OperationsPerInvoke = InnerLoopCount)]
|
||||
public void FrameOverheadTotal()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
{
|
||||
ParseRequest();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount)]
|
||||
public void FrameOverheadRequestLine()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
{
|
||||
ParseRequestLine();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount)]
|
||||
public void FrameOverheadRequestHeaders()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
{
|
||||
ParseRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseRequest()
|
||||
{
|
||||
_frame.Reset();
|
||||
|
||||
if (!_frame.TakeStartLine(_buffer, out var consumed, out var examined))
|
||||
{
|
||||
RequestParsing.ThrowInvalidRequestLine();
|
||||
}
|
||||
|
||||
_frame.InitializeHeaders();
|
||||
|
||||
if (!_frame.TakeMessageHeaders(_buffer, out consumed, out examined))
|
||||
{
|
||||
RequestParsing.ThrowInvalidRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseRequestLine()
|
||||
{
|
||||
_frame.Reset();
|
||||
|
||||
if (!_frame.TakeStartLine(_buffer, out var consumed, out var examined))
|
||||
{
|
||||
RequestParsing.ThrowInvalidRequestLine();
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseRequestHeaders()
|
||||
{
|
||||
_frame.Reset();
|
||||
_frame.InitializeHeaders();
|
||||
|
||||
if (!_frame.TakeMessageHeaders(_buffer, out var consumed, out var examined))
|
||||
{
|
||||
RequestParsing.ThrowInvalidRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
private class NullParser : IHttpParser
|
||||
{
|
||||
private readonly byte[] _target = Encoding.ASCII.GetBytes("/plaintext");
|
||||
private readonly byte[] _hostHeaderName = Encoding.ASCII.GetBytes("Host");
|
||||
private readonly byte[] _hostHeaderValue = Encoding.ASCII.GetBytes("www.example.com");
|
||||
private readonly byte[] _acceptHeaderName = Encoding.ASCII.GetBytes("Accept");
|
||||
private readonly byte[] _acceptHeaderValue = Encoding.ASCII.GetBytes("text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\r\n\r\n");
|
||||
private readonly byte[] _connectionHeaderName = Encoding.ASCII.GetBytes("Connection");
|
||||
private readonly byte[] _connectionHeaderValue = Encoding.ASCII.GetBytes("keep-alive");
|
||||
|
||||
public static readonly NullParser Instance = new NullParser();
|
||||
|
||||
public bool ParseHeaders<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler
|
||||
{
|
||||
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_connectionHeaderName), new Span<byte>(_connectionHeaderValue));
|
||||
|
||||
consumedBytes = 0;
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ParseRequestLine<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) where T : IHttpRequestLineHandler
|
||||
{
|
||||
handler.OnStartLine(HttpMethod.Get, HttpVersion.Http11, new Span<byte>(_target), new Span<byte>(_target), Span<byte>.Empty, Span<byte>.Empty);
|
||||
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||
{
|
||||
[Config(typeof(CoreConfig))]
|
||||
|
||||
public class KestrelHttpParser : IHttpRequestLineHandler, IHttpHeadersHandler
|
||||
{
|
||||
private readonly Internal.Http.KestrelHttpParser _parser = new Internal.Http.KestrelHttpParser(log: null);
|
||||
|
||||
private ReadableBuffer _buffer;
|
||||
|
||||
[Benchmark(Baseline = true, OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void PlaintextTechEmpower()
|
||||
{
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(RequestParsingData.PlaintextTechEmpowerRequest);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void LiveAspNet()
|
||||
{
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(RequestParsingData.LiveaspnetRequest);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void Unicode()
|
||||
{
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(RequestParsingData.UnicodeRequest);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertData(byte[] data)
|
||||
{
|
||||
_buffer = ReadableBuffer.Create(data);
|
||||
}
|
||||
|
||||
private void ParseData()
|
||||
{
|
||||
if (!_parser.ParseRequestLine(this, _buffer, out var consumed, out var examined))
|
||||
{
|
||||
RequestParsing.ThrowInvalidRequestHeaders();
|
||||
}
|
||||
|
||||
_buffer = _buffer.Slice(consumed, _buffer.End);
|
||||
|
||||
if (!_parser.ParseHeaders(this, _buffer, out consumed, out examined, out var consumedBytes))
|
||||
{
|
||||
RequestParsing.ThrowInvalidRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnHeader(Span<byte> name, Span<byte> value)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,10 +40,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
{
|
||||
BenchmarkRunner.Run<PipeThroughput>();
|
||||
}
|
||||
if (type.HasFlag(BenchmarkType.KnownStrings))
|
||||
if (type.HasFlag(BenchmarkType.KnownStrings))
|
||||
{
|
||||
BenchmarkRunner.Run<KnownStrings>();
|
||||
}
|
||||
if (type.HasFlag(BenchmarkType.KestrelHttpParser))
|
||||
{
|
||||
BenchmarkRunner.Run<KestrelHttpParser>();
|
||||
}
|
||||
if (type.HasFlag(BenchmarkType.FrameParsingOverhead))
|
||||
{
|
||||
BenchmarkRunner.Run<FrameParsingOverhead>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,6 +62,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
Writing = 2,
|
||||
Throughput = 4,
|
||||
KnownStrings = 8,
|
||||
KestrelHttpParser = 16,
|
||||
FrameParsingOverhead = 32,
|
||||
// add new ones in powers of two - e.g. 2,4,8,16...
|
||||
|
||||
All = uint.MaxValue
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
|
|
@ -14,107 +12,82 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
[Config(typeof(CoreConfig))]
|
||||
public class RequestParsing
|
||||
{
|
||||
private const int InnerLoopCount = 512;
|
||||
private const int Pipelining = 16;
|
||||
|
||||
private const string plaintextTechEmpower = "GET /plaintext HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Accept: text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\r\n" +
|
||||
"Connection: keep-alive\r\n\r\n";
|
||||
|
||||
private const string liveaspnetRequest = "GET https://live.asp.net/ HTTP/1.1\r\n" +
|
||||
"Host: live.asp.net\r\n" +
|
||||
"Connection: keep-alive\r\n" +
|
||||
"Upgrade-Insecure-Requests: 1\r\n" +
|
||||
"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36\r\n" +
|
||||
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" +
|
||||
"DNT: 1\r\n" +
|
||||
"Accept-Encoding: gzip, deflate, sdch, br\r\n" +
|
||||
"Accept-Language: en-US,en;q=0.8\r\n" +
|
||||
"Cookie: __unam=7a67379-1s65dc575c4-6d778abe-1; omniID=9519gfde_3347_4762_8762_df51458c8ec2\r\n\r\n";
|
||||
|
||||
private const string unicodeRequest =
|
||||
"GET http://stackoverflow.com/questions/40148683/why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric HTTP/1.1\r\n" +
|
||||
"Accept: text/html, application/xhtml+xml, image/jxr, */*\r\n" +
|
||||
"Accept-Language: en-US,en-GB;q=0.7,en;q=0.3\r\n" +
|
||||
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.14965\r\n" +
|
||||
"Accept-Encoding: gzip, deflate\r\n" +
|
||||
"Host: stackoverflow.com\r\n" +
|
||||
"Connection: Keep-Alive\r\n" +
|
||||
"Cache-Control: max-age=0\r\n" +
|
||||
"Upgrade-Insecure-Requests: 1\r\n" +
|
||||
"DNT: 1\r\n" +
|
||||
"Referer: http://stackoverflow.com/?tab=month\r\n" +
|
||||
"Pragma: no-cache\r\n" +
|
||||
"Cookie: prov=20629ccd-8b0f-e8ef-2935-cd26609fc0bc; __qca=P0-1591065732-1479167353442; _ga=GA1.2.1298898376.1479167354; _gat=1; sgt=id=9519gfde_3347_4762_8762_df51458c8ec2; acct=t=why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric&s=why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric\r\n\r\n";
|
||||
|
||||
private static readonly byte[] _plaintextTechEmpowerPipelinedRequests = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat(plaintextTechEmpower, Pipelining)));
|
||||
private static readonly byte[] _plaintextTechEmpower = Encoding.ASCII.GetBytes(plaintextTechEmpower);
|
||||
|
||||
private static readonly byte[] _liveaspnentPipelinedRequests = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat(liveaspnetRequest, Pipelining)));
|
||||
private static readonly byte[] _liveaspnentRequest = Encoding.ASCII.GetBytes(liveaspnetRequest);
|
||||
|
||||
private static readonly byte[] _unicodePipelinedRequests = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat(unicodeRequest, Pipelining)));
|
||||
private static readonly byte[] _unicodeRequest = Encoding.ASCII.GetBytes(unicodeRequest);
|
||||
|
||||
[Params(typeof(KestrelHttpParser))]
|
||||
[Params(typeof(Internal.Http.KestrelHttpParser))]
|
||||
public Type ParserType { get; set; }
|
||||
|
||||
[Benchmark(Baseline = true, OperationsPerInvoke = InnerLoopCount)]
|
||||
public void ParsePlaintextTechEmpower()
|
||||
public IPipe Pipe { get; set; }
|
||||
|
||||
public Frame<object> Frame { get; set; }
|
||||
|
||||
public PipeFactory PipelineFactory { get; set; }
|
||||
|
||||
[Setup]
|
||||
public void Setup()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++) {
|
||||
InsertData(_plaintextTechEmpower);
|
||||
var connectionContext = new MockConnection(new KestrelServerOptions());
|
||||
connectionContext.ListenerContext.ServiceContext.HttpParserFactory = frame => (IHttpParser)Activator.CreateInstance(ParserType, frame.ConnectionContext.ListenerContext.ServiceContext.Log);
|
||||
|
||||
Frame = new Frame<object>(application: null, context: connectionContext);
|
||||
PipelineFactory = new PipeFactory();
|
||||
Pipe = PipelineFactory.Create();
|
||||
}
|
||||
|
||||
[Benchmark(Baseline = true, OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void PlaintextTechEmpower()
|
||||
{
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(RequestParsingData.PlaintextTechEmpowerRequest);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount * Pipelining)]
|
||||
public void ParsePipelinedPlaintextTechEmpower()
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount * RequestParsingData.Pipelining)]
|
||||
public void PipelinedPlaintextTechEmpower()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(_plaintextTechEmpowerPipelinedRequests);
|
||||
InsertData(RequestParsingData.PlaintextTechEmpowerPipelinedRequests);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount)]
|
||||
public void ParseLiveAspNet()
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void LiveAspNet()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(_liveaspnentRequest);
|
||||
InsertData(RequestParsingData.LiveaspnetRequest);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount * Pipelining)]
|
||||
public void ParsePipelinedLiveAspNet()
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount * RequestParsingData.Pipelining)]
|
||||
public void PipelinedLiveAspNet()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(_liveaspnentPipelinedRequests);
|
||||
InsertData(RequestParsingData.LiveaspnetPipelinedRequests);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount)]
|
||||
public void ParseUnicode()
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void Unicode()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(_unicodeRequest);
|
||||
InsertData(RequestParsingData.UnicodeRequest);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerLoopCount * Pipelining)]
|
||||
public void ParseUnicodePipelined()
|
||||
[Benchmark(OperationsPerInvoke = RequestParsingData.InnerLoopCount * RequestParsingData.Pipelining)]
|
||||
public void UnicodePipelined()
|
||||
{
|
||||
for (var i = 0; i < InnerLoopCount; i++)
|
||||
for (var i = 0; i < RequestParsingData.InnerLoopCount; i++)
|
||||
{
|
||||
InsertData(_unicodePipelinedRequests);
|
||||
InsertData(RequestParsingData.UnicodePipelinedRequests);
|
||||
ParseData();
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +118,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
|
||||
if (!Frame.TakeStartLine(readableBuffer, out var consumed, out var examined))
|
||||
{
|
||||
ThrowInvalidStartLine();
|
||||
ThrowInvalidRequestLine();
|
||||
}
|
||||
Pipe.Reader.Advance(consumed, examined);
|
||||
|
||||
|
|
@ -156,38 +129,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
|
||||
if (!Frame.TakeMessageHeaders(readableBuffer, out consumed, out examined))
|
||||
{
|
||||
ThrowInvalidMessageHeaders();
|
||||
ThrowInvalidRequestHeaders();
|
||||
}
|
||||
Pipe.Reader.Advance(consumed, examined);
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
private void ThrowInvalidStartLine()
|
||||
public static void ThrowInvalidRequestLine()
|
||||
{
|
||||
throw new InvalidOperationException("Invalid StartLine");
|
||||
throw new InvalidOperationException("Invalid request line");
|
||||
}
|
||||
|
||||
private void ThrowInvalidMessageHeaders()
|
||||
public static void ThrowInvalidRequestHeaders()
|
||||
{
|
||||
throw new InvalidOperationException("Invalid MessageHeaders");
|
||||
throw new InvalidOperationException("Invalid request headers");
|
||||
}
|
||||
|
||||
[Setup]
|
||||
public void Setup()
|
||||
{
|
||||
var connectionContext = new MockConnection(new KestrelServerOptions());
|
||||
connectionContext.ListenerContext.ServiceContext.HttpParserFactory = frame => (IHttpParser)Activator.CreateInstance(ParserType, frame.ConnectionContext.ListenerContext.ServiceContext.Log);
|
||||
|
||||
Frame = new Frame<object>(application: null, context: connectionContext);
|
||||
PipelineFactory = new PipeFactory();
|
||||
Pipe = PipelineFactory.Create();
|
||||
}
|
||||
|
||||
public IPipe Pipe { get; set; }
|
||||
|
||||
public Frame<object> Frame { get; set; }
|
||||
|
||||
public PipeFactory PipelineFactory { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||
{
|
||||
[Config(typeof(CoreConfig))]
|
||||
public class RequestParsingData
|
||||
{
|
||||
public const int InnerLoopCount = 512;
|
||||
|
||||
public const int Pipelining = 16;
|
||||
|
||||
private const string _plaintextTechEmpowerRequest =
|
||||
"GET /plaintext HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Accept: text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\r\n" +
|
||||
"Connection: keep-alive\r\n" +
|
||||
"\r\n";
|
||||
|
||||
private const string _liveaspnetRequest =
|
||||
"GET https://live.asp.net/ HTTP/1.1\r\n" +
|
||||
"Host: live.asp.net\r\n" +
|
||||
"Connection: keep-alive\r\n" +
|
||||
"Upgrade-Insecure-Requests: 1\r\n" +
|
||||
"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36\r\n" +
|
||||
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" +
|
||||
"DNT: 1\r\n" +
|
||||
"Accept-Encoding: gzip, deflate, sdch, br\r\n" +
|
||||
"Accept-Language: en-US,en;q=0.8\r\n" +
|
||||
"Cookie: __unam=7a67379-1s65dc575c4-6d778abe-1; omniID=9519gfde_3347_4762_8762_df51458c8ec2\r\n" +
|
||||
"\r\n";
|
||||
|
||||
private const string _unicodeRequest =
|
||||
"GET http://stackoverflow.com/questions/40148683/why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric HTTP/1.1\r\n" +
|
||||
"Accept: text/html, application/xhtml+xml, image/jxr, */*\r\n" +
|
||||
"Accept-Language: en-US,en-GB;q=0.7,en;q=0.3\r\n" +
|
||||
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.14965\r\n" +
|
||||
"Accept-Encoding: gzip, deflate\r\n" +
|
||||
"Host: stackoverflow.com\r\n" +
|
||||
"Connection: Keep-Alive\r\n" +
|
||||
"Cache-Control: max-age=0\r\n" +
|
||||
"Upgrade-Insecure-Requests: 1\r\n" +
|
||||
"DNT: 1\r\n" +
|
||||
"Referer: http://stackoverflow.com/?tab=month\r\n" +
|
||||
"Pragma: no-cache\r\n" +
|
||||
"Cookie: prov=20629ccd-8b0f-e8ef-2935-cd26609fc0bc; __qca=P0-1591065732-1479167353442; _ga=GA1.2.1298898376.1479167354; _gat=1; sgt=id=9519gfde_3347_4762_8762_df51458c8ec2; acct=t=why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric&s=why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric\r\n" +
|
||||
"\r\n";
|
||||
|
||||
public static readonly byte[] PlaintextTechEmpowerPipelinedRequests = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat(_plaintextTechEmpowerRequest, Pipelining)));
|
||||
public static readonly byte[] PlaintextTechEmpowerRequest = Encoding.ASCII.GetBytes(_plaintextTechEmpowerRequest);
|
||||
|
||||
public static readonly byte[] LiveaspnetPipelinedRequests = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat(_liveaspnetRequest, Pipelining)));
|
||||
public static readonly byte[] LiveaspnetRequest = Encoding.ASCII.GetBytes(_liveaspnetRequest);
|
||||
|
||||
public static readonly byte[] UnicodePipelinedRequests = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat(_unicodeRequest, Pipelining)));
|
||||
public static readonly byte[] UnicodeRequest = Encoding.ASCII.GetBytes(_unicodeRequest);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue