/// <inheritdoc/> public override ValueTask <ValueHttpRequest?> CreateNewRequestAsync(HttpPrimitiveVersion version, HttpVersionPolicy versionPolicy, CancellationToken cancellationToken = default) { if (_writeBuffer.ActiveLength != 0 || _responseContentBytesRemaining != 0) { return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception("Unable to create request stream with a request already pending.")))); } if (version.Major != 1) { if (versionPolicy == HttpVersionPolicy.RequestVersionOrLower) { version = HttpPrimitiveVersion.Version11; } return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception($"Unable to create request for HTTP/{version.Major}.{version.Minor} with a {nameof(Http1Connection)}.")))); } _writeState = WriteState.Unstarted; _requestIsChunked = true; _responseHasContentLength = false; _responseIsChunked = false; _readingFirstResponseChunk = false; _readFunc = s_ReadResponse; if (Interlocked.Exchange(ref _request, null) is Http1Request request) { request.Init(this, version); } else { request = new Http1Request(this, version); } return(new ValueTask <ValueHttpRequest?>(request.GetValueRequest())); }
protected internal override ValueTask DisposeAsync(int version, CancellationToken cancellationToken) { Http1Connection connection = _connection; if (connection != null) { if (IsDisposed(version, out ValueTask task)) { return(task); } _connection = null !; _version = null !; Volatile.Write(ref connection._request, this); } return(default);
internal void WriteConnectRequest(ReadOnlySpan <byte> authority, HttpPrimitiveVersion version) { if (_writeState != WriteState.Unstarted) { throw new InvalidOperationException(); } if (authority.Length == 0) { throw new ArgumentException(); } _requestIsChunked = false; int len = GetEncodeConnectRequestLength(authority); _writeBuffer.EnsureAvailableSpace(len); EncodeConnectRequest(authority, version, _writeBuffer.AvailableSpan); _writeBuffer.Commit(len); _writeState = WriteState.RequestWritten; }
internal static unsafe void EncodeConnectRequest(ReadOnlySpan <byte> authority, HttpPrimitiveVersion version, Span <byte> buffer) { Debug.Assert(authority.Length > 0); Debug.Assert(buffer.Length >= GetEncodeConnectRequestLength(authority)); ref byte pBuf = ref MemoryMarshal.GetReference(buffer);
/// <summary> /// Opens a new request on the connection. /// </summary> /// <param name="version">The HTTP version of the request to make.</param> /// <param name="versionPolicy">A policy controlling version selection for the request.</param> /// <param name="cancellationToken">A cancellation token for this operation.</param> /// <returns> /// If a request can be made, a <see cref="HttpRequest"/> instance used to make a single request. /// Otherwise, null to indicate the connection is not accepting new requests. /// </returns> /// <remarks> /// This should return null if the connection has been gracefully closed e.g. connection reset, received GOAWAY, etc. /// </remarks> public abstract ValueTask <ValueHttpRequest?> CreateNewRequestAsync(HttpPrimitiveVersion version, HttpVersionPolicy versionPolicy, CancellationToken cancellationToken = default);
public void Init(Http1Connection connection, HttpPrimitiveVersion version) { Reset(); _connection = connection; _version = version; }
public Http1Request(Http1Connection connection, HttpPrimitiveVersion version) { _connection = connection; _version = version; }