(self)
| 159 | return payload |
| 160 | |
| 161 | def do_POST(self) -> None: |
| 162 | if self.path != "/run": |
| 163 | self.send_response(404) |
| 164 | self.end_headers() |
| 165 | return |
| 166 | |
| 167 | if not self.bridge_token_valid(): |
| 168 | self.reject(403, "invalid bridge capability") |
| 169 | return |
| 170 | |
| 171 | length = self.request_body_length() |
| 172 | if length is None: |
| 173 | return |
| 174 | |
| 175 | payload = self.read_request_payload(length) |
| 176 | if payload is None: |
| 177 | return |
| 178 | |
| 179 | server_url = payload.get("server_url") |
| 180 | if not isinstance(server_url, str): |
| 181 | self.reject(400, "server_url must be a string") |
| 182 | return |
| 183 | |
| 184 | parsed = urlparse(server_url) |
| 185 | if parsed.scheme not in {"http", "https"}: |
| 186 | self.reject(403, "server_url scheme must be http or https") |
| 187 | return |
| 188 | |
| 189 | try: |
| 190 | target_ip = canonical_ip(parsed.hostname or "") |
| 191 | expected_ip = canonical_ip(RUNNER_IP) |
| 192 | except ValueError: |
| 193 | self.reject(403, "server_url host must match the runner container IP") |
| 194 | return |
| 195 | |
| 196 | if target_ip != expected_ip: |
| 197 | self.reject(403, "server_url host must match the runner container IP") |
| 198 | return |
| 199 | |
| 200 | payload_env = payload.get("env", {}) |
| 201 | if not isinstance(payload_env, dict): |
| 202 | self.reject(400, "env must be an object") |
| 203 | return |
| 204 | if any(name not in ALLOWED_CONFORMANCE_ENV for name in payload_env): |
| 205 | self.reject(403, "env contains unsupported keys") |
| 206 | return |
| 207 | if any(not isinstance(value, str) for value in payload_env.values()): |
| 208 | self.reject(400, "env values must be strings") |
| 209 | return |
| 210 | |
| 211 | env = subprocess_env(payload_env, str(expected_ip)) |
| 212 | log(f"running client for {server_url}") |
| 213 | try: |
| 214 | result = subprocess.run( |
| 215 | ["bash", "e2e/mcp-conformance/client-through-openshell.sh", server_url], |
| 216 | cwd=ROOT, |
| 217 | env=env, |
| 218 | stdin=subprocess.DEVNULL, |
nothing calls this directly
no test coverage detected