Skip to content

patarapolw/webview-server

Repository files navigation

Practical web server in Golang with clean-up function

So, I tried to write a web server in Golang to fit in with zserge/lorca. Focusing on maximize/fullscreen on all platforms as well.

See the original post.

Tested with cURL's

% PORT=3000 ./webview-server
% curl -i -X PUT --data 'hello' http://127.0.0.1:3000/api/file\?filename\=test.txt

This, by default, works with lokijs, by using a custom adaptor.

import Loki from 'lokijs'

class LokiRestAdaptor {
  loadDatabase (dbname: string, callback: (data: string | null | Error) => void) {
    fetch(`/api/file?filename=${encodeURIComponent(dbname)}`)
      .then((r) => r.text())
      .then((r) => callback(r))
      .catch((e) => callback(e))
  }

  saveDatabase (dbname: string, dbstring: string, callback: (e: Error | null) => void) {
    fetch(`/api/file?filename=${encodeURIComponent(dbname)}`, {
      method: 'PUT',
      body: dbstring
    })
      .then(() => callback(null))
      .catch((e) => callback(e))
  }

  deleteDatabase (dbname: string, callback: (data: Error | null) => void) {
    fetch(`/api/file?filename=${encodeURIComponent(dbname)}`, {
      method: 'DELETE'
    })
      .then(() => callback(null))
      .catch((e) => callback(e))
  }
}

// eslint-disable-next-line import/no-mutable-exports
export let loki: Loki

export async function initDatabase () {
  return new Promise((resolve) => {
    loki = new Loki('db.loki', {
      adapter: new LokiRestAdaptor(),
      autoload: true,
      autoloadCallback: () => {
        resolve()
      },
      autosave: true,
      autosaveInterval: 4000
    })
  })
}

window.onbeforeunload = (e: Event) => {
  if (loki) {
    if (loki.autosaveDirty()) {
      loki.saveDatabase()

      e.preventDefault()
      e.returnValue = false
    }
  }
}

And, in you Webpack dev server (e.g. webpack.config.js)

// @ts-check

/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')

const morgan = require('morgan')

const BINARY_DIR = 'release'

module.exports = {
  devServer: {
    /**
     *
     * @param {import('express').Express} app
     * @param {import('http').Server} server
     * @param {*} compiler
     */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    before (app, server, compiler) {
      app.use('/api', morgan('tiny'))

      app.get('/api/file', (req, res) => {
        /** @type {*} */
        const { filename } = req.query
        const p = path.resolve(__dirname, BINARY_DIR, filename)

        if (fs.existsSync(p)) {
          fs.createReadStream(p).pipe(res)
          return
        }

        res.sendStatus(404)
      })

      app.put('/api/file', (req, res) => {
        /** @type {*} */
        const { filename } = req.query
        const p = path.resolve(__dirname, BINARY_DIR, filename)

        req.pipe(fs.createWriteStream(p))
        res.sendStatus(201)
      })

      app.delete('/api/file', (req, res) => {
        /** @type {*} */
        const { filename } = req.query
        const p = path.resolve(__dirname, BINARY_DIR, filename)

        fs.unlinkSync(p)
        res.sendStatus(201)
      })
    }
  }
}

Web browser in use

Currently, this app doesn't bundle a web browser. Instead, it uses Chrome DevTools Protocol; therefore, either Chrome or Chromium must be installed.

See /deps.md.

Security concerns

I learnt this from pywebview. A major thing about this, is CSRF attack.

Customization

Please see /config/types.go. The easiest way is to create /config.yaml alongside the built webview-server*.

Building

You can also build for your platform, or multiple platforms at once -- take a peek inside robo.yml

Note that executables in macOS can also run in windowed mode (no console), by renaming the extension to *.app. No need to make a folder of *.app/.

I cannot upload *.app directly to GitHub Releases.

darwin binaries can used for macOS, although not built natively on macOS.

About

webview for web servers, with focus on customizability and security

Topics

Resources

License

Stars

Watchers

Forks

Contributors