Giter Club home page Giter Club logo

griffin.webserver's People

Contributors

cjmurph avatar enricodetoma avatar gauffininteractive avatar jgauffin avatar onetrueerror avatar wo80 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

griffin.webserver's Issues

Error 400 by application/json Post.

hi Guys,

I have the following problem:

I send a Post request to the Griffin.WebServer via the dotNet HttpClient.
The Post request is to be transmitted by a Json.
The content type is application / json.
I get the following answer:

StatusCode: 400, ReasonPhrase: 'Unsupported content-type: application/json',

Why?

I hope you can help me.

ErrorModule bug

In method SetErrorPage (line 97): Instead of

httpContext.Response.Body = new MemoryStream();
httpContext.Response.Body.Write(bytes, 0, bytes.Length);

you should do

httpContext.Response.Body = new MemoryStream(bytes);

since Body.Position should be 0 when sending the response.

EDIT: Additionally, the Response.ContentLength should be set to the correct size.

Concurrency problem?

Hello! First of all, let me thank you for a quick and (mostly) painless solution for a problem that has plagued me for a while now.

I'm a college student but I'm also helping with a project as an intern at a software development company. This webserver has helped immensely but I've noticed something I cannot fix or understand. I cannot go into too much detail but the webserver setup in this project only works for the .NET webbrowser control and IE, simultaneously as well. Trying to access it from another browser (I've only tested this with Chrome, actually) leaves it waiting endlessly without any errors or any other message. Nothing even shows up in the Chrome developer console. After trying to repeat the process with a Python simple webserver (which is not portable so it's only useful for testing) everything works well.

Long story short: is there anything I can do to enable cross browser functionality, is it an incoming feature or is a fix not possible? Thank you for your time.

Exception when stopping WebServer

When you stop an instance of HttpServer an exception is thrown on another thread:

Message: An unhandled exception of type 'System.ObjectDisposedException' occurred in System.dll
Additional information: Cannot access a disposed object.
Griffin.Core.dll!Griffin.Net.ChannelTcpListener.OnAcceptSocket(System.IAsyncResult ar) Line 213 C#

Missing Content-Type in request produce BadRequest

Hello,

we're experiencing issues when receiving requests from a device that doesn't indicate the Content-Type in its requests. The requests are type POST and its content is application/octet-stream

As described in https://stackoverflow.com/a/15860815 the Griffin.WebServer should not return a Bad Request. Instead should try to guess the Content Type of the content or consider it as application/octet-stream.

If-Modified-Since problem

There's a minor problem with the DiskFileService setting the FileContext's IsModified flag:

Say your disk file time has:
Ticks = 635014822668060745

But the browser's If-Modified-Since tag ignores milliseconds:
Ticks = 635014822660000000

So in DiskFileService.GetFile() you should do something like

var date = File.GetLastWriteTimeUtc(fullPath);
date = date.AddTicks(-(date.Ticks % TimeSpan.TicksPerSecond));
if (date <= context.BrowserCacheDate) ...

It's not possible to run multiple HTTP servers in a single process / static buffer issue

I need to run multiple HTTP server instances within a single process to support multiple IP addresses and multiple sites.

In principle I'm trying to:

        var server_IPv4 = new HttpServer(moduleManager);
        server_IPv4.Start(IPAddress.Any, 0);

        var server_IPv6 = new HttpServer(moduleManager);
        server_IPv6.Start(IPAddress.IPv6Any, 0);

The 2nd call does fail when the HttpMessageBuilder pop slices from "_stack" which is defined as:

    private static readonly IBufferSliceStack _stack = new BufferSliceStack(100, 65535);

So after the static 100 buffers are used for first server, the 2nd one will fail in Pop method with:

    public IBufferSlice Pop()
    {
        PooledBufferSlice slice;
        if (_slices.TryPop(out slice))
            return slice;

        throw new InvalidOperationException(string.Format("All {0} has been given out.", _numberOfBuffers));
    }

Simply removing "static" from buffer definition causes an OutOfMemoryException, as the total number of buffer would be created for each "Pop".

Is this WebServer intended to run only as one instance per process? If not, this is a bug and I really would like to see it fixed soon :-)

Unable to Start() server again after Stop()

Now you've added a Stop() method, but when I try to restart the server after stopping it, I'm confronted with an ArgumentNullException (remoteEndPoint) in Griffin.Networking.Servers.Server.CreateClient. Please fix this, because I need the ability to restart the server after configuration changes (e.g. port number).

HTTPS support.

It'd be very nice to see HTTPS support like the old standalone webserver component had. Especially if it can be implemented using TLS. I'd be quite happy to throw some money at whoever can make this happen.

DiskFileService / GetFullPath should use UrlDecode

Requesting a file with encoded chars (like the space in http://127.0.0.1/test 1.html) won't work, since the file service can't find the file test%201.html.

So the GetFullPath method should do

relativeUri = HttpUtility.UrlDecode(relativeUri);

I suggest using the Mono code, so you don't get a dependency on System.Web (with System.Web the .Net client profile wouldn't work anymore).

Closed loop when answering 'Range' requests from FileModule

I'm still narrowing down the exact reproduction steps, but in the field users are finding that the web server enters a closed loop (and consequently munching on CPU time) when answering Range requests under certain circumstances.

In my local branch I've added an extra property to FileModule to simply disable this functionality cleanly, but I intend to find the root cause.

Blocking requests

Source: http://stackoverflow.com/questions/27139443/how-do-i-close-a-connection-on-a-request-to-the-griffin-webserver

We're using Griffin.WebServer as a replacement for the .Net HttpClient because the httpclient requires elevated privileges. After exhausting our options on that subject, we decided on Griffin.WebServer. Sorry this is not tagged with Griffin.WebServer - I do not have rep to create that tag.

This simple webserver responds to requests, and works great - once. Then the connection stays open, and a subsequent request will not process until I have closed the connection forcibly (using TCPView and right-click - Close Connection), or it times out.

Here is the client I am testing with:

    static void Main(string[] args)
    {
        try
        {
            var request = new
            {
                JsonData1 = 50538,
                JsonData2 = 2,
                JsonData3 = 1
            };

            var handler = new HttpClientHandler();
            handler.UseDefaultCredentials = true;
            using (var client = new HttpClient(handler))
            {
                client.BaseAddress = new Uri("http://ALocalMachine:8800/listener/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.ConnectionClose = true;
                Task<HttpResponseMessage> postTask = client.PostAsJsonAsync("RunTest/", request);

                postTask.Wait();

                if (!postTask.Result.IsSuccessStatusCode)
                {
                    throw new Exception("Unable to start test run - " + postTask.Result.ReasonPhrase);
                }

                var responseTask = postTask.Result.Content.ReadAsStringAsync();
                responseTask.Wait();
                dynamic response = JsonConvert.DeserializeObject(responseTask.Result);

                var results = new
                {
                    Error = "",
                    Success = true
                };
            }

            // this request fails with connection forcebly closed
            var request = new
            {
                JsonData1 = 50539,
                JsonData2 = 3,
                JsonData3 = 4
            };

            var handler = new HttpClientHandler();
            handler.UseDefaultCredentials = true;
            using (var client = new HttpClient(handler))
            {
                client.BaseAddress = new Uri("http://ALocalMachine:8800/listener/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.ConnectionClose = true;
                Task<HttpResponseMessage> postTask = client.PostAsJsonAsync("RunTest/", request);

                postTask.Wait();

                if (!postTask.Result.IsSuccessStatusCode)
                {
                    throw new Exception("Unsuccessful - " + postTask.Result.ReasonPhrase);
                }

                var responseTask = postTask.Result.Content.ReadAsStringAsync();
                responseTask.Wait();
                dynamic response = JsonConvert.DeserializeObject(responseTask.Result);

                var results = new
                {
                    Error = "",
                    Success = true
                };
            }

            Console.WriteLine("successful");
        }
        catch (Exception ex)
        {
            Console.WriteLine("failed with error: " + ex.ToString());
        }

        Console.ReadLine();
    }

Below is the Griffin IWorkerModule.

public class MyModule : IWorkerModule
{
    public class ListenerNotifyEventArgs : EventArgs
    {
        public IHttpContext Context { get; set; }
    }

    public delegate void ListenerNotifyEventHandler(object sender, ListenerNotifyEventArgs e);

    public event ListenerNotifyEventHandler OnListenerNotify;

    public void BeginRequest(IHttpContext context)
    {
    }

    public void EndRequest(IHttpContext context)
    {
    }

    public void HandleRequestAsync(IHttpContext context, Action<IAsyncModuleResult> callback)
    {
        // Since this module only supports sync
        callback(new AsyncModuleResult(context, HandleRequest(context)));
    }

    public ModuleResult HandleRequest(IHttpContext context)
    {
        if (OnListenerNotify != null)
            OnListenerNotify(null, new ListenerNotifyEventArgs(){Context = context});

        return ModuleResult.Stop;
    }
}

Here is my listener callback. Adding the:

    context.Response.KeepAlive = false;

didn't make any difference...

    private void ListenerCallback(object sender, MyModule.ListenerNotifyEventArgs eventArgs)
    {
        var context = eventArgs.Context;

        try
        {
            var requestDetails = context.Request.Uri.AbsolutePath.Substring("/TestifyAgent/".Length);

            if (requestDetails.ToLower().StartsWith("runtest"))
            {
                var data_text = new StreamReader(context.Request.Body, context.Request.ContentEncoding).ReadToEnd();

                dynamic requestVals = JsonConvert.DeserializeObject(data_text);
                int jsonData1 = Convert.ToInt32(requestVals.JsonData1);
                int jsonData2 = Convert.ToInt32(requestVals.JsonData2);
                int jsonData3 = Convert.ToInt32(requestVals.JsonData3);

                StartProcess(jsonData1, jsonData2, jsonData3);

                var returnData = new
                {
                    Result = "Success",
                    Environment.MachineName,
                    runRequest.TestCaseRunId
                };
                var returnJsonData = JsonConvert.SerializeObject(returnData);
                var returnUtfData = Encoding.UTF8.GetBytes(returnJsonData);

                context.Response.StatusCode = (int) HttpStatusCode.OK;
                context.Response.StatusDescription = "OK";
                context.Response.ContentType = "text/html";
                context.Response.Body = new MemoryStream();
                context.Response.Body.Write(returnUtfData, 0, returnUtfData.Length);
                context.Response.Body.Flush();
                context.Response.Body.Position = 0;
                context.Response.KeepAlive = false;
                return;
            }
            else
            {
                var buffer = Encoding.UTF8.GetBytes("<html><head></head><body><h1>500 - Server Error</h1></body></html>");
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
                context.Response.StatusDescription = "Bad Request";
                context.Response.ContentType = "text/html";
                context.Response.Body = new MemoryStream();
                context.Response.Body.Write(buffer, 0, buffer.Length);
                context.Response.Body.Flush();
                context.Response.Body.Position = 0;
                context.Response.KeepAlive = false;

                Notify("Invalid Request method:" + context.Request.Method + " Url: " + context.Request.Uri.AbsoluteUri);
                return;
            }
        }
        catch (Exception ex)
        {
            TrySendErrorOrWriteEventLog(ex);

            try
            {
                var buffer =
                    Encoding.UTF8.GetBytes("<html><head></head><body><h1>500 - Server Error</h1>Error processing request:" +
                    context.Request.Method + " Error: " + ex.Message + "</body></html>");
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
                context.Response.StatusDescription = "Internal Server Error";
                context.Response.ContentType = "text/html";
                context.Response.Body.Write(buffer, 0, buffer.Length);
                context.Response.Body.Flush();
                context.Response.Body.Position = 0;
            }
            catch { }
            return;
        }
    }

EDIT:
I will leave this open in case someone needs it (and it gets answered - jgauffin?), however, I found a simple solution for creating a listener that did not require elevated privileges at this CodeProject page. It is a very straightforward solution and with one change it works very well. The one issue I had with it is that it won't shut down. It needs this added to the listener loop:

public abstract class SimpleHttpServer {

    protected int port;
    private TcpListener _listener;

    // this lets us call in with Listener.Server.Close(); when we want to shutdown
    public TcpListener Listener { get { return _listener; } }
    public bool IsActive { get; set; }

    public SimpleHttpServer(int port) 
    {
        this.port = port;
    }

    public void listen()
    {
        IsActive = true;
        _listener = new TcpListener(port);
        _listener.Start();
        while (IsActive) 
        {
            try
            {
                TcpClient s = _listener.AcceptTcpClient();
                SimpleHttpProcessor processor = new SimpleHttpProcessor(s, this);
                Thread thread = new Thread(new ThreadStart(processor.process));
                thread.Start();
                Thread.Sleep(1);
            }
            catch (Exception ex)
            {   // shutdown requested?
                if (ex.Message.Contains("A blocking operation was interrupted by a call to WSACancelBlockingCall"))
                    return;
            }
        }
    }

    public abstract void handleGETRequest(SimpleHttpProcessor p);
    public abstract void handlePOSTRequest(SimpleHttpProcessor p, StreamReader inputData);
}

Then in your shutdown include something like this:

        simpleHttpServer.Listener.Server.Close();
        if (!thread.Join(10000)) // try to wait for it...
            thread.Abort();
        simpleHttpServer = null;

Hope this is helpful to another in the same search as I was. This took way longer than it should have.

Missing Stop() method

There is no Stop() method in HttpServer and I can't find another way to stop the server once started.

Routing not working

Routing is not working. I'm playing around with the DefaultDocumentRouter. Here's the program flow:

IRequestRouter.Route -> true
IRoutingModule.Route -> ModuleResult.Stop
IModuleManager.InvokeRouting ->  ModuleResult.Stop
IModuleManager.InvokeModules ->  false
IModuleManager.InvokeAsync ->  canContinue = false  ==  PROBLEM!!!

So, since canContinue is false, no more modules in the pipeline will be processed. I guess that's not the intended behaviour?

Semaphore exception when serving partical large files

when I was tried to request for a large .mp4 file from my server, the exception occurred.
I visited the url from localhost with Google Chrome, which can play .mp4 files directiy. But if I drug the progress bar for over 5 times, the server application crashed.
My code:
ModuleManager mmgr=new ModuleManager(); Griffin.WebServer.Files.DiskFileService fserv=new Griffin.WebServer.Files.DiskFileService("/","E:\\www"); Griffin.WebServer.Files.MimeTypeProvider.Instance.Add("mp4","video/mp4"); Griffin.WebServer.Files.FileModule fmodule=new Griffin.WebServer.Files.FileModule(fserv); mmgr.Add(fmodule); HttpServer server=new HttpServer(mmgr); // TODO: Implement Functionality Here server.Start(IPAddress.Parse("127.0.0.1"),8000);
screenshot of the exception:
image

WebServer crashed because HTTP 1.0

My code as below

   // Module manager handles all modules in the server
   var moduleManager = new ModuleManager();

   moduleManager.Add(new BodyDecodingModule(new UrlFormattedDecoder()));
   MyModule myM = new MyModule();
   moduleManager.Add(myM);
   // And start the server.
   HttpServer _server = new HttpServer(moduleManager);                    
   _server.Start(IPAddress.Any, 8088);



  public class MyModule : IWorkerModule
 {
    public ModuleResult HandleRequest(IHttpContext context)
    {
        IRequest msg = context.Request;
        if (msg.Method == "GET")
        {
            byte[] byContent = Encoding.UTF8.GetBytes("welcome, my friend");
            context.Response.Body = new MemoryStream();
            context.Response.ContentType = "text/html; charset=UTF-8";
            context.Response.Body.Write(byContent, 0, byContent.Length);
            context.Response.Body.Position = 0;
        }
        else if (msg.Method == "POST")
        {
            if (msg.ContentLength > 0 && msg.Body != null)
            {
                var buff = new byte[msg.ContentLength];
                msg.Body.Read(buff, 0, msg.ContentLength);
                Encoding codeM = Encoding.GetEncoding("utf-8");
                string strContent = codeM.GetString(buff);
                OutputMessage(string.Format("Content:{0}", strContent));
            }
        }           
        return ModuleResult.Continue;
    }

}

My application was crashed after received one http request. Logger as below

Method:GET/ContentEncoding:/ContentLength:0
ProtocolVersion:HTTP/1.0/KeepAlive:True/ContentType:
Uri AbsoluteUri:http://58.215.164.183/?signature=1dfea26808d632903549c69d78558fce1c418405&echostr=5867553698596935317&timestamp=1365661332&nonce=1366146317/AbsolutePath://Host:58.215.164.183/Port:80
QueryString/Name:signature/Value:1dfea26808d632903549c69d78558fce1c418405
QueryString/Name:echostr/Value:5867553698596935317
QueryString/Name:timestamp/Value:1365661332
QueryString/Name:nonce/Value:1366146317
Headers/Name:User-Agent/Value:Mozilla/4.0
Headers/Name:Accept/Value:/
Headers/Name:Host/Value:58.215.164.183
Headers/Name:Pragma/Value:no-cache
Headers/Name:Connection/Value:Keep-Alive

FileListing not working if dot in path

Hi, I had a small problem that I wanted to share:

This line of code breaks the directory listing ifa you have a dot in the foldername like

"http//something/mytool/8.0/whatever"

if (context.Request.Uri.AbsolutePath.Contains(":") || context.Request.Uri.AbsolutePath.Contains("."))

I just removed this part for now:

context.Request.Uri.AbsolutePath.Contains("."))

I just started using it since few days and especially because of ssl support, thanks for that, cheers!

IFileService should provide a method to see if a file exists

Having a IFileService.FileExists(Uri uri, string fileName) method would allow re-using the IFileService in the DefaultDocumentRouter (instead of passing a root dir and duplicating the path calculation).

EDIT: The DiskFileService implementation could look something like

/// <summary>
/// Check if the specified url is a directory and if it contains the specified file.
/// </summary>
/// <param name="uri">Uri</param>
/// <param name="fileName">File name</param>
/// <returns></returns>
public bool FileExists(Uri uri, string fileName)
{
    if (fileName == null) return false;

    var path = GetFullPath(uri);

    if (!Directory.Exists(path)) return false;

    return File.Exists(Path.Combine(path, fileName));
}

EDIT 2: Or have two methods

// Check if file or directory exists.
bool Exists(Uri uri);

// Check if uri is directory and contains given file.
bool Exists(Uri uri, string file);

Alternatively, adding GetFullPath to the interface would solve the problem.

Project not compiling

The build is failing since the last commit (6 month ago): DiskFileService and CompositeFileService do not implement IFileService (some interface methods were renamed).

Is this project still active?

Additionally, an updated nuget package would be highly appreciated!

Support for Mono/Linux

Hi,

I've been using Griffin Webserver successfully on Win32 and have now started testing out on Mono/Linux. I had a couple of problems with files in subdirectories which I think were down to path separator differences between the platforms.

To get this going I changed,

DiskFileService.cs

string GetFullPath(Uri uri)
{
            if (!uri.AbsolutePath.StartsWith(_rootUri))
                return null;

            var relativeUri = Uri.UnescapeDataString(uri.AbsolutePath.Remove(0, _rootUri.Length));
            return Path.Combine(_basePath, relativeUri.TrimStart('/').Replace('/', '\\'));
}

to

private string GetFullPath(Uri uri)
{
            if (!uri.AbsolutePath.StartsWith(_rootUri))
                return null;

            var relativeUri = Uri.UnescapeDataString(uri.AbsolutePath.Remove(0, _rootUri.Length));

            return Path.Combine(_basePath, relativeUri.TrimStart('/').Replace('/', Path.DirectorySeparatorChar));
}

I also found I had a problem with a missing / in indexes so changed,

bool TryGenerateDirectoryPage(IHttpContext context)
{
..
            foreach (var file in _fileService.GetFiles(context.Request.Uri))
            {
                var fileUri = context.Request.Uri.AbsolutePath + file.Name;
..

to

bool TryGenerateDirectoryPage(IHttpContext context)
{
..
            foreach (var file in _fileService.GetFiles(context.Request.Uri))
            {
                var fileUri = context.Request.Uri.AbsolutePath + file.Name;
                if (!fileUri.EndsWith("/"))
                    fileUri += "/";
                fileUri += file.Name;
..

Hope this helps.

Cheers,

Alex Lennon

license?

My apologies if I'm just overlooking something, but is this project released under a specific license?

Links From File Listing Leads To Nowhere

I'm trying to set it up to serve some files from my drive, it does list the files correctly
But the links lead to nowhere, it just brings up an empty page and it doesn't even throw any exceptions.
Whenever i click on the link it redirects me to:
http://localhost:8080/HugeFile.zip/HugeFile.zip
However the file is located under drive E:\HugeFile.zip

and this is what i get in the headers of the response:

Request URL: http://localhost:8080/HugeFile.zip/HugeFile.zip
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8080
Referrer Policy: no-referrer-when-downgrade

Response Headers:
Content-Length: 0
X-Pipeline-Index: 1
X-Powered-By: Griffin.Framework (http://github.com/jgauffin/griffin.framework)

Request Headers:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,fa-IR;q=0.8,fa;q=0.6,en;q=0.4
Cache-Control: no-cache
Connection: keep-alive
Cookie: PHPSESSID=g0k6ffthmmcfmoleojp2st84i5
DNT: 1
Host: localhost:8080
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

I tested the sample code provided in project files and got the same results, anyway here's the snippet i currently use (From: blog.gauffin.org):

var moduleManager = new ModuleManager();

var fileService = new DiskFileService("/", "E:");
 var module = new FileModule(fileService) { AllowFileListing = true };
moduleManager.Add(module);

var server = new HttpServer(moduleManager);
server.Start(IPAddress.Any, 8080);

Console.ReadLine();

Are parallel requests supported?

From my experience parallel requests are not supported in the way one would expect. Example: I trigger 3 requests more or less concurrently. Say, each request takes 10 seconds to complete. Now these 3 requests are queued somehow and processed one by one, so that the last one will finish after ~30 seconds.

Am I missing something or is it just not possible to do this parallel?

DiskFileService option to serve .gz versions of files if they exist and the browser accepts gzip streams.

It would be nice if the DiskFileService had an option whereby if the client requests a file, and a pre-compressed .gz version exists and the client specifies that it can accept gzip streams via the Accept-Encoding: gzip header, that it serve that instead.

So if the client requested SomeScript.js and SomeScript.js.gz existed, the .gz version would be served up instead with the Content-Encoding: gzip header to match.

I have created this issue with the intent of implementing this myself.

WebSockets support

It'd be helpful if this could handle websocket upgrade requests, so that when a client attempts to connect and request an upgrade it gets accepted and I get an event raised containing a NetworkStream for me to work with.

TypeLoadException on HttpServer.Start()

First of all thanks for all your work on this nicely written library!

Well, I'm trying to use your HttpServer class to serve a stream to a local device. Because the .Net HttpListener class needs elevated rights to run on any specific URL I quickly started looking at alternatives. So that's when I found your implementation.

I implemented IWorkerModule to handle the requests the way I need. Added it to a ModuleManager and added that to an instance of HttpServer. But the moment I call Start() this System.TypeLoadException is thrown:

Method 'CreateClient' in type 'Griffin.WebServer.HttpServer' from assembly 'Griffin.WebServer, Version=0.5.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

For reference here is my startListening() method:

/// <summary>
/// Start the HTTP request listener.
/// </summary>
public void startListening()
{
    //Add the streaming module to the 
    moduleManager = new ModuleManager();
    moduleManager.Add(new HttpStreamingModule());

    // Create and start the HTTP server
    server = new HttpServer(moduleManager);
    server.Start(IPAddress.Any, 54321);
}

Here is my implementation of the IWorkerModule also:

/// <summary>
/// Server module that handles incoming http requests
/// </summary>
public class HttpStreamingModule : IWorkerModule
{
    #region "Unused IWorkerModule methods"
    public void BeginRequest(Griffin.WebServer.IHttpContext context) { }

    public void EndRequest(Griffin.WebServer.IHttpContext context) { }
    #endregion

    /// <summary>
    /// Handles any incoming client. Prepares the http request and puts the stream in the connected streams.
    /// </summary>
    /// <param name="context">The http request context.</param>
    /// <param name="callback">The async callback, to be called when the operation finishes.</param>
    public void HandleRequestAsync(Griffin.WebServer.IHttpContext context, System.Action<IAsyncModuleResult> callback)
    {
        // Prepping the response headers
        context.Response.ContentType = "audio/mp3";
        context.Response.StatusCode = 200;
        context.Response.StatusDescription = "OK";
        context.Response.KeepAlive = true;

        // Create a new response stream
        context.Response.Body = new System.IO.MemoryStream();

        // Put the response stream in the streams list
        App.Logic.streaming.streams.Add(context.Response.Body);

        // Call the async callback telling the server we are done
        callback(new AsyncModuleResult(context, ModuleResult.Continue));
    }
}

It's probably just something I forgot or misinterpreted from your DemoServer. Oh, I almost forgot, I'm using the NuGet package for Griffin.WebServer.

No files are served with InstallShield deployment of VSTO project

Let me start by thanking you for your webserver. It has been helpful with a project I'm working on but it seems I've hit a wall.

For a while I've been using clickonce deployments to get my VSTO project running on other computers but that method is no longer viable. Therefore, I started using InstallShield to deploy my project (I haven't been able to successfully use the normal Visual Studio setup projects) but since then I've been met with some problems. While so far these problems have been fixable, I cannot find the solution to the most recent issue.

Once my VSTO project has been installed on a non-dev machine with the InstallShield method, the web files that the Webserver should be serving appear to be empty, according to the data shown in Telerik Fiddler. No web files reach their destination despite them being correctly installed in the file system (they appear in the right directory and match the development versions). Furthermore, no error messages pop up at all. The C#/.NET components load perfectly but the web files never seem to load.

Due to the lack of documentation, I haven't been able to understand what the problem is and so, while I try to find a solution myself, I decided to ask for help here in case there's something simple/direct I'm missing in the Webserver settings on my code.

Thank you for your time.

HTTPS port will stop responding after some time.

HTTP port works always. But when I open two ports, one HTTP, one HTTPS or just an HTTPS port the server will stop responding after some time on the HTTPS port while still responding on the HTTP port. Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.