Giter VIP home page Giter VIP logo

zener's People

Contributors

mcsherry avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

zener's Issues

Reject zero-length variables when matching routes

Presently, Zener will match routes containing variables with paths containing zero-length sections in place of these variables. For example, for the route foo/[var]/baz, the path foo//baz would be considered valid.

Zener should not report zero-length variables such as in foo//baz as a match.

Implement a client-side-accessible events API

An API which allows client-side code (such as JavaScript) to receive events from the server-side would likely be a good addition. The easiest way to implement this would likely be via long polling, where the server responds to the request only when the event is fired.

Add support for HTTP/2

HTTP/2 is currently a Proposed Standard, and will soon be supported in web servers and browsers. It provides improvements over HTTP/1.1 (the version Zener currently targets), so including support for it would be beneficial.

Add support for HTTP pipelining

HTTP pipelining is required for HTTP/1.1 compliance.

Pipelining is where a client sends multiple requests without waiting for a response, and does so over a single connection.This avoids the latency of negotiating a new TCP connection.

iHTTP pipelining diagram

Implement support for HTTP 408/411 (Request Timeout/Length Required)

Zener's current method for retrieving request data (waiting a few milliseconds, then reading until no data is available) is sub-optimal. Should issue #12 be implemented, it is quite possible that this will result in some request data being lost.

To replace the current functionality, Zener should instead use the Content-Length and a (configurable) time-out period. Zener should attempt to read the length specified in this header from the socket until the time-out period has elapsed (whereafter it would respond with the 408 status code), or until all data has been read.

If a client request does not include the Content-Length header, Zener should respond with the 411 status code.

File uploads fail with larger files

After the implementation of #13, which required rewriting how requests are handled, file uploads (using <input type="file"/>) fails with larger files. When a larger file is uploaded, the connection is reset by the server before a response is written.

Add cookie support

Zener does not, presently, support the use of cookies. Supporting cookies would likely be very convenient for any applications using Zener that need temporary storage.

Allow virtual hosts to be named

Presently, there isn't really a good way to access the VirtualHosts in a HostRouter. Adding a Name property to VirtualHost and an indexer this[string name] to HostRouter would make dealing with HostRouter easier.

Implement URL encoding/decoding

Presently, Zener uses the System.Web.HttpUtility class for URL en/decoding. If en/decoding were to be implemented in Zener, this would allow two changes:

  1. A reference to System.Web.dll could be removed; and
  2. Zener could change target from .NET 4.0 to .NET 4.0 Client Profile.

This would have the benefit of allowing use of the Client Profile, which would in turn result in a smaller download for users who do not have the framework installed.

Implement HTTP method constraints for routes

To ease implementation of HTTP APIs that make heavy use of request methods, routes should contain a property which indicates the request method required for the route to match. Additionally, support for routing based on method constraint should be added to the Router and ZenerCore classes.

Add a TOTP / RFC 6238 utility class

TOTP (Time-based One-Time Passwords) are commonly used in two-factor authentication schemes. Adding basic support for TOTP generation/validation would very much be within Zener's remit.

Allow Zener APIs to be disabled

It should be possible to individually disable each of the APIs provided by ZenerCore. This would allow Zener to be used in a greater number of situations (such as when file-system access is not required and having it enabled poses a security risk).

Add HTTP "Accept" header parsing

The HTTP Accept header is used by clients to specify the media types that are acceptable in a response. Including in Zener code to parse this header (which could utilise the MediaType class) would likely save time in a fair few scenarios.

Due to the format of Accept headers, they need some special handling.

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

The inclusion of a q parameter to indicate preference means that some additional code is required to separate the parameter before passing the string to MediaType.Create, as otherwise MediaType.Create would either throw an exception or erroneously interpret the q parameter as a media type parameter.

Implement support for the TAR.GZ containers

To allow assets embedded in software to be compressed, Zener should support the gzip container with DEFLATE compression. This would permit use of the extremely common .tar.gz format.

Implement support for ustar

Presently, Zener supports the UNIX V6 tar (tape archive) format. However, most modern archivers will create ustar archives, which contain additional information (such as file name prefixes). To ease use, Zener should support ustar as well as tar.

Improve support for persistent HTTP connections

Presently, Zener's support for persistent connections is fairly spartan. It will check once, after the response has been sent, whether the client has sent any more data. If it has, it will attempt to process it as a response. Otherwise, it will close the connection.

Instead of doing this, the Zener should instead have a time-out for persistent connections. A reasonably short period of time after processing the request in which, at any time, the client may send data and have it processed. Suggested time-out value is between 5 and 15 seconds.

Add support for ZIP files

ZIP is an extremely common archive/compression format, and so it being supported would be a good addition to Zener.

Correctly handle binary form data

At the moment, Zener does not correctly handle multipart/form-data parts with binary content. When confronted with a part that has a non-text/* media type, it will just discard it. As mentioned in the linked lines of code, an API for transmitting binary data is something to consider in future, but supporting binary form data should also be considered.

Implement a client-side-accessible file system API

As Zener acts only as the HTTP server, any code that can access the user's file system can only execute before a response is served. A client-side accessible (i.e. from JavaScript, via AJAX/XmlHttpRequest, or similar) file system API allows software to access the file system without requiring a page refresh.


Interface

The API should be accessed via the :fs route. The specifics of passing parameters to this route are not yet defined, but it should be able to accept relative paths (e.g. foo.txt would access a file in the application's working directory) and absolute paths (e.g. C:\Program Files\FooApp\Baz.txt).

Different file system operations are specified using the HTTP method (verb), as given below.

  • GET – Open (if file exists) and read.
  • HEAD – Check if the file exists.
  • POST – (Over)write the file, creating it if it does not exist.
  • DELETE – Delete the file.

If the provided path is a path to a directory, the API will return two arrays of strings, one containing the files in the directory and the other the names of all subdirectories. For example, a query to C:\Program Files\FooApp might return:

{
    "files": [
        "Baz.txt", "config.ini"
    ],
    "directories": [
        "assets", "scripts"
    ]
}

Method semantics for directory paths are as follows.

  • GET – Retrieve the contents of a directory.
  • HEAD – Check a directory exists.
  • DELETE – Delete a directory and all subitems.

Remove leading numerals on POST/GET variables

Currently, Zener's HttpRequest class filters the characters present in variables sent in POST data and GET query strings. For example, a variable named user-name would be renamed username. While this catches most cases, it doesn't catch them all.

C# permits the use of numerals in identifiers (e.g. int saturn5height = 363), but only if they are not at the start of the identifier. Zener should, in addition to filtering out characters which are entirely prohibited, filter out numerals from the start of a string (5livelive).

Support HTTP compression

HTTP compression is something that should be supported. Minimally, Zener should support deflate and gzip encoding.

This is likely to require that HttpResponse be passed an HttpRequest on creation. This would allow the HttpResponse to determine the best algorithm to use based on the request headers without user interaction. Compression could then be enabled or disabled via a HttpResponse.Compression property.

Allow binding to non-loopback addresses

Currently, Zener will only bind to loopback addresses (127/8 or ::1/128), which can limit its uses. Changes should be made to allow Zener to bind to non-loopback addresses.

Allow access to the underlying response stream

In HttpResponse, it should be possible to access the underlying NetworkStream. This makes easier the use of Upgrade headers, and allows upgrading to binary/non-HTTP-based protocols.

Considerations:

  • Output buffering
  • Functionality when the response stream is not a NetworkStream. The Stream passed to HttpResponse is not required to be a NetworkStream, and it is possible that a MemoryStream (or another type of stream) could be passed to the HttpResponse.
  • Checking whether the programmer has closed the underlying Stream. Presently, without the Stream exposed, the HttpResponse can assume the Stream is open until a private field indicates otherwise. With the Stream exposed, further checks will need to be made.

Support q-values in headers

Various HTTP headers use q-values to indicate preference. For example:

Accept-Encoding: gzip; q=0, deflate; q=0.5, compress;q=0.8

In this header, gzip encoding is not acceptable (the q-value is 0), and compress is preferred over deflate encoding (because the q-value for compress is greater than the q-value for deflate).

Special handling is required due to possible ambiguity with media types. See below.

Accept: text/example; param=value; q=0.5, application/example; q=0.2

Support multi-line HTTP headers

The HTTP spec defines multi-line headers:

Header fields can be extended over multiple lines by preceding each extra line with at least one SP or HT.

Zener does not currently support this, but it should be implemented at some point to ensure full compatibility.

Implement support for media type handlers

To increase extensibility, one should be able to bind handlers for specific media types via the MediaTypeMap class. This would, for example, allow a user to add to the Routing.MediaTypes a handler for .php files. This handler could then implement a PHP parser/engine.

Allow unbounded variables in format strings

Zener's route format strings can include variables. However, these variables cannot contain forward-slashes (/), which can limit some applications. In order to permit the use of forward-slashes, a second type of variable needs to be defined.

Shown below is an example of current variable declaration in format strings. In this example, [variable] can be replaced with any string which does not contain a /.

foo/[variable]/baz

Below is the proposed format for unbounded variables, which would permit the use of a /.

foo/[*variable]

As any character can be used in unbounded variables, they must be placed at the end of a format string. A format string such as foo/[*variable]/baz would never have a match.

Implement virtual hosting

Virtual hosting (vhosting) is where the server uses the value of the HTTP Host header to host multiple websites on multiple domains from a single IP address. This is a fairly standard feature with HTTP servers, and its inclusion should be considered.

Considerations:

  • Including variables in virtual host domains (e.g. [variable].example.com).
  • Default virtual host to match any/all unrecognised Hosts.

Improve HTTP/1.0 support

Zener currently implements HTTP/1.1 (more or less), but should implement (or at least attempt to support) HTTP/1.0 to ensure that older clients can at least communicate with Zener (HTTP/1.0 clients aren't guaranteed to support chunked encoding or persistent connections, for example).

For ease, it would probably be best to implement a class Rfc2616Serialiser as a subclass of Rfc7230Serialiser. This would reduce duplicate code, and would mean that support could be implemented by restricting which features can be enabled.

Replace string comparison of media types with MediaType class

In various locations throughout Zener's code, media types sent by the client are checked as strings rather than as MediaTypes. These instances of string comparison should be replaced with uses of the MediaType class and its IsEquivalent method.

Add support for HTTP HEAD requests

Presently, Zener's HTTP server will not correctly handle HEAD requests. For a reasonable amount of compliance, HEAD should be supported.

Allow serving from a (compressed) container

Allowing serving files from a container (such as ZIP, 7z, etc), preferably a compressed one, would make easier the shipping of resource files (HTML, CSS, JS, etc) with applications using Zener.

Add unit tests

Presently, Zener's code has no unit tests. To ensure code quality, unit tests should be added and build systems should be configured to run them.

Implement a client-side-accessible method call API

To further ease communication between client-side and application-side, an API accessible through client-side technologies (such as JavaScript) which provides the ability to call a set of methods (specified by the developer) is likely to be a useful addition.

This API should use the :call route. Parameters should be passed via the query string (GET variables). The API should only accept calls that use the GET method, and should return values in JSON. Every response must contain __return name-value pair indicating whether the call generated any return values. The __return pair must have boolean values.

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.