private void binaryHandler(Socket sock) { int maxlen = 1 << 20; // Use a 1MB buffer sock.ReceiveBufferSize = maxlen; byte[] data = new byte[maxlen]; SocketAsyncEventArgs args = new SocketAsyncEventArgs(); do { // Get one request at a time HttpRequest request = new HttpRequest(); int totalread = 0; try { do { // Repetitively read until request is complete if ((totalread + maxlen) > data.Length) { // Enlarge the buffer byte[] newdata = new byte[2 * data.Length]; Array.Copy(data, newdata, data.Length); data = newdata; } args.SetBuffer(data, totalread, data.Length - totalread); // Don't need the return value; we control the buffer. getBytes(sock, maxlen, 120000, args); if (SocketError.Success == args.SocketError) { totalread += args.BytesTransferred; byte[] remainder = request.Continue(data, totalread); // There might be another request, or at least the start of one if (null != remainder) { totalread -= (data.Length - remainder.Length); data = remainder; } else { // No further data, just reset the offset. totalread = 0; } } else { // Some error occurred return; } // Sanity check what we have so far if (HttpVersion.INVALID_VERSION == request.Version) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.HttpVersionNotSupported, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "The protocol version specified in the request is not recognized!\n"); // Send the error report, which will close the connection; we don't care what else the client wanted resp.Send(ConnectionPersistence.CLOSE); return; } if (HttpMethod.INVALID_METHOD == request.Method) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.NotImplemented, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "The request HTTP verb (method) is not recognized!\n", request.Version); // Send the error report, which will close the connection; we don't care what else the client wanted resp.Send(ConnectionPersistence.CLOSE); return; } } while (!request.Complete); // If we get here, this request is complete (might be more in data) servicer(request, sock); } catch (ProtocolViolationException ex) { if (sock.Connected) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.BadRequest, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "Bad request!\n" + ex.ToString()); resp.Send(ConnectionPersistence.CLOSE); } return; } catch (Exception ex) { if (sock.Connected) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.InternalServerError, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "Internal Server Error!\n" + ex.ToString() + '\n' + ex.StackTrace); resp.Send(ConnectionPersistence.CLOSE); } return; } } while (sock.Connected); }
/// <summary> /// Called after the client connection is established. Receives client request. /// </summary> /// <param name="sock">Connected TCP socket communicating with client</param> private void handler(Socket sock) { sock.ReceiveBufferSize = (1 << 20); // Use a 1MB buffer String data = ""; do { // Get one request at a time HttpRequest request = new HttpRequest(); try { do { // We need (more) data String newdata = getString(sock); if (null == newdata) { // The connection was closed gracefully return; } data += newdata; // Update/populate the request using the Continue function data = request.Continue(data); // Sanity-check what we've parsed so far if (HttpVersion.INVALID_VERSION == request.Version) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.HttpVersionNotSupported, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "The protocol version specified in the request is not recognized!\n"); // Send the error report, which will close the connection; we don't care what else the client wanted resp.Send(); return; } if (HttpMethod.INVALID_METHOD == request.Method) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.NotImplemented, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "The request HTTP verb (method) is not recognized!\n", request.Version); // Send the error report, which will close the connection; we don't care what else the client wanted resp.Send(); return; } } while (!request.Complete); // OK *that* request is done now. servicer(request, sock); } catch (ProtocolViolationException ex) { if (sock.Connected) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.BadRequest, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "Bad request!\n" + ex.ToString()); resp.Send(); } return; } catch (Exception ex) { if (sock.Connected) { HttpResponse resp = new HttpResponse( sock, HttpStatusCode.InternalServerError, Utility.CONTENT_TYPES[(int)ResponseType.TEXT_PLAIN], "Internal Server Error!\n" + ex.ToString() + '\n' + ex.StackTrace); resp.Send(); } return; } // But, there might have been more than one request in the last packet } while (sock.Connected); }