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