public EndRequestRecord GetEndRequestRecord(int appStatus, byte protocolStatus) { FastCGIHeader header = new FastCGIHeader(); header.RequestId = Request.BeginRequestRecord.Header.RequestId; header.Type = FastCGIHeader.TYPE.END_REQUEST; header.Version = Request.BeginRequestRecord.Header.Version; header.ContentLength = EndRequestBody.LENGTH; header.PaddingLength = 0; header.Reserved = 0; EndRequestBody body = new EndRequestBody(); body.AppStatus = appStatus; body.ProtocolStatus = protocolStatus; return new EndRequestRecord() { Headr = header, Body = body }; }
private int TranslateRemainingData(byte[] buffer, int offset, int length, int replaceOffset) { List<byte> stdinData = new List<byte> (); int endOffset = offset + length; while (offset < endOffset) { if (!_stdinHeader.HasValue) { FastCGIHeader header = new FastCGIHeader (buffer, offset); offset += FastCGIHeader.LENGTH; if (header.RequestId != 0) { if (header.Type == FastCGIHeader.TYPE.STDIN) { _stdinHeader = header; } else if (header.Type == FastCGIHeader.TYPE.ABORT_REQUEST) { AbortRequest = true; } } } if (_stdinHeader.HasValue) { if (_stdinHeader.Value.ContentLength == 0) { // empty stdin = last stdin = endofrequest EndOfRequest = true; break; } else if (_stdinHeader.Value.RequestId != 0 && endOffset > offset) { int contentLength = Math.Min (_stdinHeader.Value.ContentLength - _stdinDataReceivedLength, endOffset - offset); if (contentLength > 0) { for (int i = offset; i < offset + contentLength; i++) { buffer [replaceOffset] = buffer [i]; replaceOffset += 1; } offset += contentLength; _stdinDataReceivedLength += contentLength; } else { // empty stdin = last stdin = endofrequest EndOfRequest = true; break; } if (_stdinDataReceivedLength == _stdinHeader.Value.ContentLength) { offset += _stdinHeader.Value.PaddingLength; _stdinHeader = null; _stdinDataReceivedLength = 0; } } } } return replaceOffset; }
public int ParseRequest(byte[] buffer, int offset, int length) { int endOffset = offset + length; while (offset < endOffset) { FastCGIHeader header = new FastCGIHeader(buffer, offset); if (header.RequestId != 0) { if (Request == null) Request = new FastCGIRequest(); offset += FastCGIHeader.LENGTH; if (header.Type == FastCGIHeader.TYPE.BEGIN_REQUEST) { Request.BeginRequestRecord = new BeginRequestRecord() { Header = header, Body = new BeginRequestBody(buffer, offset) }; offset += header.ContentLength; } else if (header.Type == FastCGIHeader.TYPE.PARAMS) { offset = Request.ParseParams(header, buffer, offset, endOffset); } else { offset -= FastCGIHeader.LENGTH; break; } offset += header.PaddingLength; } } #if DEBUG Log(); #endif return offset; }
public byte[] TranslateToFCGIResponse(byte[] responseData) { // int paddingLength = (int)Math.Ceiling(responseData.Length / 8.0) * 8 - responseData.Length; // byte[] fcgiRespData = new byte[FastCGIHeader.LENGTH + responseData.Length + paddingLength + FastCGIHeader.LENGTH + EndRequestBody.LENGTH]; int maxChunkLength = ushort.MaxValue - 8; int lastChunkLength; int chuncksCount = Math.DivRem(responseData.Length, maxChunkLength, out lastChunkLength) + 1; int padding = 8 - (lastChunkLength % 8); if (padding == 8) padding = 0; byte[] fcgiRespData = new byte[(chuncksCount - 1) * (maxChunkLength + FastCGIHeader.LENGTH) + FastCGIHeader.LENGTH + lastChunkLength + padding + FastCGIHeader.LENGTH + EndRequestBody.LENGTH]; for (int i=0; i<chuncksCount; i++) { int contentLength = i == chuncksCount - 1 ? lastChunkLength : maxChunkLength; int paddingLength = i == chuncksCount - 1 ? padding : 0; FastCGIHeader stdoutHeader = new FastCGIHeader (); stdoutHeader.RequestId = Request.BeginRequestRecord.Header.RequestId; stdoutHeader.Type = FastCGIHeader.TYPE.STDOUT; stdoutHeader.Version = Request.BeginRequestRecord.Header.Version; stdoutHeader.ContentLength = (ushort)contentLength; stdoutHeader.PaddingLength = (byte)paddingLength; stdoutHeader.Reserved = 0; // copy stdout header stdoutHeader.CopyBytesTo (fcgiRespData, i * (FastCGIHeader.LENGTH + maxChunkLength)); // copy stdout body Array.Copy (responseData, i * maxChunkLength, fcgiRespData, i * (FastCGIHeader.LENGTH + maxChunkLength) + FastCGIHeader.LENGTH, contentLength); } // copy endrequest record header & body int endReqRecOffset = fcgiRespData.Length - (FastCGIHeader.LENGTH + EndRequestBody.LENGTH); GetEndRequestRecord(0, EndRequestBody.PROTOCOL_STATUS.FCGI_REQUEST_COMPLETE) .CopyBytesTo(fcgiRespData, endReqRecOffset); return fcgiRespData; }
public int ParseParams(FastCGIHeader paramsHeader, byte[] buffer, int offset, int endOffset) { if (paramsHeader.ContentLength > 0) { int paramsEndOffset = Math.Min(offset + paramsHeader.ContentLength, endOffset); while (offset < paramsEndOffset) { FastCGIParam param = new FastCGIParam(buffer, offset); Params.Add(param.Name, param); offset = param.ParamEndOffset; } } return offset; }