public void SetProxyInfo(ProxyInfo info) { proxiedFiles[info.LocalFilename] = info; }
private void ServeStaticFile(NetworkStream stream, byte[] buffer, ProxyInfo info, string target) { Logger.ReportInfo("Serving cached file: " + target); StringBuilder header = new StringBuilder(); header.Append("HTTP/1.1 200 OK\r\n"); header.AppendFormat("Content-Length: {0}\r\n", new FileInfo(target).Length); header.AppendFormat("Content-Type: {0}\r\n", info.ContentType); header.Append("Content-Transfer-Encoding: binary\r\n"); header.Append("\r\n"); var streamWriter = new StreamWriter(stream); streamWriter.Write(header.ToString()); using (var p = File.Open(target, FileMode.Open, FileAccess.Read, FileShare.Read)) { while (true) { var bytes_read = p.Read(buffer, 0, buffer.Length); if (bytes_read > 0) { try { stream.Write(buffer, 0, bytes_read); } catch (IOException) { return; //they probably shut down the request before we were finished } } else { break; } } } }
public void ServeCachedFile(NetworkStream stream, string filename, ProxyInfo info) { Logger.ReportInfo("Serving temp file: " + filename); byte[] buffer = new byte[8000]; FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); int retries = 500; int totalRead, bytesRead; totalRead = bytesRead = fs.Read(buffer, 0, buffer.Length); while (true) { if (bytesRead == 0) { if (retries-- > 0) { Thread.Sleep(100); } else { Logger.ReportVerbose("Returning from ServeCachedFile due to max number of retries"); break; } } else { try { stream.Write(buffer, 0, bytesRead); } catch (IOException) { return; //they probably shut down the request before we were finished } } bytesRead = fs.Read(buffer, 0, buffer.Length); totalRead += bytesRead; } }
private void ProxyRemoteFile(NetworkStream stream, byte[] buffer, ProxyInfo info, string target, string cacheFile) { Logger.ReportInfo("Proxying file: " + target); TcpClient proxy = new TcpClient(); proxy.Connect(info.Host, info.Port); var proxyStream = proxy.GetStream(); var writer = new StreamWriter(proxyStream); writer.Write(string.Format("GET {0} HTTP/1.1\r\n", info.Path)); if (info.UserAgent != null) { writer.Write(string.Format("User-Agent: {0}\r\n", info.UserAgent)); } writer.Write(string.Format("Host: {0}\r\n", info.Host)); writer.Write("Cache-Control: no-cache\r\n"); writer.Write("\r\n"); writer.Flush(); FileStream fs; using (fs = new FileStream(cacheFile, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read)) { var bytesRead = proxyStream.Read(buffer, 0, buffer.Length); var badStream = false; StringBuilder header = new StringBuilder(); bool gotHeader = false; int contentLength = -1; int totalRead = 0; int headerLength = 0; while (bytesRead > 0) { if (!gotHeader) { header.Append(ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead)); string headerString = header.ToString(); if (headerString.Contains("\r\n\r\n")) { gotHeader = true; foreach (var line in headerString.Split('\n')) { if (line.StartsWith("Content-Length:")) // 123456789123456 { contentLength = int.Parse(line.Substring(16).Trim()); } } Trace.WriteLine(contentLength); headerLength = headerString.IndexOf("\r\n\r\n") + 4; } } lock (info) { info.BytesRead += bytesRead; } totalRead += bytesRead; fs.Write(buffer, 0, bytesRead); try { if (!badStream) { stream.Write(buffer, 0, bytesRead); } } catch { // just read till the end of the file ... our stream was shut. badStream = true; } var amountToRead = buffer.Length; if (contentLength > 0) { amountToRead = Math.Min(buffer.Length, (contentLength + headerLength) - totalRead); } if (amountToRead == 0) { break; } bytesRead = proxyStream.Read(buffer, 0, amountToRead); } // file was completely read ... rename it and strip header CommitTempFile(fs, target); } info.Completed = true; }
public string ProxyUrl(MBTrailers.ITunesTrailer trailer) { Uri uri = new Uri(trailer.RealPath); ProxyInfo proxyInfo = new ProxyInfo(uri.Host, uri.PathAndQuery, ProxyInfo.ITunesUserAgent, uri.Port); TrailerInfo trailerInfo = new TrailerInfo(TrailerType.Remote, proxyInfo.LocalFilename, trailer.ParentalRating, trailer.Genres); using (ChannelFactory<ITrailerProxy> factory = new ChannelFactory<ITrailerProxy>(new NetNamedPipeBinding(), "net.pipe://localhost/mbtrailers")) { ITrailerProxy proxyServer = factory.CreateChannel(); try { proxyServer.SetProxyInfo(proxyInfo); proxyServer.SetTrailerInfo(trailerInfo); } catch (Exception e) { Logger.ReportException("Error setting proxy info", e); Logger.ReportError("Inner Exception: " + e.InnerException.Message); } finally { (proxyServer as ICommunicationObject).Close(); } } var target = Path.Combine(cacheDir, proxyInfo.LocalFilename); return File.Exists(target) ? target : string.Format("http://localhost:{0}/{1}", this.port, proxyInfo.LocalFilename); }