Cuberite
A lightweight, fast and extensible game server for Minecraft
SslHTTPServerConnection.cpp
Go to the documentation of this file.
1 
2 // SslHTTPConnection.cpp
3 
4 // Implements the cSslHTTPServerConnection class representing a HTTP connection made over a SSL link
5 
6 #include "Globals.h"
8 #include "HTTPServer.h"
9 
10 
11 
12 
13 
14 cSslHTTPServerConnection::cSslHTTPServerConnection(cHTTPServer & a_HTTPServer, std::shared_ptr<const cSslConfig> a_Config):
15  super(a_HTTPServer),
16  m_Ssl(64000)
17 {
18  if (a_Config != nullptr)
19  {
20  m_Ssl.Initialize(a_Config);
21  }
22  else
23  {
24  m_Ssl.Initialize(false);
25  }
26 }
27 
28 
29 
30 
31 
33 {
34  m_Ssl.NotifyClose();
35 }
36 
37 
38 
39 
40 
41 void cSslHTTPServerConnection::OnReceivedData(const char * a_Data, size_t a_Size)
42 {
43  // Process the received data:
44  const char * Data = a_Data;
45  size_t Size = a_Size;
46  for (;;)
47  {
48  // Try to write as many bytes into Ssl's "incoming" buffer as possible:
49  size_t BytesWritten = 0;
50  if (Size > 0)
51  {
52  BytesWritten = m_Ssl.WriteIncoming(Data, Size);
53  Data += BytesWritten;
54  Size -= BytesWritten;
55  }
56 
57  // Try to read as many bytes from SSL's decryption as possible:
58  char Buffer[32000];
59  int NumRead = m_Ssl.ReadPlain(Buffer, sizeof(Buffer));
60  if (NumRead > 0)
61  {
62  super::OnReceivedData(Buffer, static_cast<size_t>(NumRead));
63  // The link may have closed while processing the data, bail out:
64  return;
65  }
66  else if (NumRead == MBEDTLS_ERR_SSL_WANT_READ)
67  {
68  // SSL requires us to send data to peer first, do so by "sending" empty data:
69  SendData(nullptr, 0);
70  }
71 
72  // If both failed, bail out:
73  if ((BytesWritten == 0) && (NumRead <= 0))
74  {
75  return;
76  }
77  }
78 }
79 
80 
81 
82 
83 
84 void cSslHTTPServerConnection::SendData(const void * a_Data, size_t a_Size)
85 {
86  const char * OutgoingData = static_cast<const char *>(a_Data);
87  size_t pos = 0;
88  for (;;)
89  {
90  // Write as many bytes from our buffer to SSL's encryption as possible:
91  int NumWritten = 0;
92  if (pos < a_Size)
93  {
94  NumWritten = m_Ssl.WritePlain(OutgoingData + pos, a_Size - pos);
95  if (NumWritten > 0)
96  {
97  pos += static_cast<size_t>(NumWritten);
98  }
99  }
100 
101  // Read as many bytes from SSL's "outgoing" buffer as possible:
102  char Buffer[32000];
103  size_t NumBytes = m_Ssl.ReadOutgoing(Buffer, sizeof(Buffer));
104  if (NumBytes > 0)
105  {
106  m_Link->Send(Buffer, NumBytes);
107  }
108 
109  // If both failed, bail out:
110  if ((NumWritten <= 0) && (NumBytes == 0))
111  {
112  return;
113  }
114  }
115 }
116 
117 
118 
119 
virtual ~cSslHTTPServerConnection() override
size_t WriteIncoming(const void *a_Data, size_t a_NumBytes)
Stores the specified data in the "incoming" buffer, to be process by the SSL decryptor.
virtual void OnReceivedData(const char *a_Data, size_t a_Size) override
Data is received from the client.
cSslHTTPServerConnection(cHTTPServer &a_HTTPServer, std::shared_ptr< const cSslConfig > a_Config)
Creates a new connection on the specified server.
cTCPLinkPtr m_Link
The network link attached to this connection.
size_t ReadOutgoing(void *a_Data, size_t a_DataMaxSize)
Retrieves data from the "outgoing" buffer, after being processed by the SSL encryptor.
virtual void OnReceivedData(const char *a_Data, size_t a_Size) override
Data is received from the client.
virtual void SendData(const void *a_Data, size_t a_Size) override
Called to send raw data over the link.