title: CefSharp custom SchemeHandler
body: <p>Iam using CefSharp's SchemeHandler in order to grab resources from my C# project like <code>.css</code>, <code>.js</code> or <code>.png</code> files using a custom url for example <code>custom://cefsharp/assets/css/style.css</code></p>
  
  <p>I've 2 custom classes in order to archive this.</p>
  
  <p>First class, <code>MyCustomSchemeHandlerFactory</code> will be the one that handles the custom Scheme and it looks like this, where "custom" will be the custom scheme:</p>
  
  <pre><code>internal class MyCustomSchemeHandlerFactory : ISchemeHandlerFactory
  {
      public const string SchemeName = "custom";
  
      public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
      {
          return new MyCustomSchemeHandler();
      }
  }
  </code></pre>
  
  <p>The next class I've implemented is <code>MyCustomSchemeHandler</code> which will receive the call and output a response and it looks like this:</p>
  
  <pre><code>internal class MyCustomSchemeHandler : IResourceHandler
  {
  
      private static readonly IDictionary&lt;string, string&gt; ResourceDictionary;
  
      private string mimeType;
      private MemoryStream stream;
  
      static MyCustomSchemeHandler()
      {
          ResourceDictionary = new Dictionary&lt;string, string&gt;
          {
              { "/home.html", Properties.Resources.index},
              { "/assets/css/style.css", Properties.Resources.style}
          };
      }
  
      public Stream Stream { get; set; }
      public int StatusCode { get; set; }
      public string StatusText { get; set; }
      public string MimeType { get; set; }
      public NameValueCollection Headers { get; private set; }
  
      public Stream GetResponse(IResponse response, out long responseLength, out string redirectUrl)
      {
          redirectUrl = null;
          responseLength = -1;
  
          response.MimeType = MimeType;
          response.StatusCode = StatusCode;
          response.StatusText = StatusText;
          response.ResponseHeaders = Headers;
  
          var memoryStream = Stream as MemoryStream;
          if (memoryStream != null)
          {
              responseLength = memoryStream.Length;
          }
  
          return Stream;
      }
  
      public bool ProcessRequestAsync(IRequest request, ICallback callback)
      {
          // The 'host' portion is entirely ignored by this scheme handler.
          var uri = new Uri(request.Url);
          var fileName = uri.AbsolutePath;
          string resource;
  
          if (ResourceDictionary.TryGetValue(fileName, out resource) &amp;&amp; !string.IsNullOrEmpty(resource))
          {
              var resourceHandler = ResourceHandler.FromString(resource);
              stream = (MemoryStream)resourceHandler.Stream;
  
              var fileExtension = Path.GetExtension(fileName);
              mimeType = ResourceHandler.GetMimeType(fileExtension);
  
              callback.Continue();
              return true;
          }
          else
          {
              callback.Dispose();
          }
  
          return false;
      }
  
      void GetResponseHeaders(IResponse response, out long responseLength, out string redirectUrl)
      {
          responseLength = stream == null ? 0 : stream.Length;
          redirectUrl = null;
  
          response.StatusCode = (int)HttpStatusCode.OK;
          response.StatusText = "OK";
          response.MimeType = mimeType;
      }
  
      bool ReadResponse(Stream dataOut, out int bytesRead, ICallback callback)
      {
          //Dispose the callback as it's an unmanaged resource, we don't need it in this case
          callback.Dispose();
  
          if (stream == null)
          {
              bytesRead = 0;
              return false;
          }
  
          //Data out represents an underlying buffer (typically 32kb in size).
          var buffer = new byte[dataOut.Length];
          bytesRead = stream.Read(buffer, 0, buffer.Length);
  
          dataOut.Write(buffer, 0, buffer.Length);
  
          return bytesRead &gt; 0;
      }
  
      bool CanGetCookie(Cookie cookie)
      {
          return true;
      }
  
      bool CanSetCookie(Cookie cookie)
      {
          return true;
      }
  
      void Cancel()
      {
  
      }
  
  }
  </code></pre>
  
  <p>Inside this class I've defined a custom resource dictionary which will dictate what file from the resources will be used, so as I stated in the first example, <code>custom://cefsharp/assets/css/style.css</code> should load the resource <code>Properties.Resources.style</code>, the problem is that nothing gets loaded once I enter to the specific url, I've tried to output the mimeType and It works but somehow the file itself won't output correctly. Is there something wrong with my implementation?</p>
  
  <p>Additionaly I've tried to output the raw file in the form of:</p>
  
  <pre><code>if (ResourceDictionary.TryGetValue(fileName, out resource) &amp;&amp; !string.IsNullOrEmpty(resource))
  {
      MessageBox.Show(resource);
  }
  </code></pre>
  
  <p>And it outputs the correct file without any problems.</p>
  
  <p>To load the custom Scheme I use the following code before initializing CefSharp:</p>
  
  <pre><code>var settings = new CefSettings();
  settings.RegisterScheme(new CefCustomScheme
  {
      SchemeName = MyCustomSchemeHandlerFactory.SchemeName,
      SchemeHandlerFactory = new MyCustomSchemeHandlerFactory()
  });
  </code></pre>
  
  <p>The above classes were based on the following links:
  MyCustomSchemeHandlerFactory: <a href="https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/FlashResourceHandlerFactory.cs" rel="noreferrer">FlashResourceHandlerFactory.cs</a>
  MyCustomSchemeHandler: <a href="https://github.com/cefsharp/CefSharp/blob/7ec769de235670b5984a4de26c272ad53112b998/CefSharp.Example/CefSharpSchemeHandler.cs" rel="noreferrer">CefSharpSchemeHandler.cs</a> and <a href="https://github.com/cefsharp/CefSharp/blob/7ec769de235670b5984a4de26c272ad53112b998/CefSharp/ResourceHandler.cs" rel="noreferrer">ResourceHandler.cs</a></p>