响应HTTP服务的shell脚本

以下内容均为第一版, 实际使用请查看最新信息, 转至: https://hujingnb.com/archives/729

前言

兄弟萌, 我实现了一个实用的小工具, 特来分享.

事情刚开始是这样的, 我需要一个脚本来实现代码仓库web hook的任务, 首先想到的是直接调用php, 但是php-fpm是以www-data用户运行的, 很多调用是无法实现的. 此时, 我就需要一个常驻的偶尔调用一下的, 能够以root用户执行的http服务器, 但是网上查了查, 发现并么有符合我要求的现成轮子, 于是它来了.

是什么

简单介绍一下这个轮子是做什么用的. 简单说, 就是启动一个执行shell脚本的http服务.

它启动一个服务, 来监听指定端口并响应HTTP请求, 脚本在监听到新的请求后, 会根据请求路径调用响应的脚本执行任务并返回对应的内容.

如果需要HTTPS外边再套一层nginx就行了.

使用介绍

这个破玩意如何使用呢? 为了简化使用, 我将其打包成了docker镜像. 注意, 此服务每一次调用会启动一个新的进程, 故不适用于高并发场景.

启动

假设脚本的本地运行目录为: /usr/share/script.

创建文件/usr/share/script/test.bash. 内容如下:

#!/usr/bin/env bashresponse "return"

给脚本赋予执行权限: chmod +x /usr/share/script/test.bash

docker命令行启动:

docker run -it -d -p 80:80 -v /usr/share/script:/opt/script hujingnb/http_cron

docker-composer启动:

version: '3.1'services:tcp_cron:build: hujingnb/http_croncontainer_name: http_cronrestart: alwaysport: - 80:80volumes:- /usr/share/script:/opt/script

OK, 此时访问请求: http:127.0.0.1/test, 就会看到返回内容return了.

脚本运行机制

路由分配

根据请求的request_uri调用对应的脚本.

若请求为: /user/change_name.

那么会将脚本的工作路径/opt/script(工作路径通过环境变量WORKSPACE修改) 与请求拼在一起, 拼接后的路径为: /opt/script/user/change_name, 依次寻找以下后缀文件, 首次找到的为执行脚本:

  • /opt/script/user/change_name.pl
  • /opt/script/user/change_name.sh
  • /opt/script/user/change_name.bash
  • /opt/script/user/change_name.php
  • /opt/script/user/change_name.py
  • /opt/script/user/change_name.rb

若没有找到脚本, 或访问根路径, 返回404.

注意, 所有脚本都需要赋予执行权限.

接收请求

脚本通过环境变量接收请求内容, bash脚本可直接通过$METHOD_TYPE读取. 有如下内容:

  • METHOD_TYPE: 请求的方法. GET POST
  • HTTP_VERSION: 请求的HTTP版本. HTTP/1.1
  • REQUEST_URI: 请求原始路径(去掉GET参数的).
  • QUERY_STR: GET请求的原始参数字符串
  • FORM_CONTENT: 若请求是POST, 则此变量保存请求体的字符串内容.
    • 没有对内容进行解析. 因为根据content-type不同, 解析方式不同. 请自行解析
  • QUERY_PARAM_xxx: 解析后的GET请求参数. xxx为参数名
  • HEADER_xxx: 请求的 header内容. xxxheader名称

不同类型脚本读取系统env环境变量的方式不同, 请自行搜索.

响应请求

通过调用shell命令response进行返回. 如:

#!/usr/bin/env bash# 注意, 脚本在所有输出之前, 必须先调用 response 命令# status: 响应码. 默认为 200
# header_: 以 header_ 打头的参数为响应中添加的 header, 后面跟着 header 名. 可不传
# 最后的响应内容是必传参数. 若不需要, 可传空字符串
response --status=200 --header_ADD_HEADER=TEST "这里存放响应内容"
# 以极简的模式调用. 返回200, 并且没有响应体
# 若脚本全程没有审核输出, 则默认调用 response ""
# response ""# 后续的所有 echo 都作为响应内容输出
echo $QUERY_STR

若是其他脚本请参考调用系统命令的方式, 需要将response的输出内容写到标准输出流.

配置

可通过如下配置进行自定义修改.

环境变量

  • WORKSPACE: 修改运行脚本的查找目录. 默认为: /opt/script.
  • LISTEN_PORT: 修改脚本监听的端口. 默认80

docker命令行通过-e参数添加环境变量

docker-composer通过environment参数修改环境变量

环境准备

为了保证镜像的大小, 只安装了必要的软件, 包括python PHP运行环境都没有. 故, 若你有额外需求的话, 有如下两种方式来实现系统环境的定制化:

1.覆盖/opt/init.bash文件

镜像在每次启动时, 都会首先执行/opt/init.bash文件, 可以在这里安装额外的软件等初始化操作.

请注意, /opt/init.bash脚本每次镜像启动都会执行一次. 此脚本默认不执行任何操作.

2. 镜像引用

你也可以通过FROM的方式来制作自己的镜像.

Dockerfile地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wait函数的作用

前言 在编写C程序的时候, 通过fork函数来创建新的进程, wait函数来等待子进程结束. 那么就有一个问题了, 什么情况下父进程需要等待子进程结束后继续执行呢? 如果需要等待子进程结束, 那直接将操作放到父进程执行不就醒了么? 反正等着也是等着. 当然, 还有有一种情况, 任务…

OAuth1.0介绍

背景 为什么需要OAuth授权呢? 最典型的应用场景就是第三方登录了, 我们开发了一个网站希望用户可以QQ登录, 但是怎么能拿到用户的 QQ 信息呢? 用户将 账号密码告诉我们当然可以, 但是这样有如下隐患: 我们拿到了用户的密码, 这样很不安全. 而且任意一个应用被黑, 所有相关…

PHP 数组的内部实现

前言 这几天在翻github的时候, 碰巧看到了php的源码, 就 down 下来随便翻了翻. 地址: https://github.com/php/php-src 那么PHP中什么玩意最引人注目嘞? 一定是数组了, PHP中的数组太强大了, 于是就想着不如进去看看数组的实现部分. 这篇文章打算全程针对代码进行解读了. 以…

go1.18新特性

前言 最近突然发现golang更新版本1.18了, 于是迫不及待的来看看这个版本加了些什么新特性. 没准就有之前困扰很久的问题, 在新版本被官方解决了呢. 先简单概述一下都有些什么变化, 后面再细说: 增加泛型的支持系统库方法增加修复 bug 另外, 像"系统内核更新"这种…

base64编码原理

引出 众所周知, ASICC编码共127个, 使用了7个bit进行编码. 而文件在存储的时候是以 字节为单位, 也就是8bit. 这就难免导致有一部分编码是没有定义在ASICC编码中的. 而在网络中传输二进制数据的时候(字符串本质上也是二进制数据嘛), 如果直接传输比特流, 倒也不是不可以, 只是…

页面加载速度-合并资源文件

前言 一直觉得自己的博客站点页面加载很慢, 就想着去优化一下. 呐, 下图是一次文章页面的加载, 需要2.5s. 其中 js 文件就有18个. 众所周知, 浏览器对资源文件的并行下载数量是有限制的(不同浏览器限制不同). 也就是说, 这18个 js 文件是无法同时下载的, 再说了, 页面中还有其…

hbase/thrift/go连接失败

问题 在通过Go连接hbase的过程中, 发现 get操作可以查到数据, 但是scanner命令访问数据失败, 也没有报错, 就是单纯的查不到数据. 而且Python PHP都一切正常. 这里简单复述一下我出现问题的情况, 安装过程和网上大部分内容一致, 这里简单列一下, 只是为了查询问题时参考安装过…

常用搜索引擎及语法

在平常需要进行搜索的时候是不是只知道Google Baidu ?? 他们其实是全文搜索引擎, 还有一些特定领域的搜索引擎. 而且, 搜索时可以添加特定语法, 让你的搜索事半功倍. 本文整理各种场景下使用的搜索引擎, 以及各个搜索引擎支持的语法, 不定期进行更新. 如果你知道其他搜索引…

自旋锁与互斥锁

前言 在编程中经常需要使用到互斥. 互斥就是, 这个事情只能有一个人干, 我正在做着的时候, 别人要想做这件事就得等我做完了. 互斥的实现是通过锁的机制, 也就是我把这块锁上了, 别人就进不来了, 等我做完再把锁释放掉. 但是, 前辈们已经证明了, 要想单纯的在软件层面上实现…

printf缓冲区踩坑

问题 碰到了这样一段代码(经过简化的): #include "stdio.h" #include "unistd.h" #include "sys/wait.h"int main(){fork();printf("1\n");fork();printf("1\n");wait(NULL);return 0; }这里我们简单算一下, 结果会打印几…

进程切换时是如何保存上下文的

前言 当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复. 当进程运行的时候是独占CPU的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中…

GO/testing包

前言 之前在写GO单元测试的时候, 使用了这个结构testing.T. 进来无事翻了翻, 发现testing包中还有一些其他的结构体, 想来是不同用处. 没想到GO的testing包竟然默默做了这么多支持, 之前竟然不知道. 在testing包中包含一下结构体: testing.T: 这就是我们平常使用的单元测试t…

CPU的分支预测

前言 最近在进行性能调优的时候, 碰到了这样的一段代码(为了展示问题而简化的代码): <?php // 第一次运行 $start microtime(true); for ($i 0; $i < 100; $i) {for ($j 0; $j <1000; $j) {for ($k 0;$k < 10000; $k) {}} } $end microtime(true); echo fi…

Golang Context 简介

前言 在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background(). 但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中…

PHP获取Opcode及C源码

是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. 那么PHP的Opcode与之类似, 也是从.php文件到执行的过程中, 所…

PHP require/include 区别

前言 在PHP中, 载入文件可以选择使用require, 也可以使用include, 那么那他们有什么区别呢? 看了网上的一些文章, 说他们使用场景不同, require一般在文件开头引入文件, include一般在函数中动态引入文件. 但是我觉得并不是这么简单, require是作为语言结构(关键字)出现的, …

RESTful API规范

前言 我现在工作的公司是在毕业前实习的公司, 实习结束后直接转正, 因此也是我任职过的唯一一家公司. 在日常工作进行 HTTP 接口的开发时, 发现了一个疑惑, 只用到了POST和GET请求, 但我们知道 HTTP还有PUT/DELETE等等, 为什么不用呢? 并且, 接口的响应码也只有200, 接口是…

Golang 接口原理

问题 小提示, 若想直接查看原理, 可从接口原理开始查看. 有这样一段GO代码: func main() {var obj interface{}fmt.Printf("obj nil. %b\n", obj nil)type st struct{}var s *stobj sfmt.Printf("s nil. %b\n", s nil)fmt.Printf("obj nil. …

Docker kill 1无效

前言 我们在平常强制停用一个进程的时候, 会选择什么命令? 一般在测试使, 不考虑程序突然中断带来的影响, 直接使用kill -9 pid强制停止就行. 但是, 就在刚刚, 我启动了一个docker容器, 进入容器后执行命令kill -9 1没有任何效果??? 啊这, 为什么呀? 尝试 为了解释这个…

容器内存相关知识

这篇文章是我研究容器内存整理出的相关内容. 前后内容并没有上下文关系, 每个知识点都可以单独查看. 内存控制 使用这样的命令启动一个容器docker run -d -m 300M xxx. 可以限制容器使用的内存最大为300M. 那么docker是如何实现容器的内存限制呢? 其实是操作系统已经做好了…