コード例 #1
0
ファイル: HttpClient.cs プロジェクト: nono303/simpleDLNA
        private void SendResponse()
        {
            var statusCode     = response.Status;
            var responseBody   = ProcessRanges(response, ref statusCode);
            var responseStream = new ConcatenatedStream();

            try {
                var headerBlock = new StringBuilder();
                headerBlock.AppendFormat(
                    "HTTP/1.1 {0} {1}\r\n",
                    (uint)statusCode,
                    HttpPhrases.Phrases[statusCode]
                    );
                headerBlock.Append(response.Headers.HeaderBlock);
                headerBlock.Append(CRLF);

                var headerStream = new MemoryStream(
                    Encoding.ASCII.GetBytes(headerBlock.ToString()));
                responseStream.AddStream(headerStream);
                if (Method != "HEAD" && responseBody != null)
                {
                    responseStream.AddStream(responseBody);
                    responseBody = null;
                }
                DebugFormat("{0} - {1} response for {2}", this, (uint)statusCode, Path);
                state = HttpStates.Writing;
                var sp = new StreamPump(responseStream, stream, BUFFER_SIZE);
                sp.Pump((pump, result) =>
                {
                    pump.Input.Close();
                    pump.Input.Dispose();
                    if (result == StreamPumpResult.Delivered)
                    {
                        DebugFormat("{0} - Done writing response", this);

                        string conn;
                        if (Headers.TryGetValue("connection", out conn) &&
                            conn.ToUpperInvariant() == "KEEP-ALIVE")
                        {
                            ReadNext();
                            return;
                        }
                    }
                    else
                    {
                        DebugFormat("{0} - Client aborted connection", this);
                    }
                    Close();
                });
            }
            catch (Exception) {
                responseStream.Dispose();
                throw;
            }
            finally {
                responseBody?.Dispose();
            }
        }
コード例 #2
0
        private void SendResponse()
        {
            var responseBody = response.Body;
            var st           = response.Status;

            var contentLength = GetContentLengthFromStream(responseBody);

            string ar;

            if (st == HttpCodes.OK && contentLength > 0 && headers.TryGetValue("Range", out ar))
            {
                try {
                    var m = bytes.Match(ar);
                    if (!m.Success)
                    {
                        throw new InvalidDataException("Not parsed!");
                    }
                    var totalLength = contentLength;
                    var start       = 0L;
                    var end         = totalLength - 1;
                    if (!long.TryParse(m.Groups[1].Value, out start) || start < 0)
                    {
                        throw new InvalidDataException("Not parsed");
                    }
                    if (m.Groups.Count != 3 || !long.TryParse(m.Groups[2].Value, out end) || end <= start || end >= totalLength)
                    {
                        end = totalLength - 1;
                    }
                    if (start >= end)
                    {
                        responseBody.Close();
                        response = Error416.HandleRequest(this);
                        SendResponse();
                        return;
                    }

                    if (start > 0)
                    {
                        responseBody.Seek(start, SeekOrigin.Current);
                    }
                    contentLength = end - start + 1;
                    response.Headers["Content-Length"] = contentLength.ToString();
                    response.Headers.Add("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, totalLength));
                    st = HttpCodes.PARTIAL;
                }
                catch (Exception ex) {
                    Warn(String.Format("{0} - Failed to process range request!", this), ex);
                }
            }

            var hb = new StringBuilder();

            hb.AppendFormat("HTTP/1.1 {0} {1}\r\n", (uint)st, HttpPhrases.Phrases[st]);
            hb.Append(response.Headers.HeaderBlock);
            hb.Append("\r\n");

            var rs = new ConcatenatedStream();

            try {
                var headerStream = new MemoryStream(Encoding.ASCII.GetBytes(hb.ToString()));
                rs.AddStream(headerStream);
                if (method != "HEAD" && responseBody != null)
                {
                    rs.AddStream(responseBody);
                }
                InfoFormat("{0} - {1} response for {2}", this, (uint)st, path);
                state = HttpStates.WRITING;
                new StreamPump(rs, stream, (pump, result) =>
                {
                    pump.Input.Close();
                    pump.Input.Dispose();
                    if (result == StreamPumpResult.Delivered)
                    {
                        DebugFormat("{0} - Done writing response", this);

                        string conn;
                        if (headers.TryGetValue("connection", out conn) && conn.ToLower() == "keep-alive")
                        {
                            ReadNext();
                            return;
                        }
                    }
                    Close();
                }, BUFFER_SIZE);
            }
            catch (Exception) {
                rs.Dispose();
                throw;
            }
        }