public Add ( HttpRequestHeader header, string value ) : void | ||
header | HttpRequestHeader |
/// One of the |
value | string |
/// A |
return | void |
public static ResponseHandshake Parse(string[] response) { var statusLine = response[0].Split(' '); if (statusLine.Length < 3) throw new ArgumentException("Invalid status line."); var reason = new StringBuilder(statusLine[2]); for (int i = 3; i < statusLine.Length; i++) reason.AppendFormat(" {0}", statusLine[i]); var headers = new WebHeaderCollection(); for (int i = 1; i < response.Length; i++) headers.Add(response[i]); return new ResponseHandshake { Headers = headers, Reason = reason.ToString(), StatusCode = statusLine[1], ProtocolVersion = new Version(statusLine[0].Substring(5)) }; }
internal WebHeaderCollection WriteHeadersTo(MemoryStream destination) { var headers = new WebHeaderCollection(HttpHeaderType.Response, true); if (_headers != null) { headers.Add(_headers); } if (_contentType != null) { var type = _contentType.IndexOf("charset=", StringComparison.Ordinal) == -1 && _contentEncoding != null ? String.Format("{0}; charset={1}", _contentType, _contentEncoding.WebName) : _contentType; headers.InternalSet("Content-Type", type, true); } if (headers["Server"] == null) { headers.InternalSet("Server", "websocket-sharp/1.0", true); } var prov = CultureInfo.InvariantCulture; if (headers["Date"] == null) { headers.InternalSet("Date", DateTime.UtcNow.ToString("r", prov), true); } if (!_sendChunked) { headers.InternalSet("Content-Length", _contentLength.ToString(prov), true); } else { headers.InternalSet("Transfer-Encoding", "chunked", true); } /* * Apache forces closing the connection for these status codes: * - 400 Bad Request * - 408 Request Timeout * - 411 Length Required * - 413 Request Entity Too Large * - 414 Request-Uri Too Long * - 500 Internal Server Error * - 503 Service Unavailable */ var closeConn = !_context.Request.KeepAlive || !_keepAlive || _statusCode == 400 || _statusCode == 408 || _statusCode == 411 || _statusCode == 413 || _statusCode == 414 || _statusCode == 500 || _statusCode == 503; var reuses = _context.Connection.Reuses; if (closeConn || reuses >= 100) { headers.InternalSet("Connection", "close", true); } else { headers.InternalSet( "Keep-Alive", String.Format("timeout=15,max={0}", 100 - reuses), true); if (_context.Request.ProtocolVersion < HttpVersion.Version11) { headers.InternalSet("Connection", "keep-alive", true); } } if (_location != null) { headers.InternalSet("Location", _location, true); } if (_cookies != null) { foreach (Cookie cookie in _cookies) { headers.InternalSet("Set-Cookie", cookie.ToResponseString(), true); } } var enc = _contentEncoding ?? Encoding.Default; var writer = new StreamWriter(destination, enc, 256); writer.Write("HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription); writer.Write(headers.ToStringMultiValue(true)); writer.Flush(); // Assumes that the destination was at position 0. destination.Position = enc.GetPreamble().Length; return(headers); }
public static RequestHandshake Parse(string[] request) { var requestLine = request[0].Split(' '); if (requestLine.Length != 3) { var msg = "Invalid HTTP Request-Line: " + request[0]; throw new ArgumentException(msg, "request"); } var headers = new WebHeaderCollection(); for (int i = 1; i < request.Length; i++) headers.Add(request[i]); return new RequestHandshake { Headers = headers, HttpMethod = requestLine[0], RequestUri = requestLine[1].ToUri(), ProtocolVersion = new Version(requestLine[2].Substring(5)) }; }
private InputChunkState setTrailer( byte[] buffer, ref int offset, int length ) { while (offset < length) { if (_trailerState == 4) // CR LF CR LF { break; } var b = buffer[offset++]; _saved.Append((char)b); if (_trailerState == 1 || _trailerState == 3) // CR or CR LF CR { if (b != 10) { throwProtocolViolation("LF is expected."); } _trailerState++; continue; } if (b == 13) { _trailerState++; continue; } if (b == 10) { throwProtocolViolation("LF is unexpected."); } _trailerState = 0; } var len = _saved.Length; if (len > 4196) { throwProtocolViolation("The trailer is too long."); } if (_trailerState < 4) { return(InputChunkState.Trailer); } if (len == 2) { return(InputChunkState.End); } _saved.Length = len - 2; var val = _saved.ToString(); var reader = new StringReader(val); while (true) { var line = reader.ReadLine(); if (line == null || line.Length == 0) { break; } _headers.Add(line); } return(InputChunkState.End); }
private InputChunkState setTrailer(byte[] buffer, ref int offset, int length) { // Check if no trailer. if (_trailerState == 2 && buffer[offset] == 13 && _saved.Length == 0) { offset++; if (offset < length && buffer[offset] == 10) { offset++; return(InputChunkState.End); } offset--; } while (offset < length && _trailerState < 4) { var b = buffer[offset++]; _saved.Append((char)b); if (_saved.Length > 4196) { throwProtocolViolation("The trailer is too long."); } if (_trailerState == 1 || _trailerState == 3) { if (b != 10) { throwProtocolViolation("LF is expected."); } _trailerState++; continue; } if (b == 13) { _trailerState++; continue; } if (b == 10) { throwProtocolViolation("LF is unexpected."); } _trailerState = 0; } if (_trailerState < 4) { return(InputChunkState.Trailer); } _saved.Length -= 2; var reader = new StringReader(_saved.ToString()); string line; while ((line = reader.ReadLine()) != null && line.Length > 0) { _headers.Add(line); } return(InputChunkState.End); }
State ReadTrailer(byte [] buffer, ref int offset, int size) { char c = '\0'; // short path if (trailerState == 2 && (char)buffer [offset] == '\r' && saved.Length == 0) { offset++; if (offset < size && (char)buffer [offset] == '\n') { offset++; return(State.None); } offset--; } int st = trailerState; string stString = "\r\n\r"; while (offset < size && st < 4) { c = (char)buffer [offset++]; if ((st == 0 || st == 2) && c == '\r') { st++; continue; } if ((st == 1 || st == 3) && c == '\n') { st++; continue; } if (st > 0) { saved.Append(stString.Substring(0, saved.Length == 0? st - 2: st)); st = 0; if (saved.Length > 4196) { ThrowProtocolViolation("Error reading trailer (too long)."); } } } if (st < 4) { trailerState = st; if (offset < size) { ThrowProtocolViolation("Error reading trailer."); } return(State.Trailer); } var reader = new StringReader(saved.ToString()); string line; while ((line = reader.ReadLine()) != null && line != "") { headers.Add(line); } return(State.None); }
/// <summary> /// Appends a <paramref name="value"/> to the specified HTTP header sent with the response. /// </summary> /// <param name="name"> /// A <see cref="string"/> that represents the name of the header to append /// <paramref name="value"/> to. /// </param> /// <param name="value"> /// A <see cref="string"/> that represents the value to append to the header. /// </param> /// <exception cref="ArgumentException"> /// <para> /// <paramref name="name"/> or <paramref name="value"/> contains invalid characters. /// </para> /// <para> /// -or- /// </para> /// <para> /// <paramref name="name"/> is a restricted header name. /// </para> /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="name"/> is <see langword="null"/> or empty. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// The length of <paramref name="value"/> is greater than 65,535 characters. /// </exception> /// <exception cref="InvalidOperationException"> /// <para> /// The response has already been sent. /// </para> /// <para> /// -or- /// </para> /// <para> /// The current headers cannot allow the header to append a value. /// </para> /// </exception> /// <exception cref="ObjectDisposedException"> /// This object is closed. /// </exception> public void AppendHeader(string name, string value) { checkDisposedOrHeadersSent(); _headers.Add(name, value); }
internal WebHeaderCollection WriteHeadersTo (MemoryStream destination) { var headers = new WebHeaderCollection (HttpHeaderType.Response, true); if (_headers != null) headers.Add (_headers); if (_contentType != null) { var type = _contentType.IndexOf ("charset=", StringComparison.Ordinal) == -1 && _contentEncoding != null ? String.Format ("{0}; charset={1}", _contentType, _contentEncoding.WebName) : _contentType; headers.InternalSet ("Content-Type", type, true); } if (headers["Server"] == null) headers.InternalSet ("Server", "websocket-sharp/1.0", true); var prov = CultureInfo.InvariantCulture; if (headers["Date"] == null) headers.InternalSet ("Date", DateTime.UtcNow.ToString ("r", prov), true); if (!_sendChunked) headers.InternalSet ("Content-Length", _contentLength.ToString (prov), true); else headers.InternalSet ("Transfer-Encoding", "chunked", true); /* * Apache forces closing the connection for these status codes: * - 400 Bad Request * - 408 Request Timeout * - 411 Length Required * - 413 Request Entity Too Large * - 414 Request-Uri Too Long * - 500 Internal Server Error * - 503 Service Unavailable */ var closeConn = !_context.Request.KeepAlive || !_keepAlive || _statusCode == 400 || _statusCode == 408 || _statusCode == 411 || _statusCode == 413 || _statusCode == 414 || _statusCode == 500 || _statusCode == 503; var reuses = _context.Connection.Reuses; if (closeConn || reuses >= 100) { headers.InternalSet ("Connection", "close", true); } else { headers.InternalSet ( "Keep-Alive", String.Format ("timeout=15,max={0}", 100 - reuses), true); if (_context.Request.ProtocolVersion < HttpVersion.Version11) headers.InternalSet ("Connection", "keep-alive", true); } if (_location != null) headers.InternalSet ("Location", _location, true); if (_cookies != null) foreach (Cookie cookie in _cookies) headers.InternalSet ("Set-Cookie", cookie.ToResponseString (), true); var enc = _contentEncoding ?? Encoding.Default; var writer = new StreamWriter (destination, enc, 256); writer.Write ("HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription); writer.Write (headers.ToStringMultiValue (true)); writer.Flush (); // Assumes that the destination was at position 0. destination.Position = enc.GetPreamble ().Length; return headers; }