Transfer your ghost server between hosts

Assume you have a ghost server ran at a host machine.
Oneday the host machine maybe out of space or you find a new cheap host,
or you have a new host that have power memory and performance.
Then you may need to transfer your ghost server to another new host.

tar your ghost server to a *.tar.gz

//blog is my ghost server root directory
$cd www/blog
$tar -zcvf blog.tar.gz blog
copy the blog.tar.gz to the new host

preinstall on new host

nginx
sudo apt-get install nginx
node.js
https://nodejs.org/en/download/
extract and add node bin path to env
ghost
npm i -g ghost-cli 
acme.sh
https://github.com/Neilpang/acme.sh

configure on new host

tar cvf blog.tar.gz 

nginx conf

sudo ln -sf blog/system/files/blog.conf /etc/nginx/sites-available/blog.conf
sudo ln -sf /etc/nginx/sites-available/blog.conf /etc/nginx/sites-enabled/blog.conf

start http server

ghost start 
if you encounter systemd error, just follow the hint command(ghost linuxuser systemd) by ghost
and run ghost start again.
Before you start your ghost server, you should change the DNS record for your server. Since you changed host, the IP would changed.

enable https server via letsencrypt

sudo ln -sf blog/system/files/blog-ssl.conf /etc/nginx/sites-available/blog-ssl.conf
sudo ln -sf /etc/nginx/sites-available/blog-ssl.conf /etc/nginx/sites-enabled/blog-ssl.conf
acme.sh --issue --home /etc/letsencrypt --domain errong.win --webroot /home/errong_leng/www/blog/system/nginx-root --reloadcmd "nginx -s reload" --accountemail errong.leng@gmail.com

http nginx conf

server {
    listen 80;
    listen [::]:80;

    server_name errong.win;
    root /home/errong_leng/www/blog/system/nginx-root;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:6666;
        
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

https nginx conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name errong.win;
    root /home/errong_leng/www/blog/system/nginx-root;

    ssl_certificate /etc/letsencrypt/errong.win/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/errong.win/errong.win.key;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:6666;
        
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

setup shadowsocks server on ubuntu 16.04

install

sudo apt-get install software-properties-common -y
sudo add-apt-repository ppa:max-c-lv/shadowsocks-libev -y
sudo apt-get update
sudo apt install shadowsocks-libev

configure

sudo vim /etc/shadowsocks-libev/config.json
{
    "server":"10.128.0.2",
    "server_port":8911,
    "local_port":1008,
    "password":"jesusislove",
    "timeout":60,
    "method":"chacha20-ietf-poly1305"
}

start server

sudo systemctl start shadowsocks-libev

google compute engine

If the server are running on a google compute engine,
You need to setup a firewall rules for the server port(8911, written in config.json).
shadowsocks
Apply to all
IP ranges: 0.0.0.0/0
tcp:8911, udp:8911
Allow

client configuration

iOS
Android
Shadowsocks for Android / iOS also accepts BASE64 encoded URI format configs:
ss://BASE64-ENCODED-STRING-WITHOUT-PADDING#TAG 
Where the plain URI should be:
ss://method:password@hostname:port 
Quick Guide

他的力量若不够

利未记五7、11

7「他的力量若不够献一只羊羔,就要因所犯的罪,把两只斑鸠或是两只雏鸽带到耶和华面前为赎愆祭:一只作赎罪祭,一只作燔祭。

11「他的力量若不够献两只斑鸠或是两只雏鸽,就要因所犯的罪带供物来,就是细面伊法十分之一为赎罪祭;不可加上油,也不可加上乳香,因为是赎罪祭。


Photo by Brooke Lark / Unsplash

expressjs : implement http file download

Express helper, res.download

Express has a helper for this:
app.get('/xxx', function(req, res){ 
  var file = __dirname + '/xxx'; 
  res.download(file); // Set disposition and send it. 
}); 

http file download header

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
res.setHeader('Content-disposition', 'attachment; filename=xxx'); 

iptables, clean all rules

command

sudo iptables -P INPUT ACCEPT
sudo iptables -F

list all rules

sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination

node.js : file upload via express and multer

Form-based File Upload in HTML

https://tools.ietf.org/html/rfc1867

Express

Fast, unopinionated, minimalist web framework for node.

Multer

Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of busboy for maximum efficiency.
NOTE: Multer will not process any form which is not multipart (multipart/form-data).

Client Codes(index.html)

<script type="text/javascript">
function upload(postUrl, fieldName, files)
{
  var formData = new FormData();
  formData.append(fieldName, files);

  var req = new XMLHttpRequest();
  req.open("POST", postUrl);
  req.onload = function(event) { console.log(event.target.responseText); };
  req.send(formData);
}
function onchange() {
  for (let i = 0; i < this.files.length; i++) {
    upload('/uploads', 'uploadfile', this.files[i]);
  }
}
window.onload = function () {
var  input = document.getElementById('file');
input.addEventListener('change', onchange);
}
</script>
<input type="file" id="file" name="file" multiple onchange="upload" />

Server Codes

var express = require('express')
var app = express()
var path = require('path')
var tmpdir = require('os').tmpdir
var upload = require('multer')({dest: tmpdir()})

app.get('/', function (req, res) {
  var indexhtml = 'index.html';
  var tmp = path.resolve(indexhtml);
  res.sendFile(tmp);
})

app.post('/uploads', upload.single('uploadfile'), function (req, res, next) {
  var rp = {'file':req.file, 'body' : req.body, 'ip':req.ip};
  res.send(rp);
})

app.listen(3000)

Run express Server

node index.js

Test

upload
As you can see in the console, the file was uploaded to server and saved with file name of "/tmp/e2f2d3ae260814fc4b589a13d5981aec".

Print all combination of that select n elements from 1,2,3,...,m.

"C" is for "combination". A combination is an un-ordered collection of distinct elements, usually of a prescribed size and taken from a given set.

   C(n, r) = n!/[r!(n-r)!] 
 
#include <stdio.h>
#include <sys/time.h>

int a[1001];

// selected n numbers stored in array a
// a[1], a[2], ... , a[n]
// a[i+1] > a[i]
// a[i] - i <= m - n + 1

void comos(int n, int m) {
  int i,j;
  if (n > m)
    return;
  for (i = 1; i <= n; i++) {
    a[i] = i;
  }
  int cur = n;
  do {
    if (a[cur]-cur <= m - n) {
      for (i = 1; i <= n; i++)
        printf("%d ", a[i]);
      printf("\n");
      a[cur]++;
      continue;
    } else {
      if (cur == 1) {
        break;
      }
      a[--cur]++;
      for (i = 1; i <= (n-cur); i++)
        a[cur+i] = a[cur] + i;
      if (a[cur] - cur < m - n + 1)
        cur=n;
    }
  } while(1);
}

int main() {
  int N, M;
  while (scanf("%d %d", &N, &M) != EOF) {
    if (N <= M) {
      struct timeval begin, end;
      gettimeofday(&begin, 0);
      comos(N, M);
      gettimeofday(&end, 0);
      printf("print comos(%d, %d) used %ld microseconds\n", N, M, end.tv_usec-begin.tv_usec);
    } else {
      printf("Invalid Input, %d <= %d is false\n", N, M);
    }
  }
  return 0;
}
 
1 5
1
2
3
4
5
print comos(1, 5) used 116 microseconds
2 5
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
print comos(2, 5) used 171 microseconds
3 5
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
print comos(3, 5) used 153 microseconds
4 5
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
print comos(4, 5) used 97 microseconds
5 5
1 2 3 4 5
print comos(5, 5) used 33 microseconds

fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...