62 lines
2.2 KiB
C#
62 lines
2.2 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Cryville.Common.Network {
|
|
public class HttpResponse {
|
|
static readonly char[] spchar = new char[]{ ' ' };
|
|
public string HttpVersion { get; private set; }
|
|
public string StatusCode { get; private set; }
|
|
public string ReasonPhase { get; private set; }
|
|
public Dictionary<string, string> Headers { get; private set; }
|
|
public HttpResponseStream MessageBody { get; private set; }
|
|
internal HttpResponse(Stream stream) {
|
|
var reader = new BinaryReader(stream, Encoding.ASCII);
|
|
var statu_line = ReadLine(reader).Split(spchar, 3);
|
|
HttpVersion = statu_line[0];
|
|
StatusCode = statu_line[1];
|
|
ReasonPhase = statu_line[2];
|
|
Logger.Log("main", 0, "Network", "Receive Response: {0} {1} {2}", HttpVersion, StatusCode, ReasonPhase);
|
|
Headers = new Dictionary<string, string>();
|
|
while (ParseHeader(reader, Headers)) ;
|
|
if (Headers.ContainsKey("content-length")) {
|
|
int length = int.Parse(Headers["content-length"]);
|
|
MessageBody = new HttpResponseBlockStream(reader, length);
|
|
}
|
|
else if (Headers.ContainsKey("transfer-encoding") && Headers["transfer-encoding"] == "chunked") {
|
|
MessageBody = new HttpResponseChunkedStream(reader);
|
|
}
|
|
}
|
|
|
|
public override string ToString() {
|
|
return string.Format("<{0} {1} {2}>", HttpVersion, StatusCode, ReasonPhase);
|
|
}
|
|
|
|
internal static bool ParseHeader(BinaryReader reader, Dictionary<string,string> headers) {
|
|
// TODO Multiline header
|
|
var header = ReadLine(reader);
|
|
if (header == "") return false;
|
|
var s = header.Split(':');
|
|
string field_name = s[0].Trim().ToLower();
|
|
string field_value = s[1].Trim();
|
|
if (headers.ContainsKey(field_name)) headers[field_name] += "," + field_value;
|
|
else headers.Add(field_name, field_value);
|
|
Logger.Log("main", 0, "Network", "Receive Header {0}: {1}", field_name, field_value);
|
|
return true;
|
|
}
|
|
|
|
internal static string ReadLine(BinaryReader reader) {
|
|
StringBuilder result = new StringBuilder();
|
|
char c;
|
|
while (true) {
|
|
c = reader.ReadChar();
|
|
if (c == '\r') break;
|
|
result.Append(c);
|
|
}
|
|
// TODO Unseekable
|
|
reader.ReadByte();
|
|
return result.ToString();
|
|
}
|
|
}
|
|
}
|