[PYTHON] J'ai créé un proxy HTTP qui peut enregistrer et lire les réponses HTTP.

Comme le titre l'indique, nous avons créé un proxy HTTP qui peut enregistrer et lire les réponses HTTP.

Ce que je voulais

Je développe un robot d'exploration au travail, et j'ai toujours voulu quelque chose pour simuler un service externe et renvoyer une réponse HTTP pour écrire un test E2E à l'échelle du système à l'aide du robot.

Je cherchais les quatre fonctions suivantes. ** 1. Vous pouvez enregistrer une réponse HTTP et répondre en fonction des données enregistrées ** ** 2. Les données enregistrées peuvent être facilement modifiées pour simuler n'importe quelle réponse HTTP ** ** 3. Peut être utilisé comme proxy HTTP pour le rendre indépendant de tout langage ou framework de test particulier ** ** 4. Prend en charge HTTPS **

Il y avait une bibliothèque qui se moquait d'un client HTTP qui pouvait être utilisé à des fins de test et renvoyé une réponse, et il y avait diverses choses qui pouvaient créer une simulation en simulant une réponse API, mais je n'ai pas trouvé celle qui pouvait être utilisée exactement, alors j'ai décidé d'en créer une. Fait.

À propos, bien qu'il n'ait pas atteint l'objectif de cette fois, il existe un OSS appelé mountebank qui peut être utilisé pour tester des microservices, et il semble être incroyablement pratique car il peut également jouer des réponses arbitraires. était. Il existe également une bibliothèque créée par netflix appelée Polly.JS, qui est limitée à JavaScript (navigateur, node.js), et est un serveur HTTP. Vous pouvez créer un stub pour renvoyer une réponse arbitraire et vous pouvez ajuster le temps de réponse, ce qui semble très pratique. J'aimerais utiliser les deux un jour s'il y a une application appropriée.

Comment ça fonctionne

Après de nombreuses recherches, j'ai trouvé un excellent logiciel de proxy HTTP appelé mitmproxy qui répond à cet objectif. Le "mitm" de mitmproxy provient de * l'attaque Man In The Middle *, et en mettant fin à la communication SSL avec ce proxy, il est possible de manipuler le contenu même avec une réponse à la requête HTTPS. Excellent proxy HTTP! (Effrayant)

Bien que mitmproxy lui-même n'ait pas pour fonction d'enregistrer et de lire les réponses HTTP, il a une fonction très pratique d'insérer des scripts Python arbitraires à divers moments, comme lors de la réception d'une requête et lors de l'envoi d'une réponse, afin qu'elle puisse être étendue. Par conséquent, j'ai créé un plug-in pour enregistrer et lire les réponses HTTP en utilisant ce mécanisme.

image.png

Le code source est disponible ici. https://github.com/Chanmoro/record-and-replay-proxy

Nous avons publié une image Docker pour une utilisation facile. https://hub.docker.com/r/chanmoro/record-and-replay-proxy

Comment utiliser

L'image Docker est publiée sur Docker Hub (https://hub.docker.com/r/chanmoro/record-and-replay-proxy) donc elle est facile à utiliser.

1. Enregistrer la réponse HTTP

Démarrez le proxy HTTP en mode enregistrement avec la commande suivante:

$ docker run -it --rm -p 8080:8080 -v ${PWD}/response_data:/app/response_data chanmoro/record-and-replay-proxy record

La réponse enregistrée ici est enregistrée dans / app / response_data, alors montez le répertoire local pour que les données restent.

2. Envoyer une requête HTTP (enregistrement)

Ici, à titre d'exemple, nous enregistrerons la réponse lors de l'accès à https://github.com/ en utilisant curl.

$ curl -k -x localhost:8080 https://github.com/

À ce stade, curl utilise l'autocertificat émis par mitmproxy pour la communication SSL. Si vous envoyez une requête dans l'état par défaut, une erreur se produira lors du contrôle de validité SSL, alors décochez-la.

Réponse HTTP enregistrée

La réponse HTTP enregistrée est stockée dans response_data dans le répertoire actuel monté sur le conteneur Docker.

$ tree response_data
response_data
└── https%3A%2F%2Fgithub.com%2F #L'URL de la requête devient le nom du répertoire
    └── GET                     #Méthode HTTP
        ├── metadata            #Méthode HTTP, URL de requête, état de la réponse HTTP
        ├── response_body       #Corps de réponse
        └── response_header     #En-tête de réponse

metadata stocke la méthode HTTP, l'URL de la requête et l'état de la réponse HTTP de la requête enregistrée.

metadata


{
    "url": "https://github.com/",
    "method": "GET",
    "status": 200
}

Le corps de la réponse est enregistré dans «response_body».

response_body


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars0.githubusercontent.com">
  <link rel="dns-prefetch" href="https://avatars1.githubusercontent.com">
  <link rel="dns-prefetch" href="https://avatars2.githubusercontent.com">
  <link rel="dns-prefetch" href="https://avatars3.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
...

L'en-tête de réponse est enregistré dans «response_header».

response_header


Date: Thu, 12 Dec 2019 10:20:49 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Server: GitHub.com
Status: 200 OK
Vary: X-PJAX
...

3. Lisez la réponse HTTP enregistrée

Pour lire la réponse HTTP enregistrée, démarrez le proxy HTTP en mode de relecture. Le répertoire à monter sur / app / response_data spécifie le répertoire qui contient les données de réponse enregistrées.

$ docker run -it --rm -p 8080:8080 -v ${PWD}/response_data:/app/response_data chanmoro/record-and-replay-proxy replay

4. Envoyez une requête HTTP (lecture)

Si vous envoyez une requête HTTP de la même manière que lors de l'enregistrement avec le proxy HTTP s'exécutant en mode de relecture, la réponse enregistrée sera renvoyée. En mode de relecture, le proxy n'accède pas à https: // github.com /, il peut donc être utilisé hors ligne.

$ curl -k -x localhost:8080 https://github.com/

Modifions les données de réponse afin que nous puissions confirmer qu'elles ont été rejouées. Modifiez les données avec le contenu suivant.

metadata


{
    "url": "https://github.com/",
    "method": "GET",
    "status": 500
}

response_body


This is recorded response!

response_header


Date: Thu, 12 Dec 2019 10:20:49 GMT
Status: 500 Error
Hoge: This is Hoge header.

Vérifions si la réponse est renvoyée comme éditée.

$ curl -v -k -x localhost:8080 https://github.com/
...
> GET / HTTP/1.1
> Host: github.com
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
< Date: Thu, 12 Dec 2019 10:20:49 GMT
< Status: 500 Error
< Hoge: This is Hoge header.
< content-length: 26
< 
* Connection #0 to host localhost left intact
This is recorded response!

Vous pouvez voir que l'état HTTP, l'en-tête de la réponse et le corps de la réponse correspondent exactement à ce que vous avez modifié. Le meilleur!

Résumé

Cet article présente les fonctions et l'utilisation du proxy HTTP record-and-replay-proxy qui peut enregistrer et lire la réponse HTTP créée. Fait.

Cela facilite le test de la capacité d'accéder aux services externes et aux API.

Veuillez l'utiliser!

Recommended Posts

J'ai créé un proxy HTTP qui peut enregistrer et lire les réponses HTTP.
Mettre en place un serveur FTP qui peut être créé et détruit immédiatement (en Python)
Utilisez la commande pip dans un environnement proxy HTTP qui nécessite une authentification