Total Pageviews

Monday, 24 August 2026

clink

 

Bash's powerful command line editing in cmd.exe


Overview

Clink combines the native Windows shell cmd.exe with the powerful command line editing features of the GNU Readline library, which provides rich completion, history, and line-editing capabilities. Readline is best known for its use in the Unix shell Bash, the standard shell for many Linux distributions.

For details, refer to the Clink documentation.

Note

Starting Clink injects it into a cmd.exe process, where it intercepts a handful of Windows API functions so that it can replace the prompt and input line editing with its own Readline-powered enhancements.

Download

Downloads are available from the releases page.

See the issues page for known issues or to file new issues.

Feature Highlights

  • Auto-Suggestions; Clink offers suggestions as you type based on history, files, and completions.
  • Completions; Clink can complete words when you press Tab or Ctrl-Space (interactive completion list).
  • Persistent History; Clink stores persistent history between sessions.
  • Scriptable Prompt; You can customize the prompt dynamically with Lua scripts -- like in other shells -- but never before possible in cmd.exe!
  • Colored Input Line; Your input is colored by context sensitive completion scripts.
  • Command Line Editing Improvements; Clink supercharges the command line with new input editing commands and configurable key bindings.
  • Auto-answering of the "Terminate batch job?" prompt.
  • and much more!

Installation

You can install Clink by running the setup EXE file from the releases page.

Or by using winget and running winget install --id chrisant996.Clink -e.

Or by using scoop and running scoop install clink.

Or by downloading the ZIP file from releases page, and extracting the files to a directory of your choosing.

Usage

Once installed, there are several ways to start Clink.

  1. If Clink is configured for autorun, just start cmd.exe and Clink is automatically injected and ready to use.

    The setup EXE has an option "Autorun when cmd.exe starts". If you didn't use the setup EXE, or if you want to enable or disable autorun later, you can run clink autorun install or clink autorun uninstall to change the autorun configuration. Run clink autorun --help for more info.

  2. To manually start, run the Clink shortcut from the Start menu (or the clink.bat located in the install directory).

  3. To establish Clink to an existing cmd.exe process, use clink inject.

    If the Clink install directory isn't in the PATH, then use install_dir\clink in place of clink to run Clink commands. Once Clink is injected into a cmd.exe process, then it automatically sets an alias so that you can simply use clink.

You can use Clink right away without configuring anything:

  • Searchable command history will be saved between sessions.
  • Tab and Ctrl-Space will do match completion two different ways.
  • Press Alt-h to see a list of the current key bindings.
  • Press Alt-Shift-/ followed by another key to see what command is bound to the key.

See Getting Started for information on how to get started with using Clink.

Upgrading from Clink v0.4.9

The new Clink tries to be as backward compatible with Clink v0.4.9 as possible. However, in some cases upgrading may require a little bit of configuration work. More details can be found in the Clink documentation.

Extending Clink

Clink can be extended through its Lua API which allows easy creation of context sensitive match generators, prompt filtering, and more. More details can be found in the Clink documentation.

Building Clink

Clink uses Premake to generate Visual Studio solutions or makefiles for MinGW. Note that Premake >= 5.0.0-beta4 is required.

  1. Cd to your clone of Clink.
  2. Run premake5.exe toolchain (where toolchain is one of Premake's actions - see premake5.exe --help)
  3. Build scripts will be generated in .build\toolchain. For example .build\vs2022\clink.sln.
  4. Call your toolchain of choice (VS, mingw32-make.exe, msbuild.exe, etc). GNU makefiles (Premake's gmake target) have a help target for more info.

Note

Only the VS toolset is supported. If you want to try using MinGW, then make sure to use the msvcrt version because setjmp doesn't link in the URT version of MinGW.

Building Documentation

  1. Make sure npm and python are installed.
  2. Run npm install -g marked@2.0.1 to install the marked markdown library (version 2.0.1).
  3. Run pip install fonttools brotli lxml to install the pyftsubset font optimizer tool and the lxml parser.
  4. Run premake5.exe docs.

Important

Clink documentation uses marked@2.0.1. Newer versions of marked have introduced breaking changes, and I haven't yet rewritten how Clink builds the documentation to accommodate the breaking changes. The security fixes in newer versions aren't relevant since marked is only used at build time with known inputs (the marked library is no longer embedded in the documentation as of commit d5b39ca in Oct 2020).

The python dependencies are needed in order to make a subset of the Caskaydia Cove nerd font (based on Cascadia Code) to display the prompts. This optimization reduces the size (in woff2) from ~1220 kB to ~12 kB allowing it to be bundled with the clink.html file.

from  https://github.com/chrisant996/clink

用Cloudflare Zero Trust 搭建个人专属翻墙节点

 Cloudflare  提供的 Zero Trust 服务(原名 WARP/Cloudflare One)凭借其全球化的网络节点和企业级的安全架构,成为了目前最受推崇的方案之一。今天,我们将手把手教你如何通过几个简单的步骤,利用Cloudflare 的强大功能搭建属于自己的网络加速环境。

 

什么是 Cloudflare Zero Trust?(背后的原理)

在传统的网络中,我们通常靠“防火墙”来保护内部网络,就像给房子装个大门,进了门就是安全的。但这种方式很容易被攻破。

Cloudflare Zero Trust(零信任) 的逻辑不同:它默认不信任任何人和任何设备。

隧道原理(Tunneling):它在你的电脑/手机和 Cloudflare 的全球服务器之间建立一条专属的、加密的“私人隧道”。

身份验证:每次连接时,它都要检查你的身份(比如你的邮箱)。

全球加速:由于 Cloudflare 在全球(包括离中国大陆很近的地区)都有大量高性能服务器,你的请求会通过这些“高速路”传输,从而实现稳定、快速的科学上网。

Cloudflare 是谁?靠谱吗?

身份背景:Cloudflare 是美国上市公司(NYSE: NET),是全球互联网的基础设施提供商之一,。不是那种随时可能跑路的小型加速器。全球约 20% 的网页流量都经过他们的设备。这意味着他们的服务器节点多、抗干扰能力强。Cloudflare对于个人和小团队,他们提供了大量顶级企业才用得起的免费工具,是我们的“网络大善人”。

稳定性:由于它使用的是企业级的网络协议,相比于普通方案,它更难被识别和阻断,连接非常稳定。

隐私保护:它有严格的隐私政策,不会像不知名的“免费 VPN”那样售卖你的上网轨迹。

一句话建议: 如果你追求长期稳定、安全、免费且不介意初期花 10 分钟配置一下,Cloudflare Zero Trust 是目前最顶级的方案。


直接操作

点击官网注册

第一阶段:开启 Zero Trust 之门

分步指南及操作目的详解

第一步:开启零信任控制面板

操作: 登录 Cloudflare,点击左侧菜单的 "Zero Trust",然后点击 "Get Started"。 为什么要这样做? 这是在激活你的“企业级”管理后台。虽然你是个人用户,但通过这个入口,你实际上是在创建一个微型的虚拟私有网络环境。

第二步:设置团队名称 (Team Name)

操作: 输入一个唯一的名称,比如 my-private-net。 为什么要这样做? 这个名字是你隧道的“唯一门牌号”。当你以后在手机或电脑的客户端登录时,你需要输入这个名字来告诉软件:“我要连接到我自己的那个私人隧道里去”。

第三步:选择免费计划并绑定支付方式

操作: 选择 "Free" 计划,并输入信用卡信息。 为什么要这样做?

免费计划:Cloudflare 对 50 人以下的用户免费,对个人来说绰绰有余。

信用卡验证:这是为了防止机器人恶意大量注册。放心,只要你选的是 Free 计划,它不会扣除订阅费(可能会有 0 或 1 美元的预授权验证,随后会退还)。

第四步:设置“谁能进这个大门” (Device Enrollment)

操作: 在 Settings -> WARP Client -> Device enrollment 中点击 Manage,添加一条规则:允许以你自己的邮箱后缀(如 @gmail.com)结尾的人登录。 为什么要这样做? 这是最关键的安全步骤。如果你不设防,任何人知道你的 Team Name 都能蹭你的隧道。设置后,只有你能通过邮箱验证码登录。

第五步:下载并连接客户端

操作: 下载 Cloudflare WARP 客户端。在设置里找到 Account -> Login with Cloudflare Zero Trust,输入你的 Team Name,通过邮箱验证后点击连接。 为什么要这样做? 客户端就像是隧道的入口开关。一旦连接成功,你电脑上所有的流量都会被“打包”送入加密隧道,绕过复杂的干扰,直接通过 Cloudflare 的高速骨干网访问全球互联网。

手机客户端下载地址:

IOS下载】(需要美区或其他支持 Cloudflare的地区账号

安卓下载

总结

通过 Cloudflare Zero Trust,你不仅获得了一个稳定的网络连接工具,更是在设备与互联网之间建立了一道企业级的防火墙。相比于传统的方案,它更加合规、稳定,且得益于 Cloudflare 的 CDN 节点分布,延迟表现也非常出色。

加拿大向中国开门

 

卡尼时代的加拿大,如果只听外交辞令,很容易听糊涂。一方面说美国仍是最重要盟友,一方面强调加拿大必须减少对美国依赖;一方面承认中国存在安全风险,另一方面又重新向中国扩大贸易。

其实不必听那么多。国家真正的选择,不在记者会,在行动

过去一年,加拿大出现了两个同时发生的趋势:对美国,强调自主、增加距离;对中国,则降低部分壁垒、恢复贸易。两条线单独看,都有理由;放在一起看,方向已经相当清楚。

最新的美加贸易谈判尤其如此。双方在最后阶段破裂,美国对约200亿美元加拿大商品加征50%关税,加拿大宣布“dollar for dollar”反制。加拿大认为美国最后提出的条件侵犯其贸易自主,因此宁愿承受经济代价,也不接受。

这当然是加拿大的权利。

加拿大不是美国第五十一个州,卡尼也不是白宫任命的省长。一个主权国家认为过度依赖美国是一种危险,希望扩大欧洲、亚洲市场,完全讲得通

而且事情已经不能简单归结为卡尼个人。加拿大目前相当一部分民意支持政府对美国采取强硬态度。既然加拿大选民愿意尝试这条道路,美国反而应该认真一点:不要再把它当作渥太华一时闹脾气,更不必一厢情愿等待加拿大“恢复正常”。

尊重加拿大,首先就是相信加拿大人知道自己在选择什么。

有趣的是另一边。

加拿大努力降低对美国依赖的同时,却在降低与中国的部分经济壁垒卡尼访华后,加拿大同意每年给予最多4.9万辆中国电动车6.1%的关税待遇大幅松动此前100%的附加关税;作为交换,中国降低加拿大油菜籽等农产品面对的贸易壁垒。

一边减少对美国的依赖,一边向中国重新开门。加拿大完全有权如此

加拿大七成以上货物出口进入美国,两国汽车工业早已连成一片;边境对人员和车辆又高度开放。一个加拿大居民开自己的汽车去纽约、底特律度假,平常得像从广东开车去广西。

这种特殊关系能够存在,并不仅因为两国人民感情好,而是因为双方长期处于一个高度整合、风险标准相近的北美经济与安全空间。

中国电动车恰好说明,当这个前提发生变化,问题会怎样出现。

美国正在限制中国联网汽车进入本国市场,理由不只有产业保护,也包括数据和国家安全。现代汽车装有摄像头、定位系统、通信模块、软件更新系统和大量传感器。美国当然不能证明每一辆中国汽车都会搜集敏感信息,更不能证明北京明天会遥控哪一辆汽车;但国家安全本来就不是等事故发生以后才开始研究。

加拿大却可以作出不同判断。

加拿大说,这是我的市场,我愿意承担这个风险。

完全正确

但如果一辆在安大略合法购买、合法注册的中国电动车,可以按照加拿大车辆原有的便利驶入美国,那么加拿大的政策选择就产生了跨境外部性。

美国也完全可以回答:风险留在加拿大,是你的主权;风险跟着汽车进入美国,就不再只是你的事情。

这不是惩罚加拿大。

更长远的问题甚至不是这4.9万辆汽车。今天是中国的整车出口到加拿大,明天加拿大可能出现维修体系、零部件供应链,后天可能中国汽车企业投资加拿大生产。到了那一步,美国面对的就不再是几辆挂安大略车牌的汽车,而是中国汽车产业能否通过加拿大逐渐接入北美产业体系。

加拿大当然可以认为,这是经济机会。

美国也可以认为,这是安全风险。

加拿大可以说:我有权决定与中国做什么生意,美国无权替我决定

美国完全应该同意。

然后补上一句:美国也有权决定,加拿大商品、资本和车辆以什么条件进入美国。

这两句话并不矛盾。

现在加拿大社会本身相当支持减少对美国的依赖,美国更没有必要苦口婆心把加拿大往回拉。

卡尼的路线如果成功,加拿大找到了更多市场,减少对美国的依赖,又从中国和欧洲获得新的市场机会,那说明加拿大选对了

美国不必替加拿大作决定,更不必替加拿大承担选择的成本。

所以美国尤其不必发脾气。

加拿大人可以买本国货,可以抵制美国商品,可以少去佛罗里达,可以投票支持任何他们喜欢的政府。美国若因为加拿大人不喜欢川普而报复,反而显得小气。

美国真正应该做的,只是把自己的门重新量一次尺寸。

过去门开得特别宽,是因为门外站着一个几乎共享同一套经济、安全和产业规则的加拿大。今天加拿大决定改变自己的道路,美国自然可以重新考虑,这扇门还应该开多宽。

加拿大要减少对美国的依赖,这是加拿大的权利;要向中国开门,也是加拿大的权利

加拿大选自己的路,美国也选自己的。

剛升空就墜毀

 

-韩国的等级制度森严。下属即使发现了机长的错误,也不敢立即大声要求机长纠正错误,这样就耽搁了宝贵的自救时机。所以韩国的班机最好别坐。

Sunday, 23 August 2026

在windows上,如何升级nodejs

 在 Windows 上升级 Node.js 最简单的方法是直接去 Node.js 官网下载最新的 .msi 安装包覆盖安装。

  • 访问 Node.js 官网下载最新的 LTS(长期支持)版 .msi 安装包:
  •    https://nodejs.org/dist/v24.19.0/node-v24.19.0-x64.msi
  • 双击运行安装程序,一路点击 "Next"。
  • 关键点:安装路径要和您电脑上旧版本的安装路径保持一致(通常在 C:\Program Files\nodejs\)。安装程序会自动覆盖旧版本。
  • 打开命令提示符(CMD)输入 node -v 检查版本是否更新成功。

在windows下,搭建静态博客程序quarkdown

首先安装powershell: 

https://github.com/PowerShell/PowerShell/releases/download/v7.6.5/PowerShell-7.6.5-win-x64.msi ,下载并安装。

然后启动powershell.exe , 运行命令:

irm https://raw.githubusercontent.com/quarkdown-labs/get-quarkdown/refs/heads/main/install.ps1 | iex

 然后,启动git bash, 运行命令:

 quarkdown create quarkdown-document

(会在当前目录下,生成 quarkdown-document目录)

 12799@DESKTOP-B6LK9IO MINGW64 ~ (main)
$ cd quarkdown-document

12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document (main)
$ ls
image/  main.qd

12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document (main)
$ quarkdown c main.qd
[16:45] Success @ C:\Users\12799\quarkdown-document\quarkdown-output\Quickstart
(quarkdown c main.qd就是生成/更新静态网站的根目录的命令)
12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document (main)
$ ls
image/  main.qd  quarkdown-output/

12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document (main)
$ cd quarkdown-output/

12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document/quarkdown-output (main)
$ ls
Quickstart/

12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document/quarkdown-output (main)
$ cd Quickstart/

12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document/quarkdown-output/Quickstart (main)
$ ls
index.html  lib/  media/  script/  script.checksum  theme/
12799@DESKTOP-B6LK9IO MINGW64 ~/quarkdown-document/quarkdown-output/Quickstart (main)
$ python3 -m http.server 2233

访问http://127.0.0.1:2233,即可看到静态网站效果。但是这个效果比较简陋。我们可以fork程序作者自己的博客网站程序:https://github.com/iamgio/iamgio.github.io,我fork后的项目地址是https://github.com/brightmann/igi-source-code

 访问https://github.com/brightmann/igi-source-code/tree/main/src/blog ,在此,新建源帖2026-08-23-fh.qd ,内容为:
.docname {战马}
.include {template/setup.qd}
.blogpost date:{August 23, 2026}

此处写正文或html codes.

(详见https://github.com/brightmann/igi-source-code/blob/main/src/blog/2026-08-23-fh.qd)

然后,
git clone https://github.com/brightmann/igi-source-code igi-source-code-by-brightmann
cd igi-source-code-by-brightmann
12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann(main)
$ ls
src/
12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann(main)
$ cd src

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src (main)
$ ls
about.qd  blog.qd      experience.qd  js/      projects.qd  setup.qd
blog/     contacts.qd  images/        main.qd  public/      stylesheets/

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src (main)
$ quarkdown c main.qd
[17:20] Success @ C:\Users\12799\igi-source-code-by-brightmann\src\quarkdown-output\Giorgio-Garofalo-iamgio

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src (main)
$ ls
about.qd  contacts.qd    js/          public/            stylesheets/
blog/     experience.qd  main.qd      quarkdown-output/
blog.qd   images/        projects.qd  setup.qd
(生成了quarkdown-output 目录)

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src (main)
$ cd quarkdown-output/

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src/quarkdown-output (main)
$ ls
Giorgio-Garofalo-iamgio/

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src/quarkdown-output (main)
$ cd Giorgio-Garofalo-iamgio/

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src/quarkdown-output/Giorgio-Garofalo-iamgio (main)
$ ls
2025-12-05-hello-world/                     index.html  script/          theme/
2025-12-10-accidentally-in-silicon-valley/  lib/        script.checksum
2026-03-28-overengineering/                 media/      sitemap.xml
2026-08-23-fh/                              robots.txt  static/
里面有index.html文件,可见~/igi-source-code-by-brightmann/src/quarkdown-output/Giorgio-Garofalo-iamgio就是静态网站的根目录
12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src/quarkdown-output/Giorgio-Garofalo-iamgio (main)
$ python3 -m http.server 2345
访问http://127.0.0.1:2345/ ,即可看到静态网站的效果。
http://127.0.0.1:2345/2026-08-23-fh/ 不能显示视频

12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src/quarkdown-output/Giorgio-Garofalo-iamgio (main)
$ ctrl+c
12799@DESKTOP-B6LK9IO MINGW64 ~/igi-source-code-by-brightmann/src/quarkdown-output/Giorgio-Garofalo-iamgio (main)
然后静态网站的根目录的内容push到在github.com/brightmann下所新建的空仓库igi:
git init .
git add .
git commit -m 'xx'
git remote set-url xyz git@github-first:brightmann/igi
(或者git remote add xyz git@github-first:brightmann/igi)
git branch -m main  
git push -f origin main

在本地机器上生成的静态网站的根目录的内容都可以通过以上的git命令push到在github.com/your-username下所新建的某个空仓库,这样再也不用东找西找静态服务器了)

 访问 https://brightmann.github.io/igi/ 即可看到静态网站的效果。

 https://brightmann.github.io/igi/2026-08-23-fh/ 不能显示视频。

项目地址:
https://github.com/iamgio/quarkdown
https://quarkdown.com/wiki/quickstart/
https://quarkdown.com/#install
https://github.com/quarkdown-labs/get-quarkdown/

程序作者自己的博客网站程序:

https://github.com/iamgio/iamgio.github.io

 https://github.com/iamgio/iamgio.github.io/issues/1

我fork后的项目地址是https://github.com/brightmann/igi-source-code

https://github.com/brightmann/igi

3款httpd程序-asmhttpd, bashttpd, libmicrohttpd

 A minimalist HTTP server for Linux, written in x86_64 assembly。

asmhttpd - The tiniest webserver ever written.

HOW TO BUILD:

	Just run "make". You will need NASM on your system.

HOW TO RUN:

	./asmhttpd /path/to/your/webroot
	sudo ./asmhttpd /path/to/your/webroot

If run as root, it will listen on port 80. Otherwise, it will use port 8080.

HOW TINY IS IT?

The entire text and data fit on a single 4K page:

  {0}[calvin ~] cat /proc/$(pgrep -n asmhttpd)/maps
  00401000-00402000 r-xp 00001000 00:16 2483272 asmhttpd

Each client allocates an additional 4K page and a thread while connected.

The code is written in a monolithic "branching tree" style with no functions,
and uses registers for all local variables. RAM is only used for buffering the
HTTP request, and for building structures necessary for system calls.

Because there is no stack, and the targets of all branch instructions are
constants, traditional buffer overflow exploits are impossible.
from  https://github.com/jcalvinowens/asmhttpd
-------
A web server written in bash。
 

bashttpd is a simple, configurable web server written in bash

Requirements

  1. bash, any recent version should work
  2. socat or netcat to handle the underlying sockets.
  3. A healthy dose of insanity

Examples

  socat TCP4-LISTEN:8080 EXEC:/usr/local/bin/bashttpd

Or

  netcat -lp 8080 -e ./bashttpd

Note that in the socat example above, the web server will immediately exit once the first connection closes. If you wish to serve to more than one client - like most servers do, then use the variant:

 socat TCP4-LISTEN:8080,fork EXEC:/usr/local/bin/bashttpd

This way, a new process is spawned for each incoming connection.

Getting started

  1. Running bashttpd for the first time will generate a default configuration file, bashttpd.conf
  2. Review bashttpd.conf and configure it as you want.
  3. Run bashttpd using netcat or socat, as listed above.

Features

  1. Serves text and HTML files
  2. Shows directory listings
  3. Allows for configuration based on the client-specified URI

Limitations

  1. Does not support authentication
  2. Doesn't strictly adhere to the HTTP spec.

Security

  1. Only rudimentary input handling. We would not running this on a public machine.

HTTP protocol support

403: Returned when a directory is not listable, or a file is not readable 400: Returned when the first word of the first line is not GET 200: Returned with valid content Content-type: Bashttpd uses /usr/bin/file to determine the MIME type to sent to the browser 1.0: The server doesn't support Host: headers or other HTTP/1.1 features - it barely supports HTTP/1.0!

As always, your patches/pull requests are welcome!

from  https://github.com/tootallnate/bashttpd

-----

 

GNU Libmicrohttpd


GNU libmicrohttpd is a small C library that makes it easy to run an HTTP server as part of another application. GNU Libmicrohttpd is free software and part of the GNU project. Key features that distinguish GNU Libmicrohttpd from other projects are:

  • C library: fast and small
  • API is simple, expressive and fully reentrant
  • Implementation is HTTP 1.1 compliant
  • HTTP server can listen on multiple ports
  • Various threading modes: run in application thread, internal thread, thread pool, and thread-per-connection
  • Three different sockets polling modes: select(), poll(), and epoll
  • Minimised number of sys-calls to avoid extra user/kernel mode switches
  • Supported platforms include GNU/Linux, FreeBSD, OpenBSD, NetBSD, Android, Darwin (macOS), W32, OpenIndiana/Solaris, and z/OS
  • Support for IPv6
  • Support for SHOUTcast
  • Support for incremental processing of POST data (optional)
  • Support for basic and digest authentication (optional)
  • Support for TLS (requires libgnutls, optional)
  • Binary is only about 32k (without TLS support and other optional features)

GNU libmicrohttpd was started because the author needed an easy way to add a concurrent HTTP server to other projects. Existing alternatives were either non-free, not reentrant, standalone, of terrible code quality, or a combination thereof. Do not use GNU libmicrohttpd if you are looking for a standalone HTTP server, there are many other projects out there that provide that kind of functionality already. However, if you want to be able to serve WWW pages from within your C or C++ application, check it out.

GNU libmicrohttpd is maintained by Evgeny Grin (Karlson2k) and another co-maintainer.

Downloading libmicrohttpd

There are currently two main versions of the library available. GNU libmicrohttpd 1.x is the stable version, and GNU libmicrohttpd 2.x is experimental and remains under heavy development. GNU libmicrohttpd 2.x can currently only be obtained by cloning our Git repository at git://git.gnunet.org/libmicrohttpd2.git.
Source Code
Libmicrohttpd is available from the main GNU FTP server via HTTP(S) and FTP. It can also be found on the GNU mirrors; please use a mirror if possible.
Debian .deb package
The debian package can be downloaded from the official debian archive. The respective packages for libmicrohttpd are libmicrohttpd and for development libmicrohttpd-dev.
Tar Package
The latest version can be found on GNU mirrors. If the mirror does not work, you should be able to find them on the main FTP server.

Latest release is libmicrohttpd-latest.tar.gz.

Windows
Latest Windows binary is libmicrohttpd-latest-w32-bin.zip.

Documentation

In addition to the brief documentation on this webpage, we have various other forms of documentation available:

microhttpd.h
This include file documents most of the API in detail.
Manual
A manual for Libmicrohttpd is available online, as is documentation for most GNU software. You may also find more information about Libmicrohttpd by running info libmicrohttpd or man libmicrohttpd, or by looking at /usr/share/doc/libmicrohttpd/, /usr/local/doc/libmicrohttpd/, or similar directories on your system.
Tutorial
The GNU Libmicrohttpd tutorial is available as one document in PDF and HTML formats.
Security audit 2025
Ada Logics with support from the Sovereign Tech Agency performed a security audit of the source code of the GNU libmicrohttpd 2.x codebase in August 2025. All discovered issues were addressed. The full report is available here.

Mailing lists

Libmicrohttpd uses the libmicrohttpd mailinglist to discuss all aspects of Libmicrohttpd, including support, development, and enhancement requests, as well as bug reports.

Announcements about Libmicrohttpd and most other GNU software are made on info-gnu (archive).

Security reports that should not be made immediately public can be sent directly to the maintainers. If there is no response to an urgent issue, you can escalate to the general security mailing list for advice.

Getting involved

Development of Libmicrohttpd, and GNU in general, is a volunteer effort, and you can contribute. For information, please read How to help GNU. If you'd like to get involved, it's a good idea to join the discussion mailing list (see above).

Development
Known bugs and open feature requests are tracked in our bugtracker. You need to sign up for a reporter account. Please make sure you report bugs under libmicrohttpd and not under any of the other projects.
Git access

You can access the current development version of libmicrohttpd using

$ git clone https://git.gnunet.org/libmicrohttpd.git

Quick Introduction

Dependencies
GNU Libmicrohttpd can be used without any dependencies; however, for TLS (HTTPS) support it require libgnutls. Furthermore, the testcases use libcurl. Some extended testcases also use zzuf and socat (to simulate clients that violate the HTTP protocols). You can compile and use GNU Libmicrohttpd without installing libgnutls, libcurl, zzuf or socat
 
 
Threading modes
The example above uses the simplest threading mode, MHD_USE_THREAD_PER_CONNECTION. In this mode, MHD starts one thread to listen on the port for new connections and then spawns a new thread to handle each connection. This mode is great if the HTTP server has hardly any state that is shared between connections (no synchronization issues!) and may need to perform blocking operations (such as extensive IO or running of code) to handle an individual connection.

The second threading mode, MHD_USE_SELECT_INTERNALLY, uses only a single thread to handle listening on the port and processing of requests. This mode is preferable if spawning a thread for each connection would be costly. If the HTTP server is able to quickly produce responses without much computational overhead for each connection, this mode can be a great choice. Note that MHD will still start a single thread for itself – this way, the main program can continue with its operations after calling MHD_daemon_start. Naturally, if the HTTP server needs to interact with shared state in the main application, synchronization will be required. If such synchronization in code providing a response results in blocking, all HTTP server operations on all connections will stall. This mode is a bad choice if response data (for responses generated using the MHD_create_response_from_callback function) cannot always be provided instantly. The reason is that the code generating responses should not block (since that would block all other connections) and on the other hand, if response data is not available immediately, MHD will start to busy wait on it. Use the first mode if you want to block on providing response data in the callback, or the last mode if you want to use a more event-driven mode with one big select loop.

The third mode combines a thread pool with the MHD_USE_SELECT_INTERNALLY mode, which can benefit implementations that require scalability. As said before, by default this mode only uses a single thread. When combined with the thread pool option, it is possible to handle multiple connections with multiple threads. The number of threads is specified using the MHD_OPTION_THREAD_POOL_SIZE; any value greater than one for this option will activate the use of the thread pool. In contrast to the MHD_USE_THREAD_PER_CONNECTION mode (where each thread handles one and only one connection), threads in the pool can handle a large number of concurrent connections. Using MHD_USE_SELECT_INTERNALLY in combination with a thread pool is typically the most scalable (but also hardest to debug) mode of operation for MHD.

The fourth threading mode (used when no specific flag is given), uses no threads. Instead, the main application must (periodically) request file descriptor sets from MHD, perform a select call and then call MHD_run. MHD_run will then process HTTP requests as usual and return. MHD_run is guaranteed to not block; however, access handlers and response processing callbacks that it invokes may block. This mode is useful if a single-threaded implementation is desired and in particular if the main application already uses a select loop for its processing. If the application is not ready to provide a response, it can just return zero for the number of bytes read and use its file descriptors in the external select loop to wake up and continue once the data is ready – MHD will unlist the socket from the write set if the application failed to provide response data (this only happens in this mode).

The testcases provided include examples for using each of the threading modes.

Generating responses
MHD provides various functions to create struct MHD_Response objects. A response consists of a set of HTTP headers and a (possibly empty) body. The three main ways to create a response are either by specifying a given (fixed-size) body (MHD_create_response_from_data), by providing a function of type MHD_ContentReaderCallback which provides portions of the response as needed or by providing an open file descriptor (MHD_create_response_from_fd). The first response construction is great for small and in particular static webpages that fit into memory. The second response type should be used for response objects where the size is initially not known or where the response maybe too large to fit into memory. Finally, using a file descriptor can be used on Linux systems to use the highly efficient sendfile call for the file transfer.

A response is used by calling MHD_queue_response which sends the response back to the client on the specified connection. Once created, a response object can be used any number of times. Internally, each response uses a reference counter. The response is freed once the reference counter reaches zero. The HTTP server should call MHD_destroy_response when a response object is no longer needed, that is, the server will not call MHD_queue_response again using this response object. Note that this does not mean that the response will be immediately destroyed – destruction may be delayed until sending of the response is complete on all connections that have the response in the queue.

Queueing responses
Clients should never create a "100 CONTINUE" response. MHD handles "100 CONTINUE" internally and only allows clients to queue a single response per connection. Furthermore, clients must not queue a response before the request has been fully received (except in the case of rejecting PUT or POST operations in HTTP 1.1). If a client attempts to queue multiple responses or attempts to queue a response early, MHD_queue_response will fail (and return MHD_NO).

The callback function for the respective URL will be called at least twice. The first call happens after the server has received the headers. The client should use the last void** argument to store internal context for the session. The first call to the callback function is mostly for this type of initialization and for internal access checks. At least, the callback function should "remember" that the first call with just the headers has happened. Queueing a response during the first call (for a given connection) should only be used for errors – if the client queues a response during this first call, a "100 CONTINUE" response will be suppressed, the request body will not be read and the connection will be closed after sending the response. After the first call, the callback function will be called with upload data. Until *upload_data_size is zero, the callback may not queue a response, any such attempt will fail. The callback function should update *upload_data_size to indicate how many bytes were processed. Depending on available buffer space, incremental processing of the upload maybe required. Once all of the upload data has been processed, MHD will call the callback a second time with *upload_data_size being zero. At this point, the callback should queue a "normal" response. If queueing a response is not possible, the callback may either block or simply not queue a response depending on the threading mode that is used. If the callback does not queue a response at this point, MHD will either (eventually) timeout the connection or keep calling it.

Parsing of POST requests
MHD includes a set of three functions for parsing and processing data received in POST requests. The functions allow incremental parsing and processing of POST data. Only a tiny fraction of the overall POST data needs to fit into memory. As a result, applications using MHD can support POST requests of arbitrary size. POST data is processed by providing MHD with a callback function that is called on portions of the received values. The POST parser itself is invoked repeatedly whenever more input bytes become available. MHD supports both uri- and multipart/form-encoded POST data.
Memory Management
The application can determine the size of buffers that MHD should use for handling of HTTP requests and parsing of POST data. This way, MHD users can trade-off processing time and memory utilization. Applications can limit the overall number of connections MHD will accept, as well as the total amount of memory used per connection. MHD will gracefully handle all out-of-memory situations (by closing the connection and cleaning up any remaining state). 
 
from  https://www.gnu.org/software/libmicrohttpd

 

 

 

Cloudflare-Subdomain-Registrar

 

A PHP Program For Subdomain Registeration And Management Based On Cloudflare DNS.

中文 README

Next Update

  • Edit NS Record Record
  • Program setup script
  • Account Status (ability to suspend/cancel accounts)
  • Domain Name Status (ability to require registerations to be approved, suspend/cancel sub-domains)
  • Better Admin panel: Edit NS Record for specific sub-domain, etc.

Configuration

PLEASE READ AND FOLLOW THE STEPS CAREFULLY.

Step 1: Creating and Importing Database

Create a MySQL database in your server, and import cloudflareNIC.sql. Make sure to take note of your database name, username and password.

Step 2: Configuring config.php

1. Database Configuration

Update the following constants with your database credentials:

define('DB_HOST', 'your-database-host');        // e.g. localhost
define('DB_USER', 'your-database-username');
define('DB_PASS', 'your-database-password');
define('DB_NAME', 'your-database-name');

2. Registrar System Setup

Replace the following with your domain details:

define('DOMAIN_NAME', 'example.com');           // Lowercase version
define('DOMAIN_NAME_UP', 'EXAMPLE.COM');        // Uppercase version
define('REGISTRAR_DOMAIN', 'registrar.example.com');  // Domain of the registrar system

3. Cloudflare Setup

Create a scoped API token with permissions for DNS:Read and DNS:Edit for your domain.

define('CLOUDFLARE_API_KEY', 'your-cloudflare-api-token');
define('CLOUDFLARE_ZONE_ID', 'your-cloudflare-zone-id');

Get API Token From Cloudflare dashboard. Find your zone ID on the Overview tab for your domain in the Cloudflare dashboard.


4. HCaptcha Integration

Set up HCaptcha for bot protection.

define('HCAPTCHA_SITE_KEY', 'your-hcaptcha-site-key');
define('HCAPTCHA_SECRET', 'your-hcaptcha-secret-key');

Get these from your hCaptcha dashboard.


5. Google Login Setup

Enable OAuth on Google Cloud Console and get your credentials.

A more detailed guide is available at Setting Up Google Login

Follow the guide up until step 1 in the guide, you will have all of the informations you need for this step.

define('GOOGLE_CLIENT_ID', 'your-google-client-id');
define('GOOGLE_CLIENT_SECRET', 'your-google-client-secret');

Use a redirect URI like:

https://your-registrar-domain.com/oauth_callback.php

Step 3: Update User Role in MySQL Table

You need to manually update the MySQL entry once you logged in with your Google account, change the role field of your user record from user to admin. After this step, log out and log back in you will be able to access the Admin panel.

from  https://github.com/KevvTheGoat/Cloudflare-Subdomain-Registrar

搭建基于nextjs的静态博客程序mbt


首先fork此项目:https://github.com/RyukyuInteractive/blog-2023-12-19,我fork后,得到的项目地址是https://github.com/briteming/mbt,

访问https://github.com/briteming/mbt/tree/main/posts,在这里,新建源帖fh.md,内容为:

---
title: "战马"
excerpt: "点击标题看全文"
coverImage: "/blog/dynamic-routing/cover.jpg"
date: "2026-05-25T08:11:00.322Z"
author:
  name: ym
  picture: "/blog/authors/jj.jpeg"
ogImage:
  url: "/blog/dynamic-routing/cover.jpg"
---

此处写正文或html codes.

( 详见https://github.com/briteming/mbt/blob/main/posts/fh.md?plain=1) 

然后,访问vercel.com/new ,导入项目
https://github.com/brightmann/dnb

  Build Command栏填入npm run build
 Install Command栏填入npm install

点击底部的deploy按钮,等待部署完成。部署完成后,我得到网址:

https://mbt-gold.vercel.app/

项目地址:
https://github.com/RyukyuInteractive/blog-2023-12-19
https://github.com/briteming/mbt

演示博客:

 https://mbt-gold.vercel.app/

 https://mbt-gold.vercel.app/posts/fh 不能显示视频

 

IPFSBED - Decentralized IPFS File Hosting Service


 

English | 中文

Demo License IPFS

Overview

IPFSBED is a decentralized file hosting platform built on the InterPlanetary File System (IPFS). It allows users to upload and share files of various formats through the distributed IPFS network, making content accessible globally without relying on central servers.

IPFSBED Screenshot

Key Features

  • Decentralized Storage: Files are stored on the IPFS network rather than centralized servers
  • Multiple Upload Methods: Drag & drop, clipboard paste (all file types), or traditional file selection
  • Wide Format Support: Images, documents, videos, archives, and many other file types
  • Password Protection: Optional encryption for sensitive files with password protection
  • Batch Sharing: Share multiple files at once with a single link
  • Short URLs: Generate compact, easy-to-share URLs through integrated URL shortener
  • Folder Support: Upload entire folders while preserving directory structure
  • Multiple Gateways: Choose from various IPFS gateways for optimal access speed
  • Internationalization: UI available in 12 languages
  • No Registration: Use immediately without creating an account
  • Upload History: View, search, filter, export, and import your upload history

How to Use

Single File Upload

  1. Open IPFSBED
  2. (Optional) Enter a passphrase in the password field if you want to protect your file
  3. Upload a file by:
    • Clicking the upload area and selecting a file
    • Dragging and dropping a file
    • Pasting an image from clipboard (Ctrl+V)
  4. After uploading, you'll get a share link
    • With passphrase: share.html?share=encrypted_data (recipient needs the passphrase)
    • Without passphrase: share.html?d=compressed_data (publicly accessible)
    • Both formats automatically generate a short URL for easier sharing

Folder Upload

  1. Toggle "Folder Mode" using the switch at the top of the upload area
  2. Click the upload area and select a folder, or drag and drop a folder
  3. The entire folder structure will be preserved and uploaded to IPFS
  4. Share the generated link to allow recipients to browse and download the folder contents

Batch Sharing

  1. Upload multiple files or folders
  2. Select the items you want to share using the checkboxes
  3. Click "Batch Share"
  4. (Optional) Set a passphrase for this batch of files
  5. Click "Confirm & Copy Link"
  6. Share the generated link with recipients
    • With passphrase: batch-share.html?share=encrypted_data
    • Without passphrase: batch-share.html?d=compressed_data or batch-share.html?files=data (legacy format)

Accessing Shared Files

  1. Open the shared link
  2. If password-protected, enter the passphrase when prompted
  3. For batch shares:
    • You can select which files to download
    • Download individual files or all files as a ZIP archive
    • Copy links to individual files

Upload History Page

You can view your upload history by clicking the "上传历史" (Upload History) link in the top-right corner. The history page allows you to:

  • View all files and folders you have uploaded (stored in your browser)
  • Search, filter by type/time/encryption, and sort your uploads
  • Export your upload history as a JSON file, or import history from another browser
  • Delete individual records, batch delete, or clear all history
  • Copy share links or CIDs directly from the history page

Note: Upload history is stored locally in your browser and is not synced between devices.

Advanced Features

Short URL Generation

IPFSBED includes integration with a URL shortening service to make shared links more compact and easier to share. This feature:

  • Automatically generates short URLs for all shared content
  • Works for both single files/folders and batch shares
  • Can be toggled on/off with the "Short URL" option
  • Falls back to regular full-length URLs if the shortening service is unavailable

Multiple Gateway Support

IPFSBED offers various IPFS gateways for accessing your files. Different gateways may provide better performance depending on your location and network conditions.

Deployment with Cloudflare Pages

You can easily deploy your own instance of IPFSBED using Cloudflare Pages:

  1. Fork this repository on GitHub
  2. Log in to your Cloudflare dashboard and navigate to Pages
  3. Click "Create a project" and select "Connect to Git"
  4. Select your forked repository and configure the build settings:
    • Build command: npm run build (or leave empty if no build step)
    • Build output directory: / (root directory)
  5. In the Environment Variables section, add the following if you want URL shortening:
    • YOURLS_SIGNATURE: Your YOURLS API signature token (obtain it from https://yourdomain.com/admin/tools.php)
    • YOURLS_API_ENDPOINT: Your YOURLS API endpoint URL (e.g., https://yourdomain.com/yourls-api.php)

After deployment, your IPFSBED instance will be available at your-project-name.pages.dev. You can also configure a custom domain in the Cloudflare Pages settings.


Deployment with Tencent EdgeOne Pages

You can also deploy IPFSBED easily using Tencent EdgeOne Pages:

Use EdgeOne Pages to deploy

Click the button above to deploy this project to EdgeOne Pages.
You can adjust build settings and environment variables as needed in the deployment console.

Using Your Own IPFS Gateway

For better performance and control, you have to deploy your own IPFS gateway:

  1. Set up your own IPFS node with a public gateway (e.g. using Kubo)
  2. Configure CORS settings on your IPFS gateway to allow requests from your frontend domain:
    ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["https://your-frontend-domain.com", "https://your-project-name.pages.dev"]'
    ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST", "GET"]'
  3. If using a separate gateway domain, also configure CORS headers in your web server (Nginx example):
    location /api/ {
        proxy_pass http://localhost:5001/;
        proxy_set_header Host $host;
        
        # CORS headers
        add_header Access-Control-Allow-Origin "https://your-frontend-domain.com" always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, OPTIONS" always;
        add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
        
        # Handle preflight requests
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin "https://your-frontend-domain.com" always;
            add_header Access-Control-Allow-Methods "GET, POST, PUT, OPTIONS" always;
            add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
            add_header Access-Control-Max-Age 1728000;
            add_header Content-Type 'text/plain charset=UTF-8';
            add_header Content-Length 0;
            return 204;
        }
    }

References

from  https://github.com/bestZwei/ipfsbed

------

示例:

 https://bafybeihamdzo7rthg7267zvokvfqdadnsaz4zkawrf3k4n7ohaeiy5fr6m.ipfs.inbrowser.link/

 https://bafybeig2vn3scrdqy6bp6wgfq7efqg5tvmxzkwth3mcevmo2kuwvlkmezu.ipfs.inbrowser.link/

论坛网站程序spectrum

 

Simple, powerful online communities.

This is the main monorepo codebase of Spectrum. Every single line of code that's not packaged into a reusable library is in this repository.

What is Spectrum?

Vision

It is difficult to grow, manage and measure the impact of online communities. Community owners need modern, chat-based communities but are running into scaling issues when their community grows beyond a few hundred members. It becomes hard to keep track of who's who, know what conversations are happening, and ensure that the community is staying healthy and productive.

Spectrum aims to be the best platform to build any kind of community online by combining the best of forums and real-time chat apps. With best-in-class moderation tooling, a single platform for all your communities, threaded conversations by default, community health monitoring, and much more to come we think that we will be able to help more people start and grow the best online communities.

"[Spectrum] will take the place that Reddit used to have a long time ago for communities (especially tech) to freely share ideas and interact. Except realtime and trolling-free."

- Guillermo Rauch (@rauchg)

Status

Spectrum has been in full-time development since March 2017 and is part of GitHub since November 2018. See our current priorities and what we are working on in the main project board.

Docs

Contributing

We heartily welcome any and all contributions that match our engineering standards!

That being said, this codebase isn't your typical open source project because it's not a library or package with a limited scope—it's our entire product.

Ground Rules

Contributions and discussion guidelines

All conversations and communities on Spectrum agree to GitHub's Community Guidelines and Acceptable Use Policies. This code of conduct also applies to all conversations that happen within our contributor community here on GitHub. We expect discussions in issues and pull requests to stay positive, productive, and respectful. Remember: there are real people on the other side of that screen!

Reporting a bug or discussing a feature idea

If you found a technical bug on Spectrum or have ideas for features we should implement, the issue tracker is the best place to share your ideas. Make sure to follow the issue template and you should be golden! (click here to open a new issue)

Fixing a bug or implementing a new feature

If you find a bug on Spectrum and open a PR that fixes it we'll review it as soon as possible to ensure it matches our engineering standards.

If you want to implement a new feature, open an issue first to discuss what it'd look like and to ensure it fits in our roadmap and plans for the app (see the main project board for planned and currently ongoing work).

If you want to contribute but are unsure to start, we have a "good first issue" label which is applied to newcomer-friendly issues. Take a look at the full list of good first issues and pick something you like! There is also an "open" channel in the Spectrum community on Spectrum (how meta), if you run into troubles while trying to contribute that is the best place to talk to us.

Want to fix a bug or implement an agreed-upon feature? Great, jump to the local setup instructions!

Codebase

Technologies

With the ground rules out of the way, let's talk about the coarse architecture of this mono repo:

  • Full-stack JavaScript: We use Node.js to power our servers, and React to power our frontend apps. Almost all of the code you'll touch in this codebase will be JavaScript. Here is a list of all the big technologies we use:

  • RethinkDB: Data storage

  • Redis: Background jobs and caching

  • GraphQL: API, powered by the entire Apollo toolchain

  • Flowtype: Type-safe JavaScript

  • PassportJS: Authentication

  • React: Frontend React app

Folder structure

spectrum/
├── api        # API server
├── docs
├── hyperion   # Rendering server
├── public     # Public files used on the frontend
├── shared     # Shared JavaScript code
├── src        # Frontend SPA
Click to learn about the worker naming scheme


Code Style

We run Prettier on-commit, which means you can write code in whatever style you want and it will be automatically formatted according to the common style when you run git commit. We also have ESLint set up, although we've disabled all stylistic rules since Prettier takes care of those.

Rules
  • All new .js files must be flow typed: Since we only introduced Flowtype after we finished building the first version of Spectrum, we enforce in CI that all new files added to the codebase are typed. (if you've never used Flowtype before that's totally fine, just write your code in plain JS and let us know in the PR body, we can take care of it for you)
  • No console.logs in any file: We use the debug module across the codebase to log debugging information in development only. Never commit a file that contains a console.log as CI will fail your build. The only exceptions are errors, which you can log, but you have to use console.error to be explicit about it

First time setup

The first step to running Spectrum locally is downloading the code by cloning the repository:

git clone git@github.com:withspectrum/spectrum.git

If you get Permission denied error using ssh refer here or use https link as a fallback.

git clone https://github.com/withspectrum/spectrum.git

Installation

Spectrum has four big installation steps:

  1. Install RethinkDB: See the RethinkDB documentation for instructions on installing it with your OS.
  2. Install Redis: See the Redis documentation for instructions on installing it with your OS.
  3. Install yarn: We use yarn to handle our JavaScript dependencies. (plain npm doesn't work due to our monorepo setup) See the yarn documentation for instructions on installing it.
  4. Install the dependencies: Because it's pretty tedious to install the dependencies for each worker individually we've created a script that goes through and runs yarn install for every worker for you: (this takes a couple minutes, so dive into the technical docs in the meantime)
node shared/install-dependencies.js

You've now finished installing everything! Let's migrate the database and you'll be ready to go 💯

Migrating the database

When you first download the code and want to run it locally you have to migrate the database and seed it with test data. First, start rethinkdb in its own terminal tab:

rethinkdb

Then, in a new tab, run these commands:

yarn run db:migrate
yarn run db:seed
# ⚠️ To empty the database (e.g. if there's faulty data) run yarn run db:drop

There's a shortcut for dropping, migrating and seeding the database too:

yarn run db:reset

The testing database used in end to end tests is managed separately. It is built, migrated, and seeded when you run:

yarn run start:api:test

To drop the testing database, go to http://localhost:8080/#tables while rethinkdb is running, and click Delete Database on the appropriate database.

Getting the secrets

While the app will run without any secrets set up, you won't be able to sign in locally. To get that set up, copy the provided example secrets file to the real location:

cp now-secrets.example.json now-secrets.json

Note: If you're an employee at Spectrum we've got a more complete list of secrets that also lets you upload images etc. in 1Password, search for "now-secrets.json" to find it.

Now you're ready to run the app locally and sign into your local instance!

Running the app locally

Background services

Whenever you want to run Spectrum locally you have to have RethinkDB and Redis running in the background. First start rethinkdb like we did to migrate the database:

rethinkdb

Then (without closing the rethinkdb tab!) open another tab and start Redis:

redis-server

Start the servers

Depending on what you're trying to work on you'll need to start different servers. Generally, all servers run in development mode by doing yarn run dev:<workername>, e.g. yarn run dev:hermes to start the email worker.

No matter what you're trying to do though, you'll want to have the API running, so start that in a background tab:

yarn run dev:api

Develop the web UI

To develop the frontend and web UI run

yarn run dev:web
from https://github.com/withspectrum/spectrum