static string FormatHeaders(WebHeaderCollection headers) { var sb = new StringBuilder(); for (int i = 0; i < headers.Count; i++) { string key = headers.GetKey(i); if (WebHeaderCollection.AllowMultiValues(key)) { foreach (string v in headers.GetValues(i)) { sb.Append(key).Append(": ").Append(v).Append("\r\n"); } } else { sb.Append(key).Append(": ").Append(headers.Get(i)).Append("\r\n"); } } return(sb.Append("\r\n").ToString()); }
bool GetResponse(BufferOffsetSize buffer, ref int pos, ref ReadState state) { string line = null; bool lineok = false; bool isContinue = false; bool emptyFirstLine = false; do { if (state == ReadState.Aborted) { throw GetReadException(WebExceptionStatus.RequestCanceled, null, "GetResponse"); } if (state == ReadState.None) { lineok = WebConnection.ReadLine(buffer.Buffer, ref pos, buffer.Offset, ref line); if (!lineok) { return(false); } if (line == null) { emptyFirstLine = true; continue; } emptyFirstLine = false; state = ReadState.Status; string[] parts = line.Split(' '); if (parts.Length < 2) { throw GetReadException(WebExceptionStatus.ServerProtocolViolation, null, "GetResponse"); } if (String.Compare(parts[0], "HTTP/1.1", true) == 0) { Version = HttpVersion.Version11; ServicePoint.SetVersion(HttpVersion.Version11); } else { Version = HttpVersion.Version10; ServicePoint.SetVersion(HttpVersion.Version10); } StatusCode = (HttpStatusCode)UInt32.Parse(parts[1]); if (parts.Length >= 3) { StatusDescription = String.Join(" ", parts, 2, parts.Length - 2); } else { StatusDescription = string.Empty; } if (pos >= buffer.Offset) { return(true); } } emptyFirstLine = false; if (state == ReadState.Status) { state = ReadState.Headers; Headers = new WebHeaderCollection(); var headerList = new List <string> (); bool finished = false; while (!finished) { if (WebConnection.ReadLine(buffer.Buffer, ref pos, buffer.Offset, ref line) == false) { break; } if (line == null) { // Empty line: end of headers finished = true; continue; } if (line.Length > 0 && (line[0] == ' ' || line[0] == '\t')) { int count = headerList.Count - 1; if (count < 0) { break; } string prev = headerList[count] + line; headerList[count] = prev; } else { headerList.Add(line); } } if (!finished) { return(false); } // .NET uses ParseHeaders or ParseHeadersStrict which is much better foreach (string s in headerList) { int pos_s = s.IndexOf(':'); if (pos_s == -1) { throw new ArgumentException("no colon found", "header"); } var header = s.Substring(0, pos_s); var value = s.Substring(pos_s + 1).Trim(); if (WebHeaderCollection.AllowMultiValues(header)) { Headers.AddInternal(header, value); } else { Headers.SetInternal(header, value); } } if (StatusCode == HttpStatusCode.Continue) { ServicePoint.SendContinue = true; if (pos >= buffer.Offset) { return(true); } if (Request.ExpectContinue) { Request.DoContinueDelegate((int)StatusCode, Headers); // Prevent double calls when getting the // headers in several packets. Request.ExpectContinue = false; } state = ReadState.None; isContinue = true; } else { state = ReadState.Content; return(true); } } } while (emptyFirstLine || isContinue); throw GetReadException(WebExceptionStatus.ServerProtocolViolation, null, "GetResponse"); }
static int GetResponse(WebConnectionData data, ServicePoint sPoint, byte [] buffer, int max) { int pos = 0; string line = null; bool lineok = false; bool isContinue = false; bool emptyFirstLine = false; do { if (data.ReadState == ReadState.Aborted) { return(-1); } if (data.ReadState == ReadState.None) { lineok = ReadLine(buffer, ref pos, max, ref line); if (!lineok) { return(0); } if (line == null) { emptyFirstLine = true; continue; } emptyFirstLine = false; data.ReadState = ReadState.Status; string [] parts = line.Split(' '); if (parts.Length < 2) { return(-1); } if (String.Compare(parts [0], "HTTP/1.1", true) == 0) { data.Version = HttpVersion.Version11; sPoint.SetVersion(HttpVersion.Version11); } else { data.Version = HttpVersion.Version10; sPoint.SetVersion(HttpVersion.Version10); } data.StatusCode = (int)UInt32.Parse(parts [1]); if (parts.Length >= 3) { data.StatusDescription = String.Join(" ", parts, 2, parts.Length - 2); } else { data.StatusDescription = ""; } if (pos >= max) { return(pos); } } emptyFirstLine = false; if (data.ReadState == ReadState.Status) { data.ReadState = ReadState.Headers; data.Headers = new WebHeaderCollection(); ArrayList headers = new ArrayList(); bool finished = false; while (!finished) { if (ReadLine(buffer, ref pos, max, ref line) == false) { break; } if (line == null) { // Empty line: end of headers finished = true; continue; } if (line.Length > 0 && (line [0] == ' ' || line [0] == '\t')) { int count = headers.Count - 1; if (count < 0) { break; } string prev = (string)headers [count] + line; headers [count] = prev; } else { headers.Add(line); } } if (!finished) { return(0); } // .NET uses ParseHeaders or ParseHeadersStrict which is much better foreach (string s in headers) { int pos_s = s.IndexOf(':'); if (pos_s == -1) { throw new ArgumentException("no colon found", "header"); } var header = s.Substring(0, pos_s); var value = s.Substring(pos_s + 1).Trim(); var h = data.Headers; if (WebHeaderCollection.AllowMultiValues(header)) { h.AddInternal(header, value); } else { h.SetInternal(header, value); } } if (data.StatusCode == (int)HttpStatusCode.Continue) { sPoint.SendContinue = true; if (pos >= max) { return(pos); } if (data.request.ExpectContinue) { data.request.DoContinueDelegate(data.StatusCode, data.Headers); // Prevent double calls when getting the // headers in several packets. data.request.ExpectContinue = false; } data.ReadState = ReadState.None; isContinue = true; } else { data.ReadState = ReadState.Content; return(pos); } } } while (emptyFirstLine || isContinue); return(-1); }