long GetRangeLen(ByteRange range, Stream stream) { if (!stream.CanSeek) { return(-1); } long length = stream.Length; if (range.Last > stream.Length) { return(-1); } if (range.First > stream.Length) { return(-1); } if (range.Last == -1) { return(stream.Length - range.First); } if (range.First == -1) { return(range.Last); } return((range.Last - range.First) + 1); }
internal void ProcessLine(string line) { switch(state) { case ProcessingState.RequestLine: { string[] protocol = line.Split(' '); if(protocol.Length != 3) { RequestError("400", "Invalid protocol string"); return; } switch(protocol[0]) { case "GET": case "POST": case "HEAD": method = protocol[0]; break; case "PUT": case "DELETE": case "OPTIONS": case "TRACE": default: RequestError("501", StatusCodes.GetDescription("501")); return; } if(protocol[1].Length > 2500) { RequestError("414", StatusCodes.GetDescription("414")); return; } requestUri = protocol[1]; if(!protocol[2].StartsWith("HTTP/") || !(protocol[2].Length > "HTTP/".Length)) { RequestError("400", "Invalid protocol string"); return; } httpVersion = protocol[2].Substring("HTTP/".Length); date = DateTime.Now; connMode = httpVersion == "1.0" ? ConnectionMode.Close : ConnectionMode.KeepAlive; state = ProcessingState.Headers; break; } case ProcessingState.Headers: { if(headers.Count > maxHeaderLines) { RequestError("400", "Maximum header line count exceeded"); return; } if(line.Length == 0) { PostProcessHeaders(); return; } int colonIndex = line.IndexOf(":"); if(colonIndex <= 1) return; string val = line.Substring(colonIndex + 1).Trim(); string name = line.Substring(0, colonIndex); try { headers.Add(name, val); } catch { } switch(name.ToLower(CultureInfo.InvariantCulture)) { case "host": host = val; break; case "authorization": { if(val.Length < 6) break; string encoded = val.Substring(6, val.Length - 6); byte[] byteAuth; try { byteAuth = Convert.FromBase64String(encoded); } catch(FormatException) { break; } string[] strings = Encoding.UTF8.GetString(byteAuth).Split(':'); if(strings.Length != 2) break; username = strings[0]; password = strings[1]; break; } case "content-type": contentType = val; break; case "content-length": try { contentLength = long.Parse(val, NumberStyles.Integer, CultureInfo.InvariantCulture); } catch(FormatException) { } if(contentLength > client.server.MaxPostLength) { RequestError("413", StatusCodes.GetDescription("413")); return; } else if(contentLength < 0) { RequestError("400", StatusCodes.GetDescription("400")); return; } break; case "accept": accept = val; break; case "accept-language": acceptLanguage = val; break; case "user-agent": userAgent = val; break; case "connection": if(string.Compare(val, "close", true, CultureInfo.InvariantCulture) == 0) connMode = ConnectionMode.Close; else connMode = ConnectionMode.KeepAlive; break; case "if-modified-since": try { ifModifiedSince = ParseHttpTime(val); } catch(FormatException) { } break; case "if-unmodified-since": try { ifUnmodifiedSince = ParseHttpTime(val); } catch(FormatException) { } break; case "range": try { string[] rangeStrings = val.Split(','); this.ranges = new ByteRange[rangeStrings.Length]; for(int i = 0; i < rangeStrings.Length; i++) ranges[i] = new ByteRange(rangeStrings[i]); } catch(FormatException) { this.ranges = null; } break; default: break; } break; } } }
long GetRangeLen(ByteRange range, Stream stream) { if(!stream.CanSeek) return -1; long length = stream.Length; if(range.Last > stream.Length) return -1; if(range.First > stream.Length) return -1; if(range.Last == -1) return stream.Length - range.First; if(range.First == -1) return range.Last; return (range.Last - range.First) + 1; }
internal void ProcessLine(string line) { switch (state) { case ProcessingState.RequestLine: { string[] protocol = line.Split(' '); if (protocol.Length != 3) { RequestError("400", "Invalid protocol string"); return; } switch (protocol[0]) { case "GET": case "POST": case "HEAD": method = protocol[0]; break; case "PUT": case "DELETE": case "OPTIONS": case "TRACE": default: RequestError("501", StatusCodes.GetDescription("501")); return; } if (protocol[1].Length > 2500) { RequestError("414", StatusCodes.GetDescription("414")); return; } requestUri = protocol[1]; if (!protocol[2].StartsWith("HTTP/") || !(protocol[2].Length > "HTTP/".Length)) { RequestError("400", "Invalid protocol string"); return; } httpVersion = protocol[2].Substring("HTTP/".Length); date = DateTime.Now; connMode = httpVersion == "1.0" ? ConnectionMode.Close : ConnectionMode.KeepAlive; state = ProcessingState.Headers; break; } case ProcessingState.Headers: { if (headers.Count > maxHeaderLines) { RequestError("400", "Maximum header line count exceeded"); return; } if (line.Length == 0) { PostProcessHeaders(); return; } int colonIndex = line.IndexOf(":"); if (colonIndex <= 1) { return; } string val = line.Substring(colonIndex + 1).Trim(); string name = line.Substring(0, colonIndex); try { headers.Add(name, val); } catch { } switch (name.ToLower(CultureInfo.InvariantCulture)) { case "host": host = val; break; case "authorization": { if (val.Length < 6) { break; } string encoded = val.Substring(6, val.Length - 6); byte[] byteAuth; try { byteAuth = Convert.FromBase64String(encoded); } catch (FormatException) { break; } string[] strings = Encoding.UTF8.GetString(byteAuth).Split(':'); if (strings.Length != 2) { break; } username = strings[0]; password = strings[1]; break; } case "content-type": contentType = val; break; case "content-length": try { contentLength = long.Parse(val, NumberStyles.Integer, CultureInfo.InvariantCulture); } catch (FormatException) { } if (contentLength > client.server.MaxPostLength) { RequestError("413", StatusCodes.GetDescription("413")); return; } else if (contentLength < 0) { RequestError("400", StatusCodes.GetDescription("400")); return; } break; case "accept": accept = val; break; case "accept-language": acceptLanguage = val; break; case "user-agent": userAgent = val; break; case "connection": if (string.Compare(val, "close", true, CultureInfo.InvariantCulture) == 0) { connMode = ConnectionMode.Close; } else { connMode = ConnectionMode.KeepAlive; } break; case "if-modified-since": try { ifModifiedSince = ParseHttpTime(val); } catch (FormatException) { } break; case "if-unmodified-since": try { ifUnmodifiedSince = ParseHttpTime(val); } catch (FormatException) { } break; case "range": try { string[] rangeStrings = val.Split(','); this.ranges = new ByteRange[rangeStrings.Length]; for (int i = 0; i < rangeStrings.Length; i++) { ranges[i] = new ByteRange(rangeStrings[i]); } } catch (FormatException) { this.ranges = null; } break; default: break; } break; } } }