Giter Club home page Giter Club logo

bunkum's Introduction

Bunkum

Nuget downloads Version

A free and open-source protocol-agnostic request server built with flexibility yet ease of use in mind.

Bunkum gives you the freedom to do whatever you need it to do, even if that sort of means breaking the specification of the protocol you're working with. But that's because not every client is compliant, either! ;)

Supported protocols

We support a few protocols out of the box:

  • HTTP
  • Gopher
  • Gemini

You also have the option of writing your own protocol. Bunkum is flexible as long as you stick to the concept of request and response.

Keep in mind that Bunkum primarily uses HTTP as reference for its design. Concepts that work in HTTP might not play nicely with other protocols, and vice versa. We do try to keep alternative protocol support working as best we can though, so if there's a major issue with how you expect a protocol to work then feel free to make an issue

Notable projects using Bunkum

Note If you'd like to show off your project here - don't hesitate to open a pull request!

LittleBigRefresh/Refresh - A second-generation custom server for LittleBigPlanet that focuses on code quality and reliability.

LittleBigRefresh/Refresh.GopherFrontend - A proxy for Refresh ApiV3 that allows Gopher (and soon Gemini) clients to explore Refresh instances. Great example of Bunkum's protocol-agnostic support!

turecross321/SoundShapesServer - A custom server for Sound Shapes

turecross321/K.O.R-Server - Official server for K.O.R

bunkum's People

Contributors

beyley avatar dependabot[bot] avatar jvyden avatar turecross321 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

bunkum's Issues

Rewrite the whole request listening/handling chain

The entire chain of events from invoking the Listener to calling the main middleware is very confusing, even for someone like me who wrote the whole thing and should understand it. It was very hard to debug the fix for 36990eb (and the problem is still unknown...)

We need to reconsider how this flow should work to make it easier to parse. Additionally, it uses a lot of asynchronous calls which causes many headaches, so it should be synchronous like the rest of Bunkum.

The way it's currently implemented, worker threads don't actually mean anything since we just create new tasks on the task factory to handle each request, which is stupid.

Don't Throw IUser Null Warning When Nullable

image
Bunkum will currently throw a warning if the IUser is null on an endpoint that doesn't require authentication. This warning should not appear if the IUser is marked as nullable.

public string YoMan(RequestContext context, IUser user)
{
      // Should throw warning
}
public string YoMan(RequestContext context, IUser? user)
{
      // Should not throw warning
}

Bring all in-house libraries into main Bunkum repository

It's getting very annoying having to manage all these repositories and their versions. It's much better if we can just bring everything into one place and have a unified version number for everything.

  • Copy all code from each repo
  • Make sure CI is capable of supporting this move
  • Add disclaimers to README so we can point to the central Bunkum repo
  • Archive all repos

https://github.com/LittleBigRefresh/Bunkum.RealmDatabase
https://github.com/LittleBigRefresh/Bunkum.ProfanityFilter
https://github.com/LittleBigRefresh/Bunkum.AutoDiscover

Real-time communication support

This will require a lot of thinking - and there's two approaches I can see us taking.

First, we can just let the user manage everything. Pass them a raw socket/stream and let them handle the rest - however this can be a lot of code for simple operations.

The method I want to proceed with is writing a whole API for real-time protocols, like our current API for request protocols.

  • Should this be a separate package? Most of our concepts that apply to a request server do not apply to generic real-time protocols.
  • How do we store and manage connections?
  • How do we manage authentication?
  • How will this tie into Bunkum in general? In other words, how will the request server (Bunkum in its current form) hand off a connection to the real-time server?

Example use-cases that need to be filled by this:

  • Real-time activity stream and notifications in Refresh via WebSockets
  • A chat application that sends/receives messages and events through a WebSocket
  • A custom server for osu! that uses binary data over TCP to communicate

If we end up making the API, we should try to generalize this so the same code can be re-used for multiple protocols, similar to how we manage protocols for the request server.

Bunkum.ProfanityFilter can be bypassed by not using any spaces

The profanity system currently appears to split words by spaces, and check if any of the words contain profanity, and this is pretty easily circumvented.

A user can simply decide to not use spaces in their request, and nothing will be filtered.

image.png

Splitting the string by spaces is obviously to avoid false positives which is a problem that the other method: checking if a string contains profanity at all, does a lot. But I think that it's, in some situations, important that no profanity gets through - even though some false positives will appear.

I therefore suggest implementing an additional setting in the setup, or maybe a parameter in the actual profanity checking, that makes the filter check if the whole string contains any profanity, or if it should split the string by spaces first.

Better Hot Reload

Bunkum applications should be able to better handle a hot reload. Right now, changing code within an endpoint/service will work just fine. But the moment you try to add new ones, it creates problems.

This is because initialization only happens once - at startup. We can detect when a hot reload is triggered and clear Bunkum's internal storage of these endpoints and services by setting a MetadataUpdateHandler (see this stackoverflow answer: https://stackoverflow.com/a/75548913)

This leads to a problem, though. Traditionally, Bunkum applications initialize themselves in Program.cs (or similar) as opposed to something like ASP.NET's startup classes. This means that we won't be able to properly read what's being added at startup without restarting.

We can keep doing it this way for those that don't need the extra hot reload features, but one possible solution to this would be to have a lambda method that can be set that initializes everything. That way, the lambda method can be updated to include new things to be added, like so:

// Traditional Bunkum setup:
BunkumHttpServer server = new();
server.AddEndpointsBlahBlahBlah();
server.AddService<FooService>();

// Proposed Bunkum setup:
BunkumHttpServer server = new();
server.Initialize = () => {
    server.AddEndpointsBlahBlahBlah();
    server.AddService<FooService>();
}

Both methods would still work after implementation of course, but the latter would enable the extra hot reload functionality. When adding new code to this and hot-reloading, the Initialize function would be called again whereas the former would not.

This feels like a slightly dirty solution, but I'm willing to accept anything else that achieves the desired effect. I considered having an abstract class that gets called instead, but that feels even clunkier and less intuitive. Not to mention, that would conflict with the ability to spin up a BunkumHttpServer anywhere (say, unit tests.)

S3 DataStore

While primarily used by Amazon S3, it seems to be a pretty well-adopted API for object storage. We should provide an official integration for it.

Ratelimiting

Can currently be achieved with a middleware, but this is inconvenient

Migration classes

The current system for migrations (having a giant function do everything) is rather messy.

We can improve this by having a class (e.g. Migration) with a function to run the migration logic for us - that way we can look for these classes and have migration steps be in seperate files (much like EntityFramework)

Sending invalid data to socket causes Bunkum's listener to lock up

Video of the bug (courtesy of @turecross321)

2023-05-14_01-30-19.mp4.processed.mp4

Details

image
image

A patch was attempted to be made in v3.1.4 (this commit) , but this was unhelpful in resolving the issue.

Causes

This appears to be mostly caused by an issue with Chrome trying to automatically upgrade the connection to HTTPS, despite the server not supporting HTTPS. The failure is caused due to code when being unable to parse the socket's request line:

[05-13-23 11:51:54] [Request:Error] <<WaitForConnectionAsyncInternal>d__5:MoveNext> Failed to read request line: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Bunkum.CustomHttpListener.Listeners.SocketHttpListener.WaitForConnectionAsyncInternal()

The socket should be closed and it should return to WaitForConnectionAsync and begin accepting sockets again, but this doesn't appear to be the case for some reason.

Filtering user content

There should probably be some filtering in-place for user content, LBP is a kids game after all. User content refers to titles/descriptions, chat messages, comments, basically anything that a user types in a textbox.

What's our stance on this? How far should we go for default behavior - just terrible things like slurs or go all the way with your typical fuck and shit?

Not entirely sure how to implement this code-wise either.

Looking for comments/opinions.

Namespace Specific Serializer Settings

It should be possible to modify the JSON serializer settings for specific namespaces. This way you can, for example, make the server serialize API responses one way and game responses a different way.

Package to serialize Gophermaps as Gemtext

Something we discussed in #50 to enable forwards compatibility on Gopher servers. Ideally you can run two Bunkum servers in one process - one for Gopher and one for Gemini and they handle serialization.

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.