Smocker is a simple and efficient HTTP mock server and proxy.

Overview

Smocker

Build Status Netlify Status Docker Repository Github Release Go Report Card License

Smocker (server mock) is a simple and efficient HTTP mock server.

The documentation is available on smocker.dev.

Table of contents

Installation

With Docker

docker run -d \
  --restart=always \
  -p 8080:8080 \
  -p 8081:8081 \
  --name smocker \
  thiht/smocker

Manual Deployment

# This will be the deployment folder for the Smocker instance
mkdir -p /opt/smocker && cd /opt/smocker
wget -P /tmp https://github.com/Thiht/smocker/releases/latest/download/smocker.tar.gz
tar xf /tmp/smocker.tar.gz
nohup ./smocker -mock-server-listen-port=8080 -config-listen-port=8081 &

Healthcheck

curl localhost:8081/version

User Interface

Smocker exposes a configuration user interface. You can access it in your web browser on http://localhost:8081/.

History

Mocks

Usage

Smocker exposes two ports:

  • 8080 is the mock server port. It will expose the routes you register through the configuration port
  • 8081 is the configuration port. It's the port you will use to register new mocks. This port also exposes a user interface.

Hello, World!

To register a mock, you can use the YAML and the JSON formats. A basic mock might look like this:

# helloworld.yml
# This mock register two routes: GET /hello/world and GET /foo/bar
- request:
    # Note: the method could be omitted because GET is the default
    method: GET
    path: /hello/world
  response:
    # Note: the status could be omitted because 200 is the default
    status: 200
    headers:
      Content-Type: application/json
    body: >
      {
        "hello": "Hello, World!"
      }

- request:
    method: GET
    path: /foo/bar
  response:
    status: 204

You can then register it to the configuration server with the following command:

curl -XPOST \
  --header "Content-Type: application/x-yaml" \
  --data-binary "@helloworld.yml" \
  localhost:8081/mocks

After your mock is registered, you can query the mock server on the specified route, so that it returns the expected response to you:

$ curl -i localhost:8080/hello/world
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 05 Sep 2019 15:49:32 GMT
Content-Length: 31

{
  "hello": "Hello, World!"
}

To cleanup the mock server without restarting it, you can execute the following command:

curl -XPOST localhost:8081/reset

For more advanced usage, please read the project's documentation.

Development

Backend

The backend is written in Go. You can use the following commands to manage the development lifecycle:

  • make start: start the backend in development mode, with live reload
  • make build, make VERSION=xxx build: compile the code and generate a binary
  • make lint: run static analysis on the code
  • make format: automatically format the backend code
  • make test: execute unit tests
  • make test-integration: execute integration tests

Frontend

The frontend is written with TypeScript and React. You can use the following commands to manage the development lifecycle:

  • yarn install: install the dependencies
  • yarn start: start the frontend in development mode, with live reload
  • yarn build: generate the transpiled and minified files and assets
  • yarn lint: run static analysis on the code
  • yarn format: automatically format the frontend code
  • yarn test: execute unit tests
  • yarn test:watch: execute unit tests, with live reload

Documentation

The documentation is written in Markdown using Vuepress. You can use the following commands to manage the documentation:

  • yarn install: install the dependencies
  • yarn docs:generate: regenerate documentation screenshots (require the whole application to be started on the default ports)
  • yarn docs:dev: start the documentation in development mode, with live reload
  • yarn docs:build: generate the static production documentation

Docker

The application can be packaged as a standalone Docker image. You can use the following commands to manage the development lifecycle:

  • make build-docker, make VERSION=xxx build-docker: build the application as a Docker image
  • make start-docker, make VERSION=xxx start-docker: run a Smocker Docker image

Caddy

If you need to test Smocker with a base path, you can use the Caddyfile provided in the repository (Caddy v2):

  • make start-release, make VERSION=xxx start-release: create a released version of Smocker and launch it with /smocker/ as base path
  • make start-caddy: start Caddy to make Smocker accessible at http://localhost:8082/smocker/

Authors

Contributors

Issues
  • Issue #183 mock editor

    Issue #183 mock editor

    Très très draft, ça fait encore rien et c'est moche mais ça a du potentiel ^^

    Capture d’écran 2021-07-29 à 23 52 29

    Ideas:

    • [ ] autocomplete query parameter names and values from the history
    • [ ] autocomplete header names and values from history + common standard header names/values
    • [x] display the generated yaml at the bottom (collapsed)
    • [ ] validate regexps when using ShouldMatch (must be validated server side though)
    opened by Thiht 11
  • Support HTTPS

    Support HTTPS

    Currently Smocker can work as a http proxy if you try to call an API using http_proxy variable. The call will be redirected to Smocker.

    You can test this by:

    • starting Smocker:
    make start
    
    • making a call using Smocker as http proxy
    export http_proxy=http://localhost:8080/
    curl -v http://jsonplaceholder.typicode.com/todos/1
    

    Then you should see the call on Smocker.

    But when we try to make a call using HTTPS and HTTPS_PROXY, the http client send a CONNECT request on the proxy server which is not handled correctly by Smocker. It will respond to the call with a "No mock found matching the request" which will cancel the https request on client side.

    feat need-help 
    opened by gwleclerc 10
  • Static files path sould stay relative

    Static files path sould stay relative

    With the 0.17.0 release, I can not use a custom admin route /smocker/admin anymore . Admin page does not load because static files are not found.

    Now I have this index.html deployed :

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <link rel="icon" href="/assets/favicon.faca1f95.ico">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Smocker</title>
        <base href="/smocker/admin/">
        <link rel="stylesheet" href="/assets/index.f126532d.css">
        <script>
            window.basePath = "\/smocker\/admin\/", window.version = "0.17.0";
        </script>
    </head>
    
    <body>
        <div id="root"></div>
        <script type="module" src="/assets/index.80ecc049.js"></script>
        <script src="/assets/index.a1700b8b.js" nomodule="" defer></script>
    </body>
    
    </html>
    

    And before I had :

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <link rel="icon" href="assets/favicon.e6612986.ico" />
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta http-equiv="X-UA-Compatible" content="ie=edge" />
      <title>Smocker</title>
      <base href="/smocker/admin/" />
      <script>
        (window.basePath = "\/smocker\/admin\/"), (window.version = "0.16.3");
      </script>
      <link rel="stylesheet" href="assets/client.f3185208.css" />
    </head>
    
    <body>
      <div id="root"></div>
      <script src="assets/client.499147d7.js"></script>
    </body>
    
    </html>
    
    bug 
    opened by Osku 4
  • Create a mock from a request

    Create a mock from a request

    A nice to have workflow would be the following:

    • On a request in the history, click on a "+" (title: "Create mock from request")
    • The mock editor opens, prefilled with:
    - request:
        method:        # The request method
        path:          # The request path
        query_params:  # The request query params
        headers:       # The request headers (the user can remove the unnecessary ones as needed, but maybe we can filter some of them)
        # no body
    - response:
        status: 200
        headers:
          Content-Type: application/json
        body: >
    
    feat 
    opened by Thiht 4
  • CVE-2022-24675 - update go to 1.18 in go.mod

    CVE-2022-24675 - update go to 1.18 in go.mod

    Resolve CVE-2022-24675

    For some reason still getting this issue which I think may be caused by go.mod not enforcing min version to 1.18 - encoding/pem in Go before 1.17.9 and 1.8.x before 1.8.1 has a Decode stack overflow via a large amount of PEM data.

    Setting minimum version to stop packages using older go packages.

    opened by breneckd 3
  • Vulnerabilities in latest package

    Vulnerabilities in latest package

    There are a few vulnerabilities that I found with my security scan twistlock which I will outline. The first two are straight forward but there is one I cannot figure out and maybe you can help.

    1. There is also a crypto vuln outlined as v0.0.0-20200414173820-0848c9571904 which is fixed changing to this v0.0.0-20201216223049-8b5274cf687f CVE-2020-29652
    2. Issue with jwt-go v3.2.0 which is fixed in here
    3. This one I cannot figure out, there is 3 vuln in go 1.17.6 that are fixed in 1.17.7. I had a look into the image and it seems the smocker binary is causing this. I could not tell where 1.17.6 is used since the golang:1.17-alpine image actually uses 1.17.8. Is it possible because go.mod is set to go 1.15 it's causing this? For reference these are the vulnerabilities (CVE-2022-23806, CVE-2022-23773, CVE-2022-23772)

    The strange part is I tested the scan on just the builder image and it did not give the same issues. One of the vuln is related to crypto/elliptic which I could not see this package defined anywhere and the vulnerablity did not come up when I scanned only the golang stage of the image. So wondering if this one could also be somehow related to the yarn step of the image.

    Screen Shot 2022-03-09 at 12 31 10 pm

    chore 
    opened by breneckd 3
  • Setting `Host` header for proxy isn't working

    Setting `Host` header for proxy isn't working

    I'm trying to run (from a docker container) with these proxy settings:

      proxy:
          host: http://host.docker.internal:8000/
          headers:
              Host:
                - myapp.localhost
              X-foo-bar:
                - myval
    

    This results in my app properly seeing the X-foo-bar header, but the Host header is still set to host.docker.internal (and my app doesn't like that).

    I have no idea how to fix this?

    opened by tino 3
  • Allow setting mock priority

    Allow setting mock priority

    Hi,

    I would like to be able to set priority for our mocks. Here is an example use case: I have a route for email validation which takes an email and returns 200 if valid, 400 if invalid. I would like to define it in smocker so that every email, except those that contain the substring "invalid" return a 200 response. So I used this:

    - request:
        path:
          matcher: ShouldEqual
          value: /api/v1/validation
        headers:
          Content-Type: application/json
        method:
          matcher: ShouldEqual
          value: POST
        body:
          api-key:
            matcher: ShouldNotBeEmpty
          email:
            matcher: ShouldContainSubstring
            value: invalid
      response:
        body: |
          {
            "message": "Invalid email"
          }
        status: 400
        headers:
          Content-Type:
            - application/json
      context: {}
      state:
        id: mail-token-validation-send-invalid-email
        times_count: 0
        locked: false
        creation_date: 2021-09-27T12:47:25.490914394Z
    
    - request:
        path:
          matcher: ShouldEqual
          value: /api/v1/validation
        method:
          matcher: ShouldEqual
          value: POST
        headers:
          Content-Type: application/json
        body:
          api-key:
            matcher: ShouldNotBeEmpty
          email:
            matcher: ShouldNotBeEmpty
      response:
        body: |
          {
            "message": "Email valid"
          }
        status: 201
        headers:
          Content-Type:
            - application/json
      context: {}
      state:
        id: mail-token-validation-send-success
        times_count: 0
        locked: false
        creation_date: 2021-09-27T12:47:25.490914394Z
    

    It does not work because it always uses the success mock(or the first matched mock). For that to work, the "invalid" mock would need to have a higher priority than the "valid" mock. I would love to help with this but my knowledge in go is pretty bad. I can help with testing though.

    wontfix 
    opened by FelipeEmerim 3
  • build(deps): bump elliptic from 6.5.3 to 6.5.4

    build(deps): bump elliptic from 6.5.3 to 6.5.4

    Bumps elliptic from 6.5.3 to 6.5.4.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 3
  • build(deps): bump prismjs from 1.21.0 to 1.23.0

    build(deps): bump prismjs from 1.21.0 to 1.23.0

    Bumps prismjs from 1.21.0 to 1.23.0.

    Release notes

    Sourced from prismjs's releases.

    v1.23.0

    New components

    Updated components

    ... (truncated)

    Changelog

    Sourced from prismjs's changelog.

    1.23.0 (2020-12-31)

    New components

    Updated components

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 3
  • sprig v3 plus random delay

    sprig v3 plus random delay

    Minor changes to support the most recent sprig version.

    On the other hand I've changed a bit the delay logic to support random delays over each request

    opened by rmcruzv 3
  • The requests history not displayed, when link to the session is used

    The requests history not displayed, when link to the session is used

    To reproduce:

    1. Create smocker session
    2. make a few requests
    3. create another smocker session
    4. copy link to the #1 session and open it in a new browser tab.

    Expected result: Requests' history displayed in a new tab

    Current result: Requests' history seems to be empty. Making a new requests everrides the first session.

    Version: 0.17.1 (docker)

    opened by Sawiq 0
  • Request Body matcher is saved incorrectly in mocks.yml

    Request Body matcher is saved incorrectly in mocks.yml

    Summary

    Smocker appears to add an extra | character when saving a request-body matcher to the mocks.yml file.

    Smocker Version

    0.18.2 (using latest version of docker thiht/smocker:latest)

    Steps to Reproduce

    1. In the UI, add a new POST mock. Configure the request body with Default -> ShouldContainSubstring matcher Screen Shot 2022-06-06 at 4 20 27 PM

    2. Open mocks.yml

    Expected: body matcher is defined with yaml keys

    - request:
        body:
            matcher: ShouldContainSubstring
            value: test-substring
    

    Actual: body matcher has extra | character, which starts a multi-line string

    - request:
        body: |
            matcher: ShouldContainSubstring
            value: test-substring
    
    bug 
    opened by graeme-verticalscope 0
  • application/x-www-form-urlencoded body matcher

    application/x-www-form-urlencoded body matcher

    I have a use case for mocking third-party API where data is sent with POST via body in application/x-www-form-urlencoded format. It seems Smocker is pretty flexible in terms of various matchers for individual JSON keys but matchers for urlencoded params is not supported.

    So far my workaround looked the following:

    - request:
        method: POST
        path: "/test"
        headers:
          Content-Type: application/x-www-form-urlencoded
        body:
          matcher: ShouldEqual
          value: username=${username}&password=${password}
      response:
        status: 200
        headers:
          Content-Type: application/json
        body: >
          {
          }
    

    However, this solutions relies on order of the params which should not be relevant.

    Would you consider adding support for urlencoded body matching?

    feat 
    opened by mknapik 1
  • Smocker image for arm64v8 missing.

    Smocker image for arm64v8 missing.

    Could you please also release official ARM64v8 docker image ?

    docker run -d \
      --restart=always \
      -p 8080:8080 \
      -p 8081:8081 \
      --name smocker \
      thiht/smocker
    Unable to find image 'thiht/smocker:latest' locally
    latest: Pulling from thiht/smocker
    59bf1c3509f3: Pull complete
    ec1217117c09: Pull complete
    3ab0b2b28728: Pull complete
    Digest: sha256:dd573c7fd5ca33bcbe80ff5e155564b85b4307af5ab9ff16b12101d5b1baeeec
    Status: Downloaded newer image for thiht/smocker:latest
    WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
    a3f8fb8ab6b382c80385b3526a10e31cb43a4434d2f958d23a6638d1ac7bb3ab
    
    chore 
    opened by konstantinzolotarev 3
Releases(0.18.2)
A simple tool to convert socket5 proxy protocol to http proxy protocol

Socket5 to HTTP 这是一个超简单的 Socket5 代理转换成 HTTP 代理的小工具。 如何安装? Golang 用户 # Required Go 1.17+ go install github.com/mritd/[email protected] Docker 用户 docker pull m

mritd 6 Jun 25, 2022
Tcp-proxy - A dead simple reverse proxy server.

tcp-proxy A proxy that forwords from a host to another. Building go build -ldflags="-X 'main.Version=$(git describe --tags $(git rev-list --tags --max

Injamul Mohammad Mollah 0 Jan 2, 2022
Go-http-sleep: Delayed response http server, useful for testing various timeout issue for application running behind proxy

delayed response http server, useful for testing various timeout issue for application running behind proxy

guessi 0 Jan 22, 2022
“Dear Port80” is a zero-config TCP proxy server that hides SSH connection behind a HTTP server!

Dear Port80 About The Project: “Dear Port80” is a zero-config TCP proxy server that hides SSH connection behind a HTTP server! +---------------------

Abbas Gheydi 5 May 20, 2022
A simple go program to proxy http request through a server with caching

go-http-proxy A simple go program to proxy http requests through a server with caching Usage All cli options are optional, and have the default values

null 1 Nov 21, 2021
Http-server - A HTTP server and can be accessed via TLS and non-TLS mode

Application server.go runs a HTTP/HTTPS server on the port 9090. It gives you 4

Vedant Pareek 0 Feb 3, 2022
Backend implementation using go, proto3 and gRPC for a mock online store

Backend implementation using go, proto3 and gRPC for a mock online store Ricardo RICO URIBE Tasks I - Order service The current system exposes a produ

Ricardo Rico 0 Oct 10, 2021
A light-weight and sexy HTTP proxy server.

A light-weight and sexy HTTP proxy server. This is a reverse-proxy server meant to be hoested online. Once hosted, webpages through the HTTP and HTTPS

1/7 0 Feb 13, 2022
A http proxy server chaining a upstream which needs authentication headers.

Normalize HTTP Proxy A http proxy server chaining a upstream which needs authentication headers. local -> [np] -> upstream -> destination Usage Norma

LOGI 14 May 23, 2022
A HTTP proxy server tunnelling through wireguard

wg-http-proxy This project hacks together the excellent https://github.com/elazarl/goproxy and https://git.zx2c4.com/wireguard-go into an HTTP proxy s

Sebastian Himberger 8 Jun 21, 2022
A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration

paddy 简介 paddy是一款单进程的独立运行的web server,基于golang的标准库net/http实现。 paddy提供以下功能: 直接配置http响应 目录文件服务器 proxy_pass代理 http反向代理 支持请求和响应插件 部署 编译 $ go build ./main/p

fangyousong 5 May 2, 2022
An experimental Tor-Proxy serivce written in Go using Go-proxy and Go-libtor.

tor-proxy An experimental standalone tor-proxy service built with Go, using go-proxy, go-libtor and bine. This is a simple replacement to Tor's origin

Narasimha Prasanna HN 36 Jun 14, 2022
IP2Proxy Go package allows users to query an IP address to determine if it was being used as open proxy, web proxy, VPN anonymizer and TOR exits.

IP2Proxy Go Package This package allows user to query an IP address if it was being used as VPN anonymizer, open proxies, web proxies, Tor exits, data

IP2Location 13 Apr 16, 2022
Battlesnake-logging-proxy - A little proxy between the internet and your battlesnake

battlesnake-logging-proxy a little proxy between the internet and your battlesna

Penelope Phippen 3 Feb 11, 2022
mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together

mt-multiserver-proxy mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together. It is the successor to multiserv

null 9 May 18, 2022
Proxy - Minimalistic TCP relay proxy.

Proxy Minimalistic TCP relay proxy. Installation ensure you have go >= 1.17 installed clone the repo cd proxy go install main.go Examples Listen on po

null 1 May 22, 2022
Simple HTTP/HTTPS proxy - designed to be distributed as a self-contained binary that can be dropped in anywhere and run.

Simple Proxy This is a simple HTTP/HTTPS proxy - designed to be distributed as a self-contained binary that can be dropped in anywhere and run. Code b

Jamie Thompson 13 May 9, 2022
This is a tool that will proxy simple HTTPS requests to an external HTTP endpoint

AcmeShield A secured HTTP proxy that forwards requests from a remote service(Postman). This is a tool that will proxy simple HTTPS requests to an exte

Octavio Cano 1 Mar 21, 2022