public void Send(Socket socket) { var padding_size = (byte)((8 - (BodyLength % 8)) % 8); CompatArraySegment <byte> header = buffers.EnforceHeaderLength(HeaderSize); header [0] = version; header [1] = (byte)type; header [2] = (byte)(request_id >> 8); header [3] = (byte)(request_id & 0xFF); header [4] = (byte)(BodyLength >> 8); header [5] = (byte)(BodyLength & 0xFF); header [6] = padding_size; CompatArraySegment <byte> padding = buffers.EnforcePaddingLength(padding_size); for (int i = 0; i < padding_size; i++) { padding [i] = 0; } Logger.Write(LogLevel.Debug, Strings.Record_Sent, Type, RequestID, BodyLength); NRecord.SendAll(socket, header, HeaderSize); NRecord.SendAll(socket, buffers.Body, BodyLength); NRecord.SendAll(socket, padding, padding_size); }
internal void AddFileData(NRecord record) { // Validate arguments in public methods. if (record.Type != RecordType.Data) { throw new ArgumentException( Strings.Request_NotFileData, "record"); } // There should be no data following a zero byte record. if (file_data_completed) { Logger.Write(LogLevel.Warning, Strings.Request_FileDataAlreadyCompleted); return; } if (record.BodyLength == 0) { file_data_completed = true; } // Inform listeners of the data. if (FileDataReceived != null) { FileDataReceived(this, new DataReceivedArgs(record)); } }
public void EndRequest(ushort requestID, int appStatus, ProtocolStatus protocolStatus) { var body = new EndRequestBody(appStatus, protocolStatus); try { if (IsConnected) { byte[] bodyData = body.GetData(); CompatArraySegment <byte> bodyBuffer = send_buffers.EnforceBodyLength(bodyData.Length); Array.Copy(bodyData, 0, bodyBuffer.Array, bodyBuffer.Offset, bodyData.Length); var record = new NRecord(1, RecordType.EndRequest, requestID, bodyData.Length, send_buffers); record.Send(socket); } } catch (System.Net.Sockets.SocketException) { } RemoveRequest(requestID); lock (connection_teardown_lock) { if (requests.Count == 0 && (!keep_alive || stop)) { CloseSocket(); if (!stop) { server.EndConnection(this); } receive_buffers.Return(); send_buffers.Return(); } } }
void HandleStandardInput(Request request, NRecord record) { if (request == null) { StopRun(Strings.Connection_RequestDoesNotExist, record.RequestID); return; } request.AddInputData(record); }
public void Run() { Logger.Write(LogLevel.Debug, Strings.Connection_BeginningRun); if (socket == null) { Logger.Write(LogLevel.Notice, Strings.Connection_NoSocketInRun); return; } do { NRecord record; try { record = NRecord.Receive(socket, receive_buffers); } catch (System.Net.Sockets.SocketException) { StopRun(Strings.Connection_RecordNotReceived); Stop(); break; } Request request = GetRequest(record.RequestID); try { if (RequestReceived != null) { RequestReceived.BeginInvoke(this, EventArgs.Empty, null, null); } } catch (Exception e) { // We don't care if the event handler has problems Logger.Write(LogLevel.Error, "Error while invoking RequestReceived event:"); Logger.Write(e); } Logger.Write(LogLevel.Debug, "Now handling record (with type {0})", record.Type); HandleRequest(record, request); }while (!stop && (UnfinishedRequests || keep_alive)); if (requests.Count == 0) { lock (connection_teardown_lock) { CloseSocket(); if (!stop) { server.EndConnection(this); } send_buffers.Return(); receive_buffers.Return(); } } Logger.Write(LogLevel.Debug, Strings.Connection_EndingRun); }
void HandleBeginRequest(Request request, NRecord record) { // If a request with the given ID // already exists, there's a bug in the // client. Abort. if (request != null) { StopRun(Strings.Connection_RequestAlreadyExists); return; } // If there are unfinished requests // and multiplexing is disabled, inform // the client and don't begin the // request. if (!server.MultiplexConnections && UnfinishedRequests) { EndRequest(record.RequestID, 0, ProtocolStatus.CantMultiplexConnections); return; } // If the maximum number of requests is // reached, inform the client and don't // begin the request. if (!server.CanRequest) { EndRequest(record.RequestID, 0, ProtocolStatus.Overloaded); return; } var body = new BeginRequestBody(record); // If the role is "Responder", and it is // supported, create a ResponderRequest. if (body.Role == Role.Responder && server.SupportsResponder) { request = new ResponderRequest(record.RequestID, this); } else { // If the role is not supported inform the client // and don't begin the request. Logger.Write(LogLevel.Warning, Strings.Connection_RoleNotSupported, body.Role); EndRequest(record.RequestID, 0, ProtocolStatus.UnknownRole); return; } lock (request_lock) { requests.Add(request); } keep_alive = (body.Flags & BeginRequestFlags.KeepAlive) != 0; }
void HandleParams(Request request, NRecord record) { if (request == null) { StopRun(Strings.Connection_RequestDoesNotExist, record.RequestID); return; } IReadOnlyList <byte> body = record.GetBody(); request.AddParameterData(body); }
internal BeginRequestBody (NRecord record) { if (record.Type != RecordType.BeginRequest) throw new ArgumentException ( Strings.BeginRequestBody_WrongType, "record"); if (record.BodyLength != 8) throw new ArgumentException ( String.Format(Strings.BeginRequestBody_WrongSize, record.BodyLength), "record"); IReadOnlyList<byte> body = record.GetBody (); role = NRecord.ReadRole (body); flags = (BeginRequestFlags) body [2]; }
void HandleGetValues(NRecord record) { byte[] response_data; // Look up the data from the server. try { IReadOnlyList <byte> body = record.GetBody(); IDictionary <string, string> pairs_in = NameValuePair.FromData(body); IDictionary <string, string> pairs_out = server.GetValues(pairs_in.Keys); response_data = NameValuePair.GetData(pairs_out); } catch { response_data = new byte[0]; } SendRecord(RecordType.GetValuesResult, record.RequestID, response_data); }
public void SendRecord(RecordType type, ushort requestID, byte [] bodyData, int bodyIndex, int bodyLength) { if (IsConnected) { lock (send_lock) { try { CompatArraySegment <byte> body = send_buffers.EnforceBodyLength(bodyLength); Array.Copy(bodyData, bodyIndex, body.Array, body.Offset, bodyLength); var record = new NRecord(1, type, requestID, bodyLength, send_buffers); record.Send(socket); } catch (System.Net.Sockets.SocketException) { } } } }
internal BeginRequestBody(NRecord record) { if (record.Type != RecordType.BeginRequest) { throw new ArgumentException( Strings.BeginRequestBody_WrongType, "record"); } if (record.BodyLength != 8) { throw new ArgumentException( String.Format(Strings.BeginRequestBody_WrongSize, record.BodyLength), "record"); } IReadOnlyList <byte> body = record.GetBody(); role = NRecord.ReadRole(body); flags = (BeginRequestFlags)body [2]; }
void HandleRequest(NRecord record, Request request) { switch (record.Type) { // Creates a new request. case RecordType.BeginRequest: HandleBeginRequest(request, record); break; // Gets server values. case RecordType.GetValues: HandleGetValues(record); break; // Sends params to the request. case RecordType.Params: HandleParams(request, record); break; // Sends standard input to the request. case RecordType.StandardInput: HandleStandardInput(request, record); break; // Sends file data to the request. case RecordType.Data: HandleData(request, record); break; // Aborts a request when the server aborts. case RecordType.AbortRequest: HandleAbortRequest(request); break; // Informs the client that the record type is // unknown. default: HandleUnknown(record); break; } }
public Record(Socket socket, Buffers receive_buffer) : this() { if (socket == null) { throw new ArgumentNullException("socket"); } CompatArraySegment <byte> header_buffer = receive_buffer.EnforceHeaderLength(HeaderSize); // Read the 8 byte record header. NRecord.ReceiveAll(socket, header_buffer, HeaderSize); // Read the values from the data. version = header_buffer [0]; type = (RecordType)header_buffer [1]; request_id = NRecord.ReadUInt16(header_buffer, 2); BodyLength = NRecord.ReadUInt16(header_buffer, 4); byte padding_length = header_buffer [6]; CompatArraySegment <byte> body_buffer = receive_buffer.EnforceBodyLength(BodyLength); // Read the record data, and throw an exception if the // complete data cannot be read. if (BodyLength > 0) { NRecord.ReceiveAll(socket, body_buffer, BodyLength); } CompatArraySegment <byte> padding_buffer = receive_buffer.EnforcePaddingLength(padding_length); if (padding_length > 0) { NRecord.ReceiveAll(socket, padding_buffer, padding_length); } buffers = receive_buffer; Logger.Write(LogLevel.Debug, Strings.Record_Received, Type, RequestID, BodyLength); }
void HandleBeginRequest (Request request, NRecord record) { // If a request with the given ID // already exists, there's a bug in the // client. Abort. if (request != null) { StopRun (Strings.Connection_RequestAlreadyExists); return; } // If there are unfinished requests // and multiplexing is disabled, inform // the client and don't begin the // request. if (!server.MultiplexConnections && UnfinishedRequests) { EndRequest (record.RequestID, 0, ProtocolStatus.CantMultiplexConnections); return; } // If the maximum number of requests is // reached, inform the client and don't // begin the request. if (!server.CanRequest) { EndRequest (record.RequestID, 0, ProtocolStatus.Overloaded); return; } var body = new BeginRequestBody (record); // If the role is "Responder", and it is // supported, create a ResponderRequest. if (body.Role == Role.Responder && server.SupportsResponder) request = new ResponderRequest(record.RequestID, this); else { // If the role is not supported inform the client // and don't begin the request. Logger.Write (LogLevel.Warning, Strings.Connection_RoleNotSupported, body.Role); EndRequest (record.RequestID, 0, ProtocolStatus.UnknownRole); return; } lock (request_lock) { requests.Add (request); } keep_alive = (body.Flags & BeginRequestFlags.KeepAlive) != 0; }
void HandleParams (Request request, NRecord record) { if (request == null) { StopRun (Strings.Connection_RequestDoesNotExist, record.RequestID); return; } IReadOnlyList<byte> body = record.GetBody (); request.AddParameterData (body); }
void HandleGetValues (NRecord record) { byte[] response_data; // Look up the data from the server. try { IReadOnlyList<byte> body = record.GetBody (); IDictionary<string, string> pairs_in = NameValuePair.FromData (body); IDictionary<string, string> pairs_out = server.GetValues (pairs_in.Keys); response_data = NameValuePair.GetData (pairs_out); } catch { response_data = new byte[0]; } SendRecord (RecordType.GetValuesResult, record.RequestID, response_data); }
void HandleUnknown (NRecord record) { Logger.Write (LogLevel.Warning, Strings.Connection_UnknownRecordType, record.Type); SendRecord (RecordType.UnknownType, record.RequestID, new UnknownTypeBody (record.Type).GetData ()); }
void HandleStandardInput (Request request, NRecord record) { if (request == null) { StopRun (Strings.Connection_RequestDoesNotExist, record.RequestID); return; } request.AddInputData (record); }
void HandleUnknown(NRecord record) { Logger.Write(LogLevel.Warning, Strings.Connection_UnknownRecordType, record.Type); SendRecord(RecordType.UnknownType, record.RequestID, new UnknownTypeBody(record.Type).GetData()); }
void HandleRequest (NRecord record, Request request) { switch (record.Type) { // Creates a new request. case RecordType.BeginRequest: HandleBeginRequest (request, record); break; // Gets server values. case RecordType.GetValues: HandleGetValues (record); break; // Sends params to the request. case RecordType.Params: HandleParams (request, record); break; // Sends standard input to the request. case RecordType.StandardInput: HandleStandardInput (request, record); break; // Sends file data to the request. case RecordType.Data: HandleData (request, record); break; // Aborts a request when the server aborts. case RecordType.AbortRequest: HandleAbortRequest (request); break; // Informs the client that the record type is // unknown. default: HandleUnknown (record); break; } }
public DataReceivedArgs(Record record) { this.record = (NRecord)record; }
public void SendRecord (RecordType type, ushort requestID, byte [] bodyData, int bodyIndex, int bodyLength) { if (IsConnected) lock (send_lock) { try { CompatArraySegment<byte> body = send_buffers.EnforceBodyLength(bodyLength); Array.Copy(bodyData, bodyIndex, body.Array, body.Offset, bodyLength); var record = new NRecord (1, type, requestID, bodyLength, send_buffers); record.Send (socket); } catch (System.Net.Sockets.SocketException) { } } }
internal void AddFileData (NRecord record) { // Validate arguments in public methods. if (record.Type != RecordType.Data) throw new ArgumentException ( Strings.Request_NotFileData, "record"); // There should be no data following a zero byte record. if (file_data_completed) { Logger.Write (LogLevel.Warning, Strings.Request_FileDataAlreadyCompleted); return; } if (record.BodyLength == 0) file_data_completed = true; // Inform listeners of the data. if (FileDataReceived != null) FileDataReceived (this, new DataReceivedArgs (record)); }
internal DataReceivedArgs(NRecord record) { this.record = record; }
public DataReceivedArgs (Record record) { this.record = (NRecord)record; }
public void EndRequest (ushort requestID, int appStatus, ProtocolStatus protocolStatus) { var body = new EndRequestBody (appStatus, protocolStatus); try { if (IsConnected) { byte[] bodyData = body.GetData (); CompatArraySegment<byte> bodyBuffer = send_buffers.EnforceBodyLength(bodyData.Length); Array.Copy(bodyData, 0, bodyBuffer.Array, bodyBuffer.Offset, bodyData.Length); var record = new NRecord (1, RecordType.EndRequest, requestID, bodyData.Length, send_buffers); record.Send (socket); } } catch (System.Net.Sockets.SocketException) { } RemoveRequest(requestID); lock (connection_teardown_lock) { if (requests.Count == 0 && (!keep_alive || stop)) { CloseSocket (); if (!stop) server.EndConnection (this); receive_buffers.Return (); send_buffers.Return (); } } }