public static HTTPResponse ResolveHTTPResponse(byte[] rawBytes) { HTTPResponse result = new HTTPResponse(); List <string> rawHeaders = new List <string>(); int pos = 0; string ht = ""; while (pos < rawBytes.Length) { byte tb = rawBytes[pos]; if (tb == '\r') { if (rawBytes[pos + 1] == '\n') { if (ht == "") { break; } rawHeaders.Add(ht); ht = ""; pos += 2; continue; } } ht += (char)tb; pos += 1; } string[] firstline = rawHeaders[0].Split(' '); rawHeaders.Remove(rawHeaders[0]); result.Version = firstline[0]; result.StatusCode = new HTTPStatusCode(Convert.ToInt32(firstline[1]), firstline[2]); foreach (string s in rawHeaders) { CommonHeader t = new CommonHeader(s); result.AddHeader(t); } return(result); }
internal System.IO.Stream GetSaveStream(HTTPResponse response) { if (!HTTPCacheService.IsSupported) { return(null); } LastAccess = DateTime.UtcNow; string path = GetPath(); if (HTTPManager.IOService.FileExists(path)) { Delete(); } // Path name too long, we don't want to get exceptions if (path.Length > HTTPManager.MaxPathLength) { return(null); } // First write out the headers using (Stream writer = HTTPManager.IOService.CreateFileStream(GetPath(), FileStreamModes.Create)) { writer.WriteLine("HTTP/1.1 {0} {1}", response.StatusCode, response.Message); foreach (var kvp in response.Headers) { for (int i = 0; i < kvp.Value.Count; ++i) { writer.WriteLine("{0}: {1}", kvp.Key, kvp.Value[i]); } } writer.WriteLine(); } // If caching is enabled and the response is from cache, and no content-length header set, then we set one to the response. if (response.IsFromCache && !response.HasHeader("content-length")) { response.AddHeader("content-length", BodyLength.ToString()); } SetUpCachingValues(response); // then create the stream with Append FileMode return(HTTPManager.IOService.CreateFileStream(GetPath(), FileStreamModes.Append)); }
private void dealProxyRequest(object obj) { try { TcpClient client = (TcpClient)obj; Console.WriteLine(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString()); HTTPRequest request; using (BinaryReader breader = new BinaryReader(client.GetStream())) { byte[] b = new byte[1]; string ht = ""; List <string> rawHeaders = new List <string>(); while (client.GetStream().CanRead&& client.GetStream().DataAvailable) { b[0] = breader.ReadByte(); ht += Encoding.ASCII.GetString(b); if (ht.Contains("\r\n")) { rawHeaders.Add(ht); if (ht == "\r\n") { break; } ht = ""; } } string sr = ""; foreach (string st in rawHeaders) { sr += st; } if (rawHeaders.Count == 0) { client.Dispose(); return; } request = SophieHTTP.HTTPResolve.HTTPResolve.ResolveHTTPRequest(Encoding.ASCII.GetBytes(sr)); if (request.Method.MethodName == HTTPMethod.CONNECT.MethodName) { request.Url = new Uri("https://" + request.Url.OriginalString + "/"); TcpClient remoteServer = new TcpClient(); try { remoteServer.Connect(Dns.GetHostEntry(request.Url.Host).AddressList[0], Convert.ToInt32(request.Url.Port)); HTTPResponse resp = new HTTPResponse(HTTPVersion.HTTP11, HTTPStatusCode.ConnectionEstablished, new List <HTTPHeader>()); if (client.Connected) { client.GetStream().Write(resp.GetRawBytes(), 0, resp.GetRawBytes().Length); } else { client.Dispose(); return; } NetworkStream serverStream = remoteServer.GetStream(); NetworkStream clientStream = client.GetStream(); while (client.Connected) { Thread.Sleep(1); if (serverStream.CanRead && clientStream.CanRead && serverStream.CanWrite && clientStream.CanWrite) { try { if (clientStream.DataAvailable) { byte[] buf = new byte[1024]; int size = clientStream.Read(buf, 0, 1024); serverStream.Write(buf, 0, size); } if (serverStream.DataAvailable) { byte[] buf = new byte[1024]; int size = serverStream.Read(buf, 0, 1024); clientStream.Write(buf, 0, size); } } catch (Exception ex) { break; } } else { break; } } remoteServer.Dispose(); client.Dispose(); } catch (SocketException ex) { HTTPResponse resp = new HTTPResponse(HTTPVersion.HTTP11, HTTPStatusCode.BadGateway, new List <HTTPHeader>()); resp.Content = Encoding.Unicode.GetBytes(ex.Message); client.GetStream().Write(resp.GetRawBytes(), 0, resp.GetRawBytes().Length); client.Dispose(); } } else { if (request.Version == HTTPVersion.HTTP09 || request.Version == HTTPVersion.HTTP10) { if (client.Connected) { HTTPResponse resp = new HTTPResponse(request.Version, HTTPStatusCode.HttpVersionNotSupported, new List <HTTPHeader>()); resp.Content = Encoding.UTF8.GetBytes("请升级到支持HTTP1.1的浏览器"); resp.AddHeader(new CommonHeader("Content-Type: text/html; charset=utf-8")); client.GetStream().Write(resp.GetRawBytes(), 0, resp.GetRawBytes().Length); return; } else { client.Dispose(); return; } } string host; int port; try { host = request.Url.Host; port = request.Url.Port; }catch (Exception ex) { if (request.FindHeader("Host") != null) { host = (string)request.FindHeader("Host").Value; port = 80; } else { HTTPResponse resp = new HTTPResponse(request.Version, HTTPStatusCode.BadRequest, new List <HTTPHeader>()); resp.Content = Encoding.UTF8.GetBytes("错误的请求"); resp.AddHeader(new CommonHeader("Content-Type: text/html; charset=utf-8")); client.GetStream().Write(resp.GetRawBytes(), 0, resp.GetRawBytes().Length); return; } } if (request.FindHeader("Connection") == null) { request.AddHeader(new ConnectionHeader("Connection:close")); } if (((ConnectionHeader)request.FindHeader("Connection")).FindValue("close") == null) { ConnectionHeader ch = (ConnectionHeader)request.FindHeader("Connection"); ch.Value = new List <string>(); ((List <string>)ch.Value).Add("close"); } try { IPAddress remoteAddress = Dns.GetHostEntry(host).AddressList[0]; TcpClient remoteServer = new TcpClient(new IPEndPoint(remoteAddress, port)); remoteServer.GetStream().Write(request.GetRawBytes(), 0, request.GetRawBytes().Length); } catch (SocketException ex) { HTTPResponse resp = new HTTPResponse(HTTPVersion.HTTP11, HTTPStatusCode.BadGateway, new List <HTTPHeader>()); resp.Content = Encoding.Unicode.GetBytes(ex.Message); client.GetStream().Write(resp.GetRawBytes(), 0, resp.GetRawBytes().Length); client.Dispose(); } } } } catch (Exception ex) { return; } }