Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Net;
- using System.Collections.Generic;
- using System.IO;
- using System.Runtime.Serialization.Formatters.Binary;
- namespace YoutubeCache
- {
- class MainClass
- {
- static List<string> DownloadJobs = new List<string> ();
- public static void Main (string[] args)
- {
- var listener = new HttpListener ();
- Environment.CurrentDirectory = Path.GetDirectoryName (
- System.Reflection.Assembly.GetExecutingAssembly ().Location);
- listener.Prefixes.Add ("http://*:3949/");
- listener.Start ();
- Console.WriteLine ("Listening on port 3949");
- while (true) {
- try {
- var context = listener.GetContext ();
- string requestString = context.Request.RawUrl;
- HttpWebRequest request = (HttpWebRequest)WebRequest.Create (requestString);
- request.KeepAlive = false;
- request.Proxy.Credentials = CredentialCache.DefaultCredentials;
- request.Timeout = 200000;
- request.Method = context.Request.HttpMethod;
- RequestData requestData = new RequestData (request, context);
- if (requestString.Contains ("youtube.com/videoplayback")) {
- requestData.Cache = true;
- requestData.Signature = GetSignature (requestString);
- Console.WriteLine ("Youtube Video: " + requestData.Signature);
- Console.WriteLine (request.Method);
- foreach(string h in context.Request.Headers)
- {
- if(h == "Content-Range" || h == "Range")
- {
- Console.WriteLine ("{0}: {1}",h,context.Request.Headers[h]);
- }
- }
- if(File.Exists (requestData.Signature + "_done"))
- {
- request.BeginGetResponse (RespCacheCallback,requestData);
- Console.WriteLine ("Load from cache");
- }
- else
- {
- request.BeginGetResponse (RespCallback,requestData);
- Console.WriteLine ("Save to cache");
- }
- }
- else
- {
- request.BeginGetResponse (RespCallback, requestData);
- }
- } catch (Exception ex) {
- }
- }
- }
- static string GetSignature (string url)
- {
- int index = url.IndexOf ("&id=") + 4;
- int len = url.IndexOf ('&',index) - index;
- return GetITag(url) + "_" + url.Substring (index,len);
- }
- static string GetITag (string url)
- {
- int index = url.IndexOf ("&itag=") + 6;
- int len = url.IndexOf ('&',index) - index;
- return url.Substring (index,len);
- }
- static void RespCacheCallback (IAsyncResult asyncresult)
- {
- RequestData requestData = (RequestData)asyncresult.AsyncState;
- HttpListenerResponse responseOut = requestData.Context.Response;
- using (var cacheFile = File.OpenRead (requestData.Signature)) {
- var info = ReadInfo (requestData.Signature);
- if(info.ResponseLength != -1)
- responseOut.ContentLength64 = info.ResponseLength;
- responseOut.StatusCode = info.StatusCode;
- responseOut.Cookies = info.Cookies;
- responseOut.Headers = info.Headers;
- CopyStream (cacheFile,responseOut.OutputStream);
- cacheFile.Close ();
- responseOut.OutputStream.Close ();
- }
- }
- public static void WriteInfo (string signature, SavedResponse response)
- {
- var formatter = new BinaryFormatter();
- using (var file = File.Create (signature + "_info")) {
- formatter.Serialize (file,response);
- }
- }
- public static SavedResponse ReadInfo (string signature)
- {
- var formatter = new BinaryFormatter ();
- SavedResponse resp;
- using (var file = File.OpenRead (signature + "_info")) {
- resp = (SavedResponse)formatter.Deserialize (file);
- }
- return resp;
- }
- static void RespCallback (IAsyncResult asyncresult)
- {
- RequestData requestData = (RequestData)asyncresult.AsyncState;
- try {
- using (HttpWebResponse response = (HttpWebResponse)requestData.Request.EndGetResponse(asyncresult)) {
- HttpListenerResponse responseOut = requestData.Context.Response;
- using (var receiveStream = response.GetResponseStream ()) {
- if (response.ContentLength != -1)
- responseOut.ContentLength64 = response.ContentLength;
- responseOut.StatusCode = (int)response.StatusCode;
- responseOut.Cookies = response.Cookies;
- responseOut.Headers = response.Headers;
- if(requestData.Cache)
- {
- var info = new SavedResponse(response.ContentLength,
- (int)response.StatusCode,
- response.Cookies,
- response.Headers);
- WriteInfo (requestData.Signature,info);
- CopyStreamCache (receiveStream,responseOut.OutputStream,requestData.Signature);
- }
- else
- CopyStream (receiveStream, responseOut.OutputStream);
- responseOut.OutputStream.Close ();
- }
- }
- } catch (WebException e) {
- Console.WriteLine ("Web exception");
- Console.WriteLine (e.Message);
- HttpListenerResponse responseOut = requestData.Context.Response;
- responseOut.StatusCode = (int)HttpStatusCode.NotFound;
- responseOut.OutputStream.Close ();
- } catch (IOException e) {
- Console.WriteLine ("Client closed?");
- Console.WriteLine (e.Message);
- } catch (Exception e) {
- Console.WriteLine ("Generic Exception");
- Console.WriteLine (e.Message);
- Console.WriteLine (e.StackTrace);
- }
- }
- public static int CopyStreamCache (Stream input, Stream output, string signature)
- {
- bool stillOpen = true;
- bool download = false;
- Stream stream;
- if (!DownloadJobs.Contains (signature)) {
- DownloadJobs.Add (signature);
- stream = File.Create (signature);
- download = true;
- }
- byte[] buffer = new byte[32768];
- int bytesWritten = 0;
- while (stillOpen && download) {
- int read = input.Read (buffer, 0, buffer.Length);
- if (read <= 0)
- break;
- if (stillOpen) {
- try {
- output.Write (buffer, 0, read);
- } catch (Exception) {
- stillOpen = false;
- }
- }
- bytesWritten += read;
- if (download)
- stream.Write (buffer, 0, read);
- }
- if (download) {
- stream.Close ();
- stream.Dispose ();
- File.WriteAllText (signature + "_done","");
- }
- return bytesWritten;
- }
- public static int CopyStream (Stream input, Stream output)
- {
- byte[] buffer = new byte[32768];
- int bytesWritten = 0;
- while (true) {
- int read = input.Read (buffer, 0, buffer.Length);
- if (read <= 0)
- break;
- output.Write (buffer, 0, read);
- bytesWritten += read;
- }
- return bytesWritten;
- }
- }
- class RequestData
- {
- public HttpWebRequest Request;
- public HttpListenerContext Context;
- public bool Cache = false;
- public string Signature = "";
- public RequestData (HttpWebRequest request, HttpListenerContext context)
- {
- Request = request;
- Context = context;
- }
- }
- [Serializable()]
- class SavedResponse
- {
- public long ResponseLength;
- public int StatusCode;
- public CookieCollection Cookies;
- public WebHeaderCollection Headers;
- public SavedResponse() {}
- public SavedResponse(long responseLength, int statusCode, CookieCollection cookies, WebHeaderCollection headers)
- {
- ResponseLength = responseLength;
- StatusCode = statusCode;
- Cookies = cookies;
- Headers = headers;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement