예제 #1
0
파일: Record.cs 프로젝트: zofuthan/xsp
        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);
        }
예제 #2
0
파일: Request.cs 프로젝트: zofuthan/xsp
        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));
            }
        }
예제 #3
0
        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();
                }
            }
        }
예제 #4
0
        void HandleStandardInput(Request request, NRecord record)
        {
            if (request == null)
            {
                StopRun(Strings.Connection_RequestDoesNotExist, record.RequestID);
                return;
            }

            request.AddInputData(record);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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;
        }
예제 #7
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);
        }
예제 #8
0
		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];
		}
예제 #9
0
        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);
        }
예제 #10
0
 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) {
             }
         }
     }
 }
예제 #11
0
        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];
        }
예제 #12
0
        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;
            }
        }
예제 #13
0
파일: Record.cs 프로젝트: zofuthan/xsp
        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);
        }
예제 #14
0
		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;
		}
예제 #15
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);
		}
예제 #16
0
		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);
		}
예제 #17
0
		void HandleUnknown (NRecord record)
		{
			Logger.Write (LogLevel.Warning, Strings.Connection_UnknownRecordType, record.Type);
			SendRecord (RecordType.UnknownType, record.RequestID, new UnknownTypeBody (record.Type).GetData ());
		}
예제 #18
0
		void HandleStandardInput (Request request, NRecord record)
		{
			if (request == null) {
				StopRun (Strings.Connection_RequestDoesNotExist, record.RequestID);
				return;
			}

			request.AddInputData (record);
		}
예제 #19
0
 void HandleUnknown(NRecord record)
 {
     Logger.Write(LogLevel.Warning, Strings.Connection_UnknownRecordType, record.Type);
     SendRecord(RecordType.UnknownType, record.RequestID, new UnknownTypeBody(record.Type).GetData());
 }
예제 #20
0
		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;
			}
		}
예제 #21
0
파일: Request.cs 프로젝트: zofuthan/xsp
 public DataReceivedArgs(Record record)
 {
     this.record = (NRecord)record;
 }
예제 #22
0
		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) {
					}
				}
		}
예제 #23
0
		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));
		}
예제 #24
0
		internal DataReceivedArgs(NRecord record)
		{
			this.record = record;
		}
예제 #25
0
		public DataReceivedArgs (Record record)
		{
			this.record = (NRecord)record;
		}
예제 #26
0
		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 ();
				}
			}
		}
예제 #27
0
파일: Request.cs 프로젝트: zofuthan/xsp
 internal DataReceivedArgs(NRecord record)
 {
     this.record = record;
 }