private void HandleHttp2(Http2Connection http2Connection, string remoteAddr, bool isSsl, X509Certificate remoteCertificate) { http2Connection.Run((ht2stream) => { HttpRequest req; try { req = new Http2Request(ht2stream, remoteAddr, m_IsBehindProxy, isSsl, remoteCertificate); } catch (Http2Connection.StreamErrorException) { /* ignore */ return; } catch (HttpResponse.ConnectionCloseException) { /* ignore */ return; } catch (HttpStream.TimeoutException) { /* ignore */ return; } ThreadPool.UnsafeQueueUserWorkItem(HandleHttp2WorkItem, req); }); }
private void AcceptedConnection_Internal(Stream httpstream, string remoteAddr, bool isSsl, X509Certificate remoteCertificate) { Interlocked.Increment(ref m_AcceptedConnectionsCount); try { AddThread(Thread.CurrentThread); while (true) { HttpRequest req; try { req = new Http1Request(httpstream, remoteAddr, m_IsBehindProxy, isSsl, remoteCertificate); } catch (HttpResponse.ConnectionCloseException) { return; } catch (HttpStream.TimeoutException) { return; } catch (TimeoutException) { return; } catch (IOException) { return; } catch (InvalidDataException) { return; } catch (ObjectDisposedException) { return; } catch (SocketException) { return; } catch (Exception e) { m_Log.WarnFormat("Unexpected exception: {0}: {1}\n{2}", e.GetType().FullName, e.Message, e.StackTrace); return; } /* Recognition for HTTP/2.0 connection */ if (req.Method == "PRI") { if (req.MajorVersion != 2 || req.MinorVersion != 0) { req.SetConnectionClose(); req.ErrorResponse(HttpStatusCode.BadRequest, "Bad Request"); } else { X509Certificate cert = req.RemoteCertificate; req = null; /* no need for the initial request data */ HandleHttp2(new Http2Connection(httpstream, true), remoteAddr, isSsl, cert); } return; } else if (req.IsH2CUpgradable || req.IsH2CUpgradableAfterReadingBody) { Stream upgradeStream = null; if (req.IsH2CUpgradableAfterReadingBody) { upgradeStream = new MemoryStream(); req.Body.CopyTo(upgradeStream); upgradeStream.Seek(0, SeekOrigin.Begin); } httpstream.Write(m_H2cUpgrade, 0, m_H2cUpgrade.Length); byte[] settingsdata = FromUriBase64(req["http2-settings"]); var preface_receive = new byte[24]; if (24 != httpstream.Read(preface_receive, 0, 24)) { httpstream.Write(m_H2cGoAwayProtocolError, 0, m_H2cGoAwayProtocolError.Length); httpstream.Close(); upgradeStream?.Dispose(); return; } if (!preface_receive.SequenceEqual(m_H2cClientPreface)) { httpstream.Write(m_H2cGoAwayProtocolError, 0, m_H2cGoAwayProtocolError.Length); httpstream.Close(); upgradeStream?.Dispose(); return; } var h2con = new Http2Connection(httpstream, true); Http2Connection.Http2Stream h2stream = h2con.UpgradeStream(settingsdata, !req.IsH2CUpgradableAfterReadingBody && req.Expect100Continue); req = new Http2Request(h2stream, req.CallerIP, m_IsBehindProxy, isSsl, req.RemoteCertificate, req, upgradeStream); ThreadPool.UnsafeQueueUserWorkItem(HandleHttp2WorkItem, req); HandleHttp2(h2con, remoteAddr, isSsl, req.RemoteCertificate); return; } ProcessHttpRequest(req); } } catch (HttpStream.TimeoutException) { /* ignore */ } catch (Http2Connection.ConnectionClosedException) { /* HTTP/2 connection closed */ } catch (Http2Connection.ProtocolErrorException #if DEBUG e #endif ) { /* HTTP/2 protocol errors */ #if DEBUG m_Log.Debug("HTTP/2 Protocol Exception: ", e); #endif } catch (HttpResponse.DisconnectFromThreadException) { /* we simply disconnected that HttpRequest from HttpServer */ throw; } catch (HttpResponse.ConnectionCloseException) { /* simply a closed connection */ } catch (IOException) { /* commonly a broken pipe */ } catch (SocketException) { /* commonly a broken pipe */ } catch (ObjectDisposedException) { /* commonly a broken pipe */ } catch (Exception e) { m_Log.DebugFormat("Exception: {0}: {1}\n{2}", e.GetType().Name, e.Message, e.StackTrace); } finally { RemoveThread(Thread.CurrentThread); } }
public RequestBodyStream(Http2Request req) { m_Req = req; }