private bool isRequestComplete() { if (this.m_headers == null) { if (!this.HeadersAvailable()) { return(false); } if (!this.ParseRequestForHeaders()) { string str; if (this.m_requestData != null) { str = Utilities.ByteArrayToHexView(this.m_requestData.GetBuffer(), 0x18, (int)Math.Min(this.m_requestData.Length, 0x800L)); } else { str = "{Web Browser:no data}"; } if (this.m_headers == null) { this.m_headers = new HTTPRequestHeaders(); this.m_headers.HTTPMethod = "BAD"; this.m_headers["Host"] = "BAD-REQUEST"; this.m_headers.RequestPath = "/BAD_REQUEST"; } this.FailSession(400, "Web Browser - Bad Request", "[Web Browser] Request Header parsing failed. Request was:\n" + str); return(true); } this.m_session.Timers.SDVPGotRequestHeaders = DateTime.Now; this.m_session._AssignID(); SDVPApplication.DoRequestHeadersAvailable(this.m_session); } if (this.m_headers.ExistsAndEquals("Transfer-encoding", "chunked")) { long num; long num2; return(Utilities.IsChunkedBodyComplete(this.m_session, this.m_requestData, (long)this.iEntityBodyOffset, out num2, out num)); } if (this.m_headers.Exists("Content-Length")) { long result = 0L; try { if (!long.TryParse(this.m_headers["Content-Length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result) || (result < 0L)) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInRequest, true, true, "Request content length was invalid.\nContent-Length: " + this.m_headers["Content-Length"]); this.FailSession(400, "Web Browser - Bad Request", "[Web Browser] Request Content-Length header parsing failed.\nContent-Length: " + this.m_headers["Content-Length"]); return(true); } return(this.m_requestData.Length >= (this.iEntityBodyOffset + result)); } catch { this.FailSession(400, "Web Browser - Bad Request", "[Web Browser] Unknown error: Check content length header?"); return(false); } } return(true); }
private bool HeadersAvailable() { if (this.iEntityBodyOffset <= 0) { HTTPHeaderParseWarnings warnings; if (this.m_responseData == null) { return(false); } if (!Parser.FindEndOfHeaders(this.m_responseData.GetBuffer(), ref this._iBodySeekProgress, this.m_responseData.Length, out warnings)) { return(false); } this.iEntityBodyOffset = this._iBodySeekProgress + 1; switch (warnings) { case HTTPHeaderParseWarnings.EndedWithLFLF: SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "The Server did not return properly formatted HTTP Headers. HTTP headers\nshould be terminated with CRLFCRLF. These were terminated with LFLF."); break; case HTTPHeaderParseWarnings.EndedWithLFCRLF: SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "The Server did not return properly formatted HTTP Headers. HTTP headers\nshould be terminated with CRLFCRLF. These were terminated with LFCRLF."); break; } } return(true); }
private bool GetHeaders() { if (!this.HeadersAvailable()) { return(false); } if (!this.ParseResponseForHeaders()) { string str; this.m_session.SetBitFlag(SessionFlags.ProtocolViolationInResponse, true); this._PoisonPipe(); if (this.m_responseData != null) { str = "<plaintext>\n" + Utilities.ByteArrayToHexView(this.m_responseData.GetBuffer(), 0x18, (int)Math.Min(this.m_responseData.Length, 0x800L)); } else { str = "{Web Browser:no data}"; } this.m_session.oRequest.FailSession(500, "Web Browser - Bad Response", string.Format("[Web Browser] Response Header parsing failed.\n{0}Response Data:\n{1}", this.m_session.isFlagSet(SessionFlags.ServerPipeReused) ? "This can be caused by an illegal HTTP response earlier on this reused server socket-- for instance, a HTTP/304 response which illegally contains a body.\n" : string.Empty, str)); return(true); } if ((this.m_inHeaders.HTTPResponseCode <= 0x63) || (this.m_inHeaders.HTTPResponseCode >= 200)) { return(true); } if (this.m_inHeaders.Exists("Content-Length") && ("0" != this.m_inHeaders["Content-Length"].Trim())) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "HTTP/1xx responses MUST NOT contain a body, but a non-zero content-length was returned."); } if (SDVPApplication.Prefs.GetBoolPref("SDVP.network.streaming.leakhttp1xx", true) && (this.m_session.oRequest.pipeClient != null)) { try { StringDictionary dictionary; this.m_session.oRequest.pipeClient.Send(this.m_inHeaders.ToByteArray(true, true)); (dictionary = this.m_session.oFlags)["x-SDVP-Stream1xx"] = dictionary["x-SDVP-Stream1xx"] + "Returned a HTTP/" + this.m_inHeaders.HTTPResponseCode.ToString() + " message from the server."; } catch (Exception exception) { if (SDVPApplication.Prefs.GetBoolPref("SDVP.network.streaming.abortifclientaborts", false)) { throw new Exception("Leaking HTTP/1xx response to client failed", exception); } } } else { StringDictionary dictionary2; (dictionary2 = this.m_session.oFlags)["x-SDVP-streaming"] = dictionary2["x-SDVP-streaming"] + "Eating a HTTP/" + this.m_inHeaders.HTTPResponseCode.ToString() + " message from the stream."; } this._deleteInformationalMessage(); return(this.GetHeaders()); }
internal byte[] TakeEntity() { byte[] bytes; if (this.iEntityBodyOffset < 0) { throw new InvalidDataException("Request Entity Body Offset must not be negative"); } long num = this.m_requestData.Length - this.iEntityBodyOffset; long num2 = this._calculateExpectedEntityTransferSize(); if (num > num2) { //SDVPApplication.Log.LogFormat("HTTP Pipelining Client detected; excess data on client socket for session #{0}.", new object[] { this.m_session.id }); try { bytes = new byte[num - num2]; this.m_requestData.Position = this.iEntityBodyOffset + num2; this.m_requestData.Read(bytes, 0, bytes.Length); } catch (OutOfMemoryException exception) { SDVPApplication.ReportException(exception, "HTTP Request Pipeline Too Large"); bytes = Encoding.ASCII.GetBytes("Web Browser: Out of memory"); this.m_session.PoisonClientPipe(); return(new byte[0]); } this.pipeClient.putBackSomeBytes(bytes); num = num2; } if ((num != num2) && (num < num2)) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInRequest, true, true, string.Format("Content-Length mismatch: Request Header indicated {0:N0} bytes, but client sent {1:N0} bytes.", num2, num)); } try { bytes = new byte[num]; this.m_requestData.Position = this.iEntityBodyOffset; this.m_requestData.Read(bytes, 0, bytes.Length); } catch (OutOfMemoryException exception2) { SDVPApplication.ReportException(exception2, "HTTP Request Too Large"); bytes = Encoding.ASCII.GetBytes("Web Browser: Out of memory"); this.m_session.PoisonClientPipe(); } this._freeRequestData(); return(bytes); }
private bool isResponseBodyComplete() { if (this.m_session.HTTPMethodIs("HEAD")) { return(true); } if (this.m_session.HTTPMethodIs("CONNECT") && (this.m_inHeaders.HTTPResponseCode == 200)) { return(true); } if (((this.m_inHeaders.HTTPResponseCode == 0xcc) || (this.m_inHeaders.HTTPResponseCode == 0xcd)) || (this.m_inHeaders.HTTPResponseCode == 0x130)) { if (this.m_inHeaders.Exists("Content-Length") && ("0" != this.m_inHeaders["Content-Length"].Trim())) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "This type of HTTP response MUST NOT contain a body, but a non-zero content-length was returned."); return(true); } return(true); } if (this.m_inHeaders.ExistsAndEquals("Transfer-Encoding", "chunked")) { long num; if (this._lngLastChunkInfoOffset < this.iEntityBodyOffset) { this._lngLastChunkInfoOffset = this.iEntityBodyOffset; } return(Utilities.IsChunkedBodyComplete(this.m_session, this.m_responseData, this._lngLastChunkInfoOffset, out this._lngLastChunkInfoOffset, out num)); } if (this.m_inHeaders.Exists("Content-Length")) { long num2; if (long.TryParse(this.m_inHeaders["Content-Length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out num2) && (num2 >= 0L)) { return(this.m_responseTotalDataCount >= (this.iEntityBodyOffset + num2)); } SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, true, true, "Content-Length response header is not a valid unsigned integer.\nContent-Length: " + this.m_inHeaders["Content-Length"]); return(true); } if ((!this.m_inHeaders.ExistsAndEquals("Connection", "close") && !this.m_inHeaders.ExistsAndEquals("Proxy-Connection", "close")) && ((this.m_inHeaders.HTTPVersion == "HTTP/1.1") || this.m_inHeaders.ExistsAndContains("Connection", "Keep-Alive"))) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, true, true, "No Connection: close, no Content-Length. No way to tell if the response is complete."); } return(false); }
private bool ParseRequestForHeaders() { int num; int num2; int num3; if ((this.m_requestData == null) || (this.iEntityBodyOffset < 4)) { return(false); } this.m_headers = new HTTPRequestHeaders(Browser.oHeaderEncoding); byte[] arrRequest = this.m_requestData.GetBuffer(); Parser.CrackRequestLine(arrRequest, out num2, out num3, out num); if ((num2 < 1) || (num3 < 1)) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInRequest, true, false, "Incorrectly formed Request-Line"); return(false); } this.m_headers.HTTPMethod = Encoding.ASCII.GetString(arrRequest, 0, num2 - 1).ToUpper(); this.m_headers.HTTPVersion = Encoding.ASCII.GetString(arrRequest, (num2 + num3) + 1, ((num - num3) - num2) - 2).Trim().ToUpper(); int num4 = 0; if (arrRequest[num2] != 0x2f) { if (((num3 > 7) && (arrRequest[num2 + 4] == 0x3a)) && ((arrRequest[num2 + 5] == 0x2f) && (arrRequest[num2 + 6] == 0x2f))) { this.m_headers.UriScheme = Encoding.ASCII.GetString(arrRequest, num2, 4); num4 = num2 + 6; num2 += 7; num3 -= 7; } else if (((num3 > 8) && (arrRequest[num2 + 5] == 0x3a)) && ((arrRequest[num2 + 6] == 0x2f) && (arrRequest[num2 + 7] == 0x2f))) { this.m_headers.UriScheme = Encoding.ASCII.GetString(arrRequest, num2, 5); num4 = num2 + 7; num2 += 8; num3 -= 8; } else if (((num3 > 6) && (arrRequest[num2 + 3] == 0x3a)) && ((arrRequest[num2 + 4] == 0x2f) && (arrRequest[num2 + 5] == 0x2f))) { this.m_headers.UriScheme = Encoding.ASCII.GetString(arrRequest, num2, 3); num4 = num2 + 5; num2 += 6; num3 -= 6; } } if (num4 == 0) { if ((this.pipeClient != null) && this.pipeClient.bIsSecured) { this.m_headers.UriScheme = "https"; } else { this.m_headers.UriScheme = "http"; } } if (num4 > 0) { while (((num3 > 0) && (arrRequest[num2] != 0x2f)) && (arrRequest[num2] != 0x3f)) { num2++; num3--; } if (num3 == 0) { num2 = num4; num3 = 1; } int index = num4 + 1; int count = num2 - index; if (count > 0) { this.m_sHostFromURI = Browser.oHeaderEncoding.GetString(arrRequest, index, count); if ((this.m_headers.UriScheme == "ftp") && this.m_sHostFromURI.Contains("@")) { int length = this.m_sHostFromURI.LastIndexOf("@") + 1; this.m_headers._uriUserInfo = this.m_sHostFromURI.Substring(0, length); this.m_sHostFromURI = this.m_sHostFromURI.Substring(length); } } } byte[] dst = new byte[num3]; Buffer.BlockCopy(arrRequest, num2, dst, 0, num3); this.m_headers.RawPath = dst; string str = Browser.oHeaderEncoding.GetString(arrRequest, num, this.iEntityBodyOffset - num).Trim(); arrRequest = null; if (str.Length >= 1) { string[] sHeaderLines = str.Replace("\r\n", "\n").Split(new char[] { '\n' }); string sErrors = string.Empty; if (!Parser.ParseNVPHeaders(this.m_headers, sHeaderLines, 0, ref sErrors)) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInRequest, true, false, "Incorrectly formed request headers.\n" + sErrors); } } return(true); }
internal bool ReadResponse() { int iMaxByteCount = 0; bool flag = false; bool flag2 = false; bool flag3 = false; byte[] arrBuffer = new byte[_cbServerReadBuffer]; do { try { iMaxByteCount = this.pipeServer.Receive(arrBuffer); if (0L == this.m_session.Timers.ServerBeginResponse.Ticks) { this.m_session.Timers.ServerBeginResponse = DateTime.Now; } if (iMaxByteCount <= 0) { flag = true; SDVPApplication.DoReadResponseBuffer(this.m_session, arrBuffer, 0); } else { if (Browser.bDebugSpew) { SDVPApplication.DebugSpew(Utilities.ByteArrayToHexView(arrBuffer, 0x20, iMaxByteCount)); } if (!SDVPApplication.DoReadResponseBuffer(this.m_session, arrBuffer, iMaxByteCount)) { flag2 = true; } this.m_responseData.Write(arrBuffer, 0, iMaxByteCount); this.m_responseTotalDataCount += iMaxByteCount; if ((this.m_inHeaders == null) && this.GetHeaders()) { this.m_session.Timers.SDVPGotResponseHeaders = DateTime.Now; if ((this.m_session.state == SessionStates.Aborted) && this.m_session.isAnyFlagSet(SessionFlags.ProtocolViolationInResponse)) { return(false); } SDVPApplication.DoResponseHeadersAvailable(this.m_session); if (Browser.bStreamAudioVideo) { string str = this.m_inHeaders["Content-Type"]; if ((str.StartsWith("video/", StringComparison.OrdinalIgnoreCase) || str.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) || str.StartsWith("application/x-mms-framed", StringComparison.OrdinalIgnoreCase)) { this.m_session.bBufferResponse = false; } } if (!this.m_session.bBufferResponse) { this.m_session.bBufferResponse = this.m_session.HTTPMethodIs("CONNECT"); } if (!this.m_session.bBufferResponse && (this.m_session.oRequest.pipeClient == null)) { this.m_session.bBufferResponse = true; } if ((!this.m_session.bBufferResponse && ((0x191 == this.m_inHeaders.HTTPResponseCode) || (0x197 == this.m_inHeaders.HTTPResponseCode))) && this.m_session.oFlags.ContainsKey("x-AutoAuth")) { this.m_session.bBufferResponse = true; } this.m_session.SetBitFlag(SessionFlags.ResponseStreamed, !this.m_session.bBufferResponse); if (!this.m_session.bBufferResponse) { if (this.m_session.oFlags.ContainsKey("response-trickle-delay")) { int num2 = int.Parse(this.m_session.oFlags["response-trickle-delay"]); this.m_session.oRequest.pipeClient.TransmitDelay = num2; } if (this.m_session.oFlags.ContainsKey("log-drop-response-body") || SDVPApplication.Prefs.GetBoolPref("SDVP.network.streaming.ForgetStreamedData", false)) { flag3 = true; } } } if ((this.m_inHeaders != null) && this.m_session.isFlagSet(SessionFlags.ResponseStreamed)) { this.LeakResponseBytes(); if (flag3) { this.m_session.SetBitFlag(SessionFlags.ResponseBodyDropped, true); if (this._lngLastChunkInfoOffset > -1L) { this.ReleaseStreamedChunkedData(); } else if (this.m_inHeaders.ExistsAndContains("Transfer-Encoding", "chunked")) { this.ReleaseStreamedChunkedData(); } else { this.ReleaseStreamedData(); } } } } } catch (Exception exception) { flag2 = true; if (exception is OperationCanceledException) { this.m_session.state = SessionStates.Aborted; } else if (exception is OutOfMemoryException) { SDVPApplication.ReportException(exception); this.m_session.state = SessionStates.Aborted; } else { } } }while ((!flag && !flag2) && ((this.m_inHeaders == null) || !this.isResponseBodyComplete())); this.m_session.Timers.ServerDoneResponse = DateTime.Now; if (this.m_session.isFlagSet(SessionFlags.ResponseStreamed)) { this.m_session.Timers.ClientDoneResponse = this.m_session.Timers.ServerDoneResponse; } if ((this.m_responseTotalDataCount == 0L) && (this.m_inHeaders == null)) { flag2 = true; } arrBuffer = null; if (flag2) { this.m_responseData.Dispose(); this.m_responseData = null; return(false); } if (this.m_inHeaders == null) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, true, true, "The Server did not return properly formatted HTTP Headers. Maybe missing altogether (e.g. HTTP/0.9), maybe only \\r\\r instead of \\r\\n\\r\\n?\n"); this.m_session.SetBitFlag(SessionFlags.ResponseStreamed, false); this.m_inHeaders = new HTTPResponseHeaders(Browser.oHeaderEncoding); this.m_inHeaders.HTTPVersion = "HTTP/1.0"; this.m_inHeaders.HTTPResponseCode = 200; this.m_inHeaders.HTTPResponseStatus = "200 This buggy server did not return headers"; this.iEntityBodyOffset = 0; return(true); } return(true); }
private bool ParseResponseForHeaders() { if ((this.m_responseData != null) && (this.iEntityBodyOffset >= 4)) { this.m_inHeaders = new HTTPResponseHeaders(Browser.oHeaderEncoding); byte[] bytes = this.m_responseData.GetBuffer(); string str = Browser.oHeaderEncoding.GetString(bytes, 0, this.iEntityBodyOffset).Trim(); if ((str == null) || (str.Length < 1)) { this.m_inHeaders = null; return(false); } string[] sHeaderLines = str.Replace("\r\n", "\n").Split(new char[] { '\n' }); if (sHeaderLines.Length >= 1) { int index = sHeaderLines[0].IndexOf(' '); if (index > 0) { this.m_inHeaders.HTTPVersion = sHeaderLines[0].Substring(0, index).ToUpper(); sHeaderLines[0] = sHeaderLines[0].Substring(index + 1).Trim(); if (!this.m_inHeaders.HTTPVersion.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase)) { if (!this.m_inHeaders.HTTPVersion.StartsWith("ICY", StringComparison.OrdinalIgnoreCase)) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "Response does not start with HTTP. Data:\n\n\t" + sHeaderLines[0]); return(false); } this.m_session.bBufferResponse = false; this.m_session.oFlags["log-drop-response-body"] = "ICY"; } this.m_inHeaders.HTTPResponseStatus = sHeaderLines[0]; bool flag = false; index = sHeaderLines[0].IndexOf(' '); if (index > 0) { flag = int.TryParse(sHeaderLines[0].Substring(0, index).Trim(), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out this.m_inHeaders.HTTPResponseCode); } else { string s = sHeaderLines[0].Trim(); flag = int.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out this.m_inHeaders.HTTPResponseCode); if (!flag) { for (int i = 0; i < s.Length; i++) { if (!char.IsDigit(s[i])) { flag = int.TryParse(s.Substring(0, i), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out this.m_inHeaders.HTTPResponseCode); if (flag) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, false, "The response's status line was missing a space between ResponseCode and ResponseStatus. Data:\n\n\t" + s); } break; } } } } if (!flag) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "The response's status line did not contain a ResponseCode. Data:\n\n\t" + sHeaderLines[0]); return(false); } string sErrors = string.Empty; if (!Parser.ParseNVPHeaders(this.m_inHeaders, sHeaderLines, 1, ref sErrors)) { SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "Incorrectly formed response headers.\n" + sErrors); } return(true); } SDVPApplication.HandleHTTPError(this.m_session, SessionFlags.ProtocolViolationInResponse, false, true, "Cannot parse HTTP response; Status line contains no spaces. Data:\n\n\t" + sHeaderLines[0]); } } return(false); }