#!/usr/bin/env python2 ### # ============LICENSE_START======================================================= # ONAP CLAMP # ================================================================================ # Copyright (C) 2018 AT&T Intellectual Property. All rights # reserved. # Modifications Copyright (C) 2021 Nordix Foundation. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 # ============LICENSE_END============================================ # =================================================================== # ### import json import requests import os import errno import SimpleHTTPServer import SocketServer import argparse import tempfile import signal import uuid import shutil parser = argparse.ArgumentParser(description="3rd party Cache & Replay") parser.add_argument("--username", "-u", type=str, help="Set the username for contacting 3rd party - only used for GET") parser.add_argument("--password", "-p", type=str, help="Set the password for contacting 3rd party - only used for GET") parser.add_argument("--root", "-r", default=tempfile.mkdtemp(), type=str, help="Root folder for the proxy cache") parser.add_argument("--temp", "-t", default=tempfile.mkdtemp(), type=str, help="Temp folder for the generated content") parser.add_argument("--proxy" , type=str, help="Url of the Act as a proxy. If not set, this script only uses the cache and will return a 404 if files aren't found") parser.add_argument("--port", "-P", type=int, default="8081", help="Port on which the proxy should listen to") parser.add_argument("--verbose", "-v", type=bool, help="print(more information in case of error") parser.add_argument("--proxyaddress","-a", type=str, help="Address of this proxy, generally either third-party-proxy:8085 or localhost:8085 depending if started with docker-compose or not") options = parser.parse_args() PORT = options.port HOST = options.proxy AUTH = (options.username, options.password) HEADERS = {'X-ECOMP-InstanceID':'CLAMP'} CACHE_ROOT = str(options.root) TMP_ROOT = str(options.temp) PROXY_ADDRESS=str(options.proxyaddress) def signal_handler(signal_sent, frame): global httpd if signal_sent == signal.SIGINT: print('Got Ctrl-C (SIGINT)') httpd.socket.close() httpd.shutdown() httpd.server_close() class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): def print_headers(self): for header,value in self.headers.items(): print("header: %s : %s" % (header, value)) def check_credentials(self): pass def _send_content(self, header_file, content_file): self.send_response(200) with open(header_file, 'rb') as f: headers = json.load(f) for key,value in headers.items(): if key in ('Transfer-Encoding',): continue self.send_header(key, value) self.end_headers() with open(content_file,'rb') as f: fc = f.read() self.wfile.write(fc) def _write_cache(self,cached_file_folder, header_file, content_file, response): os.makedirs(cached_file_folder, 0o777) with open(content_file, 'w') as f: f.write(response.raw.read()) with open(header_file, 'w') as f: json.dump(dict(response.raw.headers), f) # Entry point of the code def _get_cached_file_folder_name(self,folder): cached_file_folder = '%s/%s' % (folder, self.path,) print("Cached file name before escaping : %s" % cached_file_folder) cached_file_folder = cached_file_folder.replace('+','').replace('<','<').replace('>','>').replace('?','?').replace('*','*').replace('\\','*').replace(':',':').replace('|','|') print("Cached file name after escaping (used for cache storage) : %s" % cached_file_folder) return cached_file_folder def _get_cached_content_file_name(self,cached_file_folder): return "%s/.file" % (cached_file_folder,) def _get_cached_header_file_name(self,cached_file_folder): return "%s/.header" % (cached_file_folder,) def _create_cache(self, generated_json, cached_file_folder, cached_file_header, cached_file_content): print("jsonGenerated: " + generated_json) if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o775) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(generated_json)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w+') as f: f.write(generated_json) def _execute_content_generated_cases(self,http_type): print("Testing special cases, cache files will be sent to :" +TMP_ROOT) cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) _file_available = os.path.exists(cached_file_content) if self.path.startswith("/dcae-service-types?asdcResourceId=") and http_type == "GET": if not _file_available: print("self.path start with /dcae-service-types?asdcResourceId=, generating response json...") uuidGenerated = str(uuid.uuid4()) typeId = "typeId-" + uuidGenerated typeName = "typeName-" + uuidGenerated print("typeId generated: " + typeName + " and typeName: "+ typeId) jsonGenerated = "{\"totalCount\":1, \"items\":[{\"typeId\":\"" + typeId + "\", \"typeName\":\"" + typeName +"\"}]}" print("jsonGenerated: " + jsonGenerated) os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w') as f: f.write(jsonGenerated) return True elif self.path.startswith("/dcae-operationstatus/install") and http_type == "GET": if not _file_available: print("self.path start with /dcae-operationstatus/install, generating response json...") jsonGenerated = "{\"operationType\": \"install\", \"status\": \"succeeded\"}" print("jsonGenerated: " + jsonGenerated) try: os.makedirs(cached_file_folder, 0o777) except OSError as e: if e.errno != errno.EEXIST: raise print(cached_file_folder+" already exists") with open(cached_file_header, 'w') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w') as f: f.write(jsonGenerated) return True elif self.path.startswith("/dcae-operationstatus/uninstall") and http_type == "GET": if not _file_available: print("self.path start with /dcae-operationstatus/uninstall, generating response json...") jsonGenerated = "{\"operationType\": \"uninstall\", \"status\": \"succeeded\"}" print("jsonGenerated: " + jsonGenerated) try: os.makedirs(cached_file_folder, 0o777) except OSError as e: if e.errno != errno.EEXIST: raise print(cached_file_folder+" already exists") with open(cached_file_header, 'w') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w') as f: f.write(jsonGenerated) return True elif self.path.startswith("/sdc/v1/catalog/services/") and http_type == "POST": if not _file_available: print("self.path start with /sdc/v1/catalog/services/, generating response json...") jsondata = json.loads(self.data_string) jsonGenerated = "{\"artifactName\":\"" + jsondata['artifactName'] + "\",\"artifactType\":\"" + jsondata['artifactType'] + "\",\"artifactURL\":\"" + self.path + "\",\"artifactDescription\":\"" + jsondata['description'] + "\",\"artifactChecksum\":\"ZjJlMjVmMWE2M2M1OTM2MDZlODlmNTVmZmYzNjViYzM=\",\"artifactUUID\":\"" + str(uuid.uuid4()) + "\",\"artifactVersion\":\"1\"}" print("jsonGenerated: " + jsonGenerated) os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w') as f: f.write(jsonGenerated) return True elif self.path.startswith("/dcae-deployments/") and http_type == "PUT": print("self.path start with /dcae-deployments/ DEPLOY, generating response json...") #jsondata = json.loads(self.data_string) jsonGenerated = "{\"operationType\":\"install\",\"status\":\"processing\",\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus/install?test=test\"}}" print("jsonGenerated: " + jsonGenerated) if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w+') as f: f.write(jsonGenerated) return True elif self.path.startswith("/dcae-deployments/") and http_type == "DELETE": print("self.path start with /dcae-deployments/ UNDEPLOY, generating response json...") #jsondata = json.loads(self.data_string) jsonGenerated = "{\"operationType\":\"uninstall\",\"status\":\"processing\",\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus/uninstall?test=test\"}}" print("jsonGenerated: " + jsonGenerated) if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w+') as f: f.write(jsonGenerated) return True elif (self.path.startswith("/pdp/api/") and (http_type == "PUT" or http_type == "DELETE")) or (self.path.startswith("/pdp/api/policyEngineImport") and http_type == "POST"): print("self.path start with /pdp/api/, copying body to response ...") if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}") with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True elif self.path.startswith("/policy/api/v1/policytypes/") and http_type == "POST": print("self.path start with POST new policy API /pdp/api/, copying body to response ...") if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}") with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True elif self.path.startswith("/policy/api/v1/policytypes/") and http_type == "DELETE": print("self.path start with DELETE new policy API /policy/api/v1/policytypes/ ...") if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len("")) + "\", \"Content-Type\": \""+str("")+"\"}") with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True elif self.path.startswith("/policy/pap/v1/pdps/policies") and http_type == "POST": print("self.path start with POST new policy API /policy/pap/v1/pdps/ ...") if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len("")) + "\", \"Content-Type\": \""+str("")+"\"}") with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True elif (self.path.startswith("/policy/pap/v1/policies/deployed/")) and http_type == "GET": print("self.path start with /policy/api/v1/policytypes/, generating response json...") jsonGenerated = "{\"policyTypeId\": \"onap.policies.controlloop.operational\",\"policyTypeVersion\": \"1.0.0\",\"policyId\": \"OPERATIONAL_z711F_v1_0_ResourceInstanceName1_tca\"}" print("jsonGenerated: " + jsonGenerated) if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w') as f: f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w') as f: f.write(jsonGenerated) return True elif self.path.startswith("/dcae-service-types") and http_type == "GET": if not _file_available: self.path = "/dcae-service-types" cached_file_folder = '%s/%s' % (TMP_ROOT, self.path) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) print("self.path start with /dcae-service-types, generating response json...") response = "{\"links\": {\"previousLink\": {\"title\": \"string\",\"rel\": \"string\",\"uri\": \"string\",\"uriBuilder\": {},\"rels\": [\"string\"],\"params\": {\"additionalProp1\": \"string\",\"additionalProp2\": \"string\",\"additionalProp3\": \"string\"},\"type\": \"string\"},\"nextLink\": {\"title\": \"string\",\"rel\": \"string\",\"uri\": \"string\",\"uriBuilder\": {},\"rels\": [\"string\"],\"params\": {\"additionalProp1\": \"string\",\"additionalProp2\": \"string\",\"additionalProp3\": \"string\"},\"type\": \"string\"}},\"totalCount\": 1,\"items\": [{\"owner\": \"testOwner\",\"application\": \"testApplication\",\"component\": \"testComponent\",\"typeName\": \"testTypeName\",\"typeVersion\": 0,\"blueprintTemplate\": \"testBlueprintTemplate\",\"serviceIds\": [\"serviceId1\", \"serviceId2\"],\"vnfTypes\": [\"vnfType1\", \"vnfType2\"],\"serviceLocations\": [\"serviceLocation1\", \"serviceLocation2\"],\"asdcServiceId\": \"testAsdcServiceId\",\"asdcResourceId\": \"0\",\"asdcServiceURL\": \"testAsdcServiceURL\",\"typeId\": \"testtypeId\",\"selfLink\": {\"title\": \"selfLinkTitle\",\"rel\": \"selfLinkRel\",\"uri\": \"selfLinkUri\",\"uriBuilder\": {},\"rels\": [\"string\"],\"params\": {\"additionalProp1\": \"string\",\"additionalProp2\": \"string\",\"additionalProp3\": \"string\"},\"type\": \"string\"},\"created\": \"2020-01-22T09:38:15.436Z\",\"deactivated\": \"2020-01-22T09:38:15.437Z\"},{\"owner\": \"testOwner2\",\"application\": \"testApplication1\",\"component\": \"testComponent2\",\"typeName\": \"testTypeName2\",\"typeVersion\": 0,\"blueprintTemplate\": \"testBlueprintTemplate2\",\"serviceIds\": [\"serviceId3\", \"serviceId4\"],\"vnfTypes\": [\"vnfType13\", \"vnfType4\"],\"serviceLocations\": [\"serviceLocation3\", \"serviceLocation4\"],\"asdcServiceId\": \"testAsdcServiceId\",\"asdcResourceId\": \"1\",\"asdcServiceURL\": \"testAsdcServiceURL2\",\"typeId\": \"testtypeId2\",\"selfLink\": {\"title\": \"selfLinkTitle\",\"rel\": \"selfLinkRel\",\"uri\": \"selfLinkUri\",\"uriBuilder\": {},\"rels\": [\"string\"],\"params\": {\"additionalProp1\": \"string\",\"additionalProp2\": \"string\",\"additionalProp3\": \"string\"},\"type\": \"string\"},\"created\": \"2020-01-22T09:38:15.436Z\",\"deactivated\": \"2020-01-22T09:38:15.437Z\"}]}" print("jsonGenerated: " + response) os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w') as f: f.write("{\"Content-Length\": \"" + str(len(response)) + "\", \"Content-Type\": \"application/json\"}") with open(cached_file_content, 'w') as f: f.write(response) return True elif (self.path.startswith("/onap/controlloop/v2/commission/toscaservicetemplate")) and http_type == "GET": if not _file_available: cached_file_folder = cached_file_folder.split('bridgeEndpoint')[0] print(("cached file folder for onap is %s: ", cached_file_folder)) print("self.path start with /onap/controlloop/v2/commission/, generating response json...") jsonGenerated = "{\"tosca_definitions_version\": \"tosca_simple_yaml_1_1_0\",\"data_types\": {},\"node_types\": {}, \"policy_types\": {}, \"topology_template\": {}, \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\", \"metadata\": {}}" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission/toscaServiceTemplateSchema")) and http_type == "GET": if not _file_available: cached_file_folder = cached_file_folder.split('bridgeEndpoint')[0] print(("cached file folder for onap is %s: ", cached_file_folder)) print("self.path start with /onap/controlloop/v2/commission/, generating response json...") jsonGenerated = "{\"tosca_definitions_version\": \"tosca_simple_yaml_1_1_0\",\"data_types\": {},\"node_types\": {}, \"policy_types\": {}, \"topology_template\": {}, \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\", \"metadata\": {}}" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission/elements")) and http_type == "GET": if not _file_available: print("self.path start with /commission/elements Control Loop Elements, generating response json...") jsonGenerated = "[{\"name\": ,\"org.onap.domain.pmsh.PMSH_DCAEMicroservice\": [{ \"version\": \"1.2.3\", \"derived_from\": null }]}]" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission")) and http_type == "GET": if not _file_available: print("self.path start with /commission control loop definition, generating response json...") #jsondata = json.loads(self.data_string) jsonGenerated = "[{\"name\": ,\"org.onap.domain.pmsh.PMSHControlLoopDefinition\": [{ \"version\": \"1.2.3\", \"derived_from\": null }]}]" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission/getCommonOrInstanceProperties")) and http_type == "GET": if not _file_available: print("self.path start with /commission getting common properties, generating response json...") with open("example/node_template.json", "r") as f: jsonGenerated = f.read() self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission")) and http_type == "POST": print("self.path start with POST /onap/controlloop/v2/commission, copying body to response ...") if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}") with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True elif (self.path.startswith("/onap/controlloop/v2/commission")) and http_type == "DELETE": print("self.path start with /commission Decommissioning, generating response json...") jsonGenerated = "{\"errorDetails\": null,\"affectedControlLoopDefinitions\": [{ \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\" }]}" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/instantiation")) and http_type == "GET": print("self.path start with /instantiation Retrieving Instantiation, generating response json...") jsonGenerated = "{\"controlLoopList\": [{\"name\": \"PMSHInstance0\",\"version\": \"1.0.1\",\"definition\": {},\"state\": \"UNINITIALISED\",\"orderedState\": \"UNINITIALISED\",\"description\": \"PMSH control loop instance 0\",\"elements\": {}}]}"; self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/instanceProperties")) and http_type == "POST": print("self.path start with POST /onap/controlloop/v2/instanceProperties, copying body to response ...") if not os.path.exists(cached_file_folder): os.makedirs(cached_file_folder, 0o777) with open(cached_file_header, 'w+') as f: f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}") with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True elif (self.path.startswith("/onap/controlloop/v2/instanceProperties")) and http_type == "DELETE": print("self.path start with /instanceProperties Deleting instance properties, generating response json...") jsonGenerated = "{\"errorDetails\": null,\"affectedControlLoopDefinitions\": [{ \"name\": \"PMSH_Instance1\", \"version\": \"2.3.1\" }]}" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/instantiation/command")) and http_type == "PUT": print("self.path start with /instantiation/command Changing order state, generating response json...") jsonGenerated = "{\"orderedState\":\"PASSIVE\",\"controlLoopIdentifierList\":[{\"name\":\"PMSH_Instance1\",\"version\":\"2.3.1\"}]}" self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True else: return False def do_GET(self): cached_file_folder = "" cached_file_content ="" cached_file_header="" print("\n\n\nGot a GET request for %s " % self.path) self.print_headers() self.check_credentials() # Verify if it's a special case is_special = self._execute_content_generated_cases("GET") if is_special: cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) else: cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) _file_available = os.path.exists(cached_file_content) if not _file_available: print("Request for data currently not present in cache: %s" % (cached_file_folder,)) if not HOST: self.send_response(404) self.end_headers() self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!') print("HOST value is: %s " % (options.proxy)) return "404 Not found, no remote HOST specified on the emulator !!!" url = '%s%s' % (HOST, self.path) response = requests.get(url, auth=AUTH, headers=HEADERS, stream=True) if response.status_code == 200: self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response) else: print('Error when requesting file :') print('Requested url : %s' % (url,)) print('Status code : %s' % (response.status_code,)) print('Content : %s' % (response.content,)) self.send_response(response.status_code) self.end_headers() self.wfile.write('404 Not found, nothing found on the remote server !!!') return response.content else: print("Request for data currently present in cache: %s" % (cached_file_folder,)) print("HOST value is: %s " % (HOST)) self._send_content(cached_file_header, cached_file_content) if self.path.startswith("/dcae-service-types?asdcResourceId="): print("DCAE case deleting folder created " + cached_file_folder) shutil.rmtree(cached_file_folder, ignore_errors=False, onerror=None) elif self.path.startswith("/dcae-service-types"): print("DCAE case deleting folder created " + cached_file_folder) shutil.rmtree(cached_file_folder, ignore_errors=False, onerror=None) else: print("NOT in DCAE case deleting folder created " + cached_file_folder) def do_POST(self): cached_file_folder = "" cached_file_content ="" cached_file_header="" print("\n\n\nGot a POST for %s" % self.path) self.check_credentials() self.data_string = self.rfile.read(int(self.headers['Content-Length'])) print("data-string:\n %s" % self.data_string) print("self.headers:\n %s" % self.headers) is_special = self._execute_content_generated_cases("POST") if is_special: cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) else: cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) _file_available = os.path.exists(cached_file_content) if not _file_available: if not HOST: self.send_response(404) self.end_headers() self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!') return "404 Not found, no remote HOST specified on the emulator !!!" print("Request for data currently not present in cache: %s" % (cached_file_folder,)) url = '%s%s' % (HOST, self.path) print("url: %s" % (url,)) response = requests.post(url, data=self.data_string, headers=self.headers, stream=True) if response.status_code == 200: self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response) else: print('Error when requesting file :') print('Requested url : %s' % (url,)) print('Status code : %s' % (response.status_code,)) print('Content : %s' % (response.content,)) self.send_response(response.status_code) self.end_headers() self.wfile.write('404 Not found, nothing found on the remote server !!!') return response.content else: print("Request for data present in cache: %s" % (cached_file_folder,)) self._send_content(cached_file_header, cached_file_content) def do_PUT(self): cached_file_folder = "" cached_file_content ="" cached_file_header="" print("\n\n\nGot a PUT for %s " % self.path) self.check_credentials() self.data_string = self.rfile.read(int(self.headers['Content-Length'])) print("data-string:\n %s" % self.data_string) print("self.headers:\n %s" % self.headers) is_special = self._execute_content_generated_cases("PUT") if is_special: cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) else: cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) _file_available = os.path.exists(cached_file_content) if not _file_available: if not HOST: self.send_response(404) self.end_headers() self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!') return "404 Not found, no remote HOST specified on the emulator !!!" print("Request for data currently not present in cache: %s" % (cached_file_folder,)) url = '%s%s' % (HOST, self.path) print("url: %s" % (url,)) response = requests.put(url, data=self.data_string, headers=self.headers, stream=True) if response.status_code == 200: self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response) else: print('Error when requesting file :') print('Requested url : %s' % (url,)) print('Status code : %s' % (response.status_code,)) print('Content : %s' % (response.content,)) self.send_response(response.status_code) self.end_headers() self.wfile.write('404 Not found, nothing found on the remote server !!!') return response.content else: print("Request for data present in cache: %s" % (cached_file_folder,)) self._send_content(cached_file_header, cached_file_content) def do_DELETE(self): cached_file_folder = "" cached_file_content ="" cached_file_header="" print("\n\n\nGot a DELETE for %s " % self.path) self.check_credentials() if self.headers.get('Content-Length') is not None: self.data_string = self.rfile.read(int(self.headers['Content-Length'])) else: self.data_string = "empty generated" print("self.headers:\n %s" % self.headers) is_special = self._execute_content_generated_cases("DELETE") if is_special: cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) else: cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT) cached_file_content = self._get_cached_content_file_name(cached_file_folder) cached_file_header = self._get_cached_header_file_name(cached_file_folder) _file_available = os.path.exists(cached_file_content) if not _file_available: if not HOST: self.send_response(404) self.end_headers() self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!') return "404 Not found, no remote HOST specified on the emulator !!!" print("Request for data currently not present in cache: %s" % (cached_file_folder,)) url = '%s%s' % (HOST, self.path) print("url: %s" % (url,)) response = requests.put(url, data=self.data_string, headers=self.headers, stream=True) if response.status_code == 200: self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response) else: print('Error when requesting file :') print('Requested url : %s' % (url,)) print('Status code : %s' % (response.status_code,)) print('Content : %s' % (response.content,)) self.send_response(response.status_code) self.end_headers() self.wfile.write('404 Not found, nothing found on the remote server !!!') return response.content else: print("Request for data present in cache: %s" % (cached_file_folder,)) self._send_content(cached_file_header, cached_file_content) # Main code that start the HTTP server httpd = SocketServer.ForkingTCPServer(('', PORT), Proxy) httpd.allow_reuse_address = True print("Listening on port "+ str(PORT) + "(Press Ctrl+C/Ctrl+Z to stop HTTPD Caching script)") print("Caching folder " + CACHE_ROOT + ", Tmp folder for generated files " + TMP_ROOT) signal.signal(signal.SIGINT, signal_handler) httpd.serve_forever()