Giter VIP home page Giter VIP logo

danode's Introduction

DaNode - A secure and small footprint web server for D

master: D licence: license

Web server written in the D programming language to host server side web applications (written in any programming language) on multiple domains. It provides encrypted HTTP content over SSL using Server Name Identification, and has been battle tested in production for over 5 years hosting several of my web domains, such as my own personal website.

Written because I was looking for a quick way of sharing Rscript output with other researchers at different universities. Once working I wanted to use other programming languages as well and added generic support for other languages. Use any language to write your SSL encrypted homepage, why not brainfuck, however Ada, R or PHP are also fine.

The web servers main features / aims summarized:

Get DaNode

Install the DMD compiler from https://dlang.org/

Clone the source code from Github

git clone https://github.com/DannyArends/DaNode.git
cd DaNode

Build DaNode using the dub package manager

dub build

Another option is to compile using the compile script

./sh/compile

Start the web server at a specific port (e.g. 8080)

./danode/server -p 8080

Confirm that the web server is running by going to: http://localhost:8080/

Enable HTTPs support

To compile the server with HTTPS support (binds to port 443), use dub and specify the ssl configuration:

dub build --config=ssl

or, compile using the compile script:

./sh/compile ssl

Start the web server on port 80 and 443:

./danode/server

After starting the server, confirm that the web server is running by going to http://127.0.0.1/ and https://127.0.0.1/ and make sure you have enough user rights to bind port 80 and 443, a server private key and domain certificates are required. I use Let's Encrypt to secure my own homepage. Setup instructions for Let's Encrypt can be found in the sh/letsEncrypt file.

Troubleshooting: [ERROR] unable to bind socket on port 80

Starting the server on port 80 and 443 might fail, when you do not have appropriate rights on the system. First check if you can start the server on another port:

./danode/server -p 8080

I use nohup and authbind to start the web server in deamon (background) mode at port 80, and 443 (SSL). First, install nohup and authbind via your package manager, configure authbind to allow connections to port 80 (and 443, when using the ssl version), then start the webserver by running:

./sh/run
Command-line parameters

The content of the ./sh/run shell script:

nohup authbind danode/server -k -b 100 -v 2 > server.log 2>&1 &

This starts the server, does not allow for keyboard command (-k) has a backlog (-b) of 100 simultaneous connection (per port), and produces more log output (-v 2).

      --port      -p       HTTP port to listen on (integer)
      --backlog   -b       Backlog of clients supported simultaneously per port (integer)
      --keyoff    -k       Keyboard input via STDIN (boolean)
      --certDir            Location of folder with SSL certificates (string)
      --keyFile            Server private key location (string)
      --wwwRoot            Server www root folder holding website domains (string)
      --verbose   -v       Verbose level, logs on STDOUT (integer)
Example websites

See the www/ folder for a number of example web sites. After compiling the web server, run the web server and the www/localhost/ folder is available at http://localhost/ or http://127.0.0.1/ from the browser. For the other examples in the www/ folder you will have to update your hosts file.

Create a PHP enabled website

To create a simple PHP enabled web site first download and install DaNode, the next step is to create a directory for the new website, by executing the following commands from the DaNode directory:

mkdir www/domain.xxx
touch www/domain.xxx/index.php

Add some php / html content to the index page, and create a web.config file:

touch www/domain.xxx/web.config

Add the following configuration settings to the web.config file, if you want to use scripting languages such as PHP, you have to manually allow the execution of cgi file. Add the following lines in your web.cofig file to redirect to the index.php file, and allow the webserver to execute the php script, and redirect the incomming requests to the index.php page:

allowcgi     = yes
redirecturl  = index.php
Update the hosts file

If you do not own the domain name you want to host, use the /etc/hosts file to redirect requests from the domain name to your local IP address using the hosts file:

sudo nano /etc/hosts

Then add the following lines to this hostfile using your favourite editor:

127.0.0.1   domain.xxx
127.0.0.1   www.domain.xxx

Save the file with these lines added, then open a browser and navigate to: http://www.domain.xxx, you should now see the content of your php / html file.

Supported back-end languages

Languages with supported APIs: PHP, PYTHON, D, R

See: api/README.md

Contributing

Want to contribute? Great! Contribute to DaNode by starring or forking on Github, and feel free to start an issue or sending a pull request.

Fell free to also post comments on commits.

Or be a maintainer, and adopt (the documentation of) a function.

License

DaNode is written by Danny Arends and is released under the GNU GENERAL PUBLIC LICENSE Version 3 (GPLv3). See LICENSE.txt.

danode's People

Contributors

dannyarends 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

danode's Issues

Chrome [HTML5] Video Tag does not allow to control a video

Low importance issue.

[issue's title says it all, look up the video below.]

Somehow I suspect that this has to do with the Web Server. (DaNode)
Haven't tested on Apache or other Web Servers yet.
But it (HTML video tag) seems to work perfectly for everyone else that do not use DaNode.

2021-12-20.14-36-27.mp4

Guide to reproduce
Temporary live version. (1-2 days)

  1. This is what I've used.
<video width="320" height="240" controls>
  <source src="1.mp4" type="video/mp4">
  <source src="1.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
  1. Now place a video .mp4 file named 1.mp4 in the same folder alongside.
  2. Place it in the DaNode www/*/ folder
  3. Test things out and see that you can't control the video.

Erroneous HTML date from browsers can cause "304 Not Modified" response optimization to be disabled

After adding index.html file and visiting the 78.150.536.25/index.html via a browser I get this error.

image

More photos:
image

Also I've noticed that I get an error on startup and every time I try to visit a web page.

[WARN]   unknown client exception: core.time.TimeException@std/datetime/date.d(3776): 255 is not a valid month of the year.
----------------
??:? pure @safe void std.datetime.date.enforceValid!("months").enforceValid(int, immutable(char)[], ulong) [0x559cb55792e3]
??:? pure ref @safe std.datetime.date.Date std.datetime.date.Date.__ctor(int, int, int) [0x559cb5577b86]
??:? pure ref @safe std.datetime.date.DateTime std.datetime.date.DateTime.__ctor(int, int, int, int, int, int) [0x559cb5577365]
danode/functions.d:23 std.datetime.systime.SysTime danode.functions.parseHtmlDate(const(immutable(char)[])) [0x559cb547d9ed]
danode/request.d:145 const @property std.datetime.systime.SysTime danode.request.Request.ifModified() [0x559cb554d33c]
danode/response.d:175 void danode.response.serveStaticFile(ref danode.response.Response, in danode.request.Request, danode.filesystem.FileSystem) [0x559cb554f6ec]
danode/router.d:105 void danode.router.Router.deliver(ref danode.request.Request, ref danode.response.Response, bool) [0x559cb5550352]
danode/router.d:55 void danode.router.Router.route(danode.interfaces.DriverInterface, ref danode.request.Request, ref danode.response.Response, long) [0x559cb554fe0f]
danode/client.d:44 void danode.client.Client.run() [0x559cb547be76]
??:? void core.thread.context.Callable.opCall() [0x559cb5560fe4]
??:? thread_entryPoint [0x559cb5560ac2]
??:? [0x7fc04afe8fa2]
??:? clone [0x7fc04ad6d4ce]
[WARN]   unknown client exception: core.time.TimeException@std/datetime/date.d(3776): 255 is not a valid month of the year.
----------------
??:? pure @safe void std.datetime.date.enforceValid!("months").enforceValid(int, immutable(char)[], ulong) [0x559cb55792e3]
??:? pure ref @safe std.datetime.date.Date std.datetime.date.Date.__ctor(int, int, int) [0x559cb5577b86]
??:? pure ref @safe std.datetime.date.DateTime std.datetime.date.DateTime.__ctor(int, int, int, int, int, int) [0x559cb5577365]
danode/functions.d:23 std.datetime.systime.SysTime danode.functions.parseHtmlDate(const(immutable(char)[])) [0x559cb547d9ed]
danode/request.d:145 const @property std.datetime.systime.SysTime danode.request.Request.ifModified() [0x559cb554d33c]
danode/response.d:175 void danode.response.serveStaticFile(ref danode.response.Response, in danode.request.Request, danode.filesystem.FileSystem) [0x559cb554f6ec]
danode/router.d:105 void danode.router.Router.deliver(ref danode.request.Request, ref danode.response.Response, bool) [0x559cb5550352]
danode/router.d:55 void danode.router.Router.route(danode.interfaces.DriverInterface, ref danode.request.Request, ref danode.response.Response, long) [0x559cb554fe0f]
danode/client.d:44 void danode.client.Client.run() [0x559cb547be76]
??:? void core.thread.context.Callable.opCall() [0x559cb5560fe4]
??:? thread_entryPoint [0x559cb5560ac2]
??:? [0x7fc04afe8fa2]
??:? clone [0x7fc04ad6d4ce]
[WARN]   unknown client exception: core.time.TimeException@std/datetime/date.d(3776): 255 is not a valid month of the year.
----------------
??:? pure @safe void std.datetime.date.enforceValid!("months").enforceValid(int, immutable(char)[], ulong) [0x559cb55792e3]
??:? pure ref @safe std.datetime.date.Date std.datetime.date.Date.__ctor(int, int, int) [0x559cb5577b86]
??:? pure ref @safe std.datetime.date.DateTime std.datetime.date.DateTime.__ctor(int, int, int, int, int, int) [0x559cb5577365]
danode/functions.d:23 std.datetime.systime.SysTime danode.functions.parseHtmlDate(const(immutable(char)[])) [0x559cb547d9ed]
danode/request.d:145 const @property std.datetime.systime.SysTime danode.request.Request.ifModified() [0x559cb554d33c]
danode/response.d:175 void danode.response.serveStaticFile(ref danode.response.Response, in danode.request.Request, danode.filesystem.FileSystem) [0x559cb554f6ec]
danode/router.d:105 void danode.router.Router.deliver(ref danode.request.Request, ref danode.response.Response, bool) [0x559cb5550352]
danode/router.d:55 void danode.router.Router.route(danode.interfaces.DriverInterface, ref danode.request.Request, ref danode.response.Response, long) [0x559cb554fe0f]
danode/client.d:44 void danode.client.Client.run() [0x559cb547be76]
??:? void core.thread.context.Callable.opCall() [0x559cb5560fe4]
??:? thread_entryPoint [0x559cb5560ac2]
??:? [0x7fc04afe8fa2]
??:? clone [0x7fc04ad6d4ce]
[WARN]   unknown client exception: core.time.TimeException@std/datetime/date.d(3776): 255 is not a valid month of the year.
----------------
??:? pure @safe void std.datetime.date.enforceValid!("months").enforceValid(int, immutable(char)[], ulong) [0x559cb55792e3]
??:? pure ref @safe std.datetime.date.Date std.datetime.date.Date.__ctor(int, int, int) [0x559cb5577b86]
??:? pure ref @safe std.datetime.date.DateTime std.datetime.date.DateTime.__ctor(int, int, int, int, int, int) [0x559cb5577365]
danode/functions.d:23 std.datetime.systime.SysTime danode.functions.parseHtmlDate(const(immutable(char)[])) [0x559cb547d9ed]
danode/request.d:145 const @property std.datetime.systime.SysTime danode.request.Request.ifModified() [0x559cb554d33c]
danode/response.d:175 void danode.response.serveStaticFile(ref danode.response.Response, in danode.request.Request, danode.filesystem.FileSystem) [0x559cb554f6ec]
danode/router.d:105 void danode.router.Router.deliver(ref danode.request.Request, ref danode.response.Response, bool) [0x559cb5550352]
danode/router.d:55 void danode.router.Router.route(danode.interfaces.DriverInterface, ref danode.request.Request, ref danode.response.Response, long) [0x559cb554fe0f]
danode/client.d:44 void danode.client.Client.run() [0x559cb547be76]
??:? void core.thread.context.Callable.opCall() [0x559cb5560fe4]
??:? thread_entryPoint [0x559cb5560ac2]
??:? [0x7fc04afe8fa2]
??:? clone [0x7fc04ad6d4ce]

"dub build" doesn't compile - dmd failed with exit code 1.

@DannyArends

λ cd .\Temp\Git
​C:\Temp\Git

λ git clone https://github.com/DannyArends/DaNode.git
Cloning into 'DaNode'...
remote: Enumerating objects: 35, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (24/24), done.
Rremote: Total 2006 (delta 17), reused 24 (delta 11), pack-reused 1971eceiving objects: 99% (1986/2006)
Receiving objects: 100% (2006/2006), 419.11 KiB | 1.15 MiB/s, done.
Resolving deltas: 100% (1356/1356), done.

λ cd DaNode
​C:\Temp\Git\DaNode [master ≡]

λ dub build
Performing "debug" build using dmd for x86_64.
danode ~master: building configuration "default"...
danode\cgi.d(110,58): Error: template std.math.fmin cannot deduce function from argument types !()(long, ulong), candidates are:
C:\Users\me\scoop\apps\dmd\current\windows\bin....\src\phobos\std\math.d(7267,3): fmin(F)(const F x, const F y)
with F = ulong
must satisfy the following constraint:
__traits(isFloating, F)
danode\filesystem.d(118,76): Error: template std.math.fmin cannot deduce function from argument types !()(long, ulong), candidates are:
C:\Users\me\scoop\apps\dmd\current\windows\bin....\src\phobos\std\math.d(7267,3): fmin(F)(const F x, const F y)
with F = ulong
must satisfy the following constraint:
__traits(isFloating, F)
danode\filesystem.d(120,70): Error: template std.math.fmin cannot deduce function from argument types !()(long, ulong), candidates are:
C:\Users\me\scoop\apps\dmd\current\windows\bin....\src\phobos\std\math.d(7267,3): fmin(F)(const F x, const F y)
with F = ulong
must satisfy the following constraint:
__traits(isFloating, F)
danode\payload.d(42,48): Error: template std.math.fmin cannot deduce function from argument types !()(long, ulong), candidates are:
C:\Users\me\scoop\apps\dmd\current\windows\bin....\src\phobos\std\math.d(7267,3): fmin(F)(const F x, const F y)
with F = ulong
must satisfy the following constraint:
__traits(isFloating, F)
dmd failed with exit code 1.


systeminfo - OS Version: 10.0.19042 N/A Build 19042

λ dmd --version
DMD32 D Compiler v2.094.2-dirty
Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved written by Walter Bright

λ dub --version
DUB version 1.23.0, built on Nov 20 2020

.mp4 file is not accessible | 403 - Access to this resource has been restricted

Now who would not want to have an accessible video file.
Today I really had a need to test out if DaNode would let me look at things such as images and videos on the web server.
After some uploads, only the .png image file was accessible. The .mp4 file was blocked off. Not sure how to go about it.

image

http://78.140.136.25/1.mp4 This is a working link to a file that is .mp4 media. (Resource is Inaccessible)

http://78.140.136.25/2.png Now the .png media file seems to show properly. (Resource is Accessible)


I suspect that mimetypes.d are lacking entry of .mp4
https://github.com/DannyArends/DaNode/blob/b12e8950e90ffaf9f86f5cf6c72d0bd2e5f08d8f/danode/mimetypes.d

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.