MockServer:模拟外部http / https响应会拒绝80/443上的连接

问题描述

我试图实现的是模拟google oauth2端点的响应。 这是我的设置:

# docker-compose.yml
version: '3.8'

services:
  busyBox:
    image: yauritux/busyBox-curl:latest
    command: tail -f /dev/null
    networks:
      - our-network

  api-mock:
    image: mockserver/mockserver
    networks:
      our-network:
        aliases:
          - oauth2.googleapis.com
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /api-mock/expectations_init.json
      MOCKSERVER_WATCH_INITIALIZATION_JSON: 'true'
    volumes:
      - ./api-mock/:/api-mock
    ports:
      - 1080:1080

networks:
  our-network:

我们的Mockserver期望

# ./api-mock/expectations_init.json
[
  {
    "httpRequest": {
      "method": "GET","path": "/token","secure": true
    },"httpResponse": {
      "statusCode": 200,"body": "Hello World - secure"
    }
  },{
    "httpRequest": {
      "method": "GET","secure": false
    },"body": "Hello World"
    }
  }
]

我的项目结构

stackoverflow
    - ./api-mock
        - expectations_init.json
    - docker-compose.yml

要运行此最小示例,请运行

docker-compose up -d

查看模拟服务器的仪表板

localhost:1080/mockserver/dashboard

我期望的工作是:

docker exec stackoverflow_busyBox_1 curl -k https://oauth2.googleapis.com/token
# curl: (7) Failed connect to oauth2.googleapis.com:443; Connection refused

有效的方法是:

docker exec stackoverflow_busyBox_1 curl -k https://oauth2.googleapis.com:1080/token
# Hello World - secure

与此处相同,有望正常工作

docker exec stackoverflow_busyBox_1 curl -k http://oauth2.googleapis.com/token
# curl: (7) Failed connect to oauth2.googleapis.com:80; Connection refused

以及有效的替代方法

docker exec stackoverflow_busyBox_1 curl -k http://oauth2.googleapis.com:1080/token
# Hello World

由于我无法控制供应商代码正在调用的URL,因此我错过了什么才能配置为在不通过端口的情况下获得响应。我无法在模拟服务器的文档中找到有关此用例的任何提示以实现此目的。也许这是docker / docker-compose的问题?

最诚挚的问候

解决方法

问题不是在docker-compose中,而是在模拟服务器映像中。由于它是在没有root权限的情况下执行的,因此无法使用端口80,但始终在端口1080上启动(有关详细信息,请检查https://www.mock-server.com/where/docker.html#run_docker_container)。

您可以使用以下方法通过启动docker映像来更改端口:

docker run --rm --name mockserver mockserver/mockserver -serverPort 1090

这将使映像在端口1090上运行(这不是您想要的),或者您可以强制容器以root用户身份运行并将端口更改为80。例如

docker run --user root --rm --name mockserver mockserver/mockserver -serverPort 80

无论如何,可能有充分的理由不为此使用root。我从未使用过该软件,所以我不能说真的。

然后您可以轻松地以docker-compose格式移植命令

,

此设置非常有用,尤其是在通过模拟服务器转发请求时:

nginx-虚拟主机:

server {
    listen 80 default;

    location / {
        return 418;
    }
}

server {
    listen 443 ssl;

    ssl_certificate /etc/ssl/certs/local.pub.pem;
    ssl_certificate_key /etc/ssl/private/local.key.pem;
    ssl_session_cache shared:SSL:16m;
    ssl_session_timeout 10m;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers RC4:HIGH:!aNULL:!MD5:!kEDH;
    ssl_prefer_server_ciphers on;

    location / {
        return 418;
    }
}

docker-compose.yml

version: '3.8'

services:
  nginx:
    build:
      context: .
      dockerfile: docker/nginx/Dockerfile
    networks:
      - our-network

  busybox:
    image: yauritux/busybox-curl:latest
    command: tail -f /dev/null
    networks:
      - our-network

  api-mock: *api-mock
    image: mockserver/mockserver
    user: root
    command: -serverPort 80
    networks:
      our-network:
        aliases:
          - oauth2.googleapis.com
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /api-mock/expectations_init.json
      MOCKSERVER_WATCH_INITIALIZATION_JSON: 'true'
    volumes:
      - ./api-mock/:/api-mock
    ports:
      - 1080:80

  api-mock-secure:
    <<: *api-mock
    command: -serverPort 443
    ports:
      - 1081:443

networks:
  our-network:

expectations_init.json

[
  {
    "httpRequest": {
      "method": "GET","path": "/token","headers": {
        "Host": [ "oauth2.googleapis.com" ]
      },"secure": true
    },"httpResponse": {
      "statusCode": 200,"body": "Hello World - secure\n"
    }
  },{
    "httpRequest": {
      "method": "GET","secure": false
    },"body": "Hello World\n"
    }
  },{
    "httpRequest": {
      "secure": false
    },"httpForward": {
      "host": "nginx","port": 80,"scheme": "HTTP"
    }
  },{
    "httpRequest": {
      "secure": true
    },"port": 443,"scheme": "HTTPS"
    }
  }
]

感谢Stefano

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...