Merge "Add a unit test"
[clamp.git] / src / test / resources / http-cache / third_party_proxy.py
1 #!/usr/bin/env python2
2 ###
3 # ============LICENSE_START=======================================================
4 # ONAP CLAMP
5 # ================================================================================
6 # Copyright (C) 2018 AT&T Intellectual Property. All rights
7 #                             reserved.
8 # ================================================================================
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 # http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 # ============LICENSE_END============================================
21 # ===================================================================
22 #
23 ###
24
25 import json
26 import requests
27 import os
28 import errno
29 import sys
30 import SimpleHTTPServer
31 import SocketServer
32 import argparse
33 import tempfile
34 import signal
35 import uuid
36 import shutil
37
38 parser = argparse.ArgumentParser(description="3rd party Cache & Replay")
39 parser.add_argument("--username", "-u", type=str, help="Set the username for contacting 3rd party - only used for GET")
40 parser.add_argument("--password", "-p", type=str, help="Set the password for contacting 3rd party - only used for GET")
41 parser.add_argument("--root",     "-r", default=tempfile.mkdtemp(), type=str, help="Root folder for the proxy cache")
42 parser.add_argument("--temp",     "-t", default=tempfile.mkdtemp(), type=str, help="Temp folder for the generated content")
43 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")
44 parser.add_argument("--port",     "-P", type=int, default="8081", help="Port on which the proxy should listen to")
45 parser.add_argument("--verbose",  "-v", type=bool, help="Print more information in case of error")
46 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")
47 options = parser.parse_args()
48
49
50 PORT = options.port
51 HOST = options.proxy
52 AUTH = (options.username, options.password)
53 HEADERS = {'X-ECOMP-InstanceID':'CLAMP'}
54 CACHE_ROOT = str(options.root)
55 TMP_ROOT = str(options.temp)
56 PROXY_ADDRESS=str(options.proxyaddress)
57
58 def signal_handler(signal_sent, frame):
59     global httpd
60     if signal_sent == signal.SIGINT:
61         print('Got Ctrl-C (SIGINT)')
62         httpd.socket.close()
63         httpd.shutdown()
64         httpd.server_close()
65
66 class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
67     def print_headers(self):
68         for header,value in self.headers.items():
69             print("header: %s : %s" % (header, value))
70
71     def check_credentials(self):
72         pass
73
74     def _send_content(self, header_file, content_file):
75         self.send_response(200)
76         with open(header_file, 'rb') as f:
77             headers = json.load(f)
78             for key,value in headers.items():
79                 if key in ('Transfer-Encoding',):
80                     continue
81                 self.send_header(key, value)
82             self.end_headers()
83         with open(content_file,'rb') as f:
84             fc = f.read()
85             self.wfile.write(fc)
86
87     def _write_cache(self,cached_file_folder, header_file, content_file, response):
88         os.makedirs(cached_file_folder, 0777)
89         with open(content_file, 'w') as f:
90             f.write(response.raw.read())
91         with open(header_file, 'w') as f:
92             json.dump(dict(response.raw.headers), f)
93     # Entry point of the code
94     def _get_cached_file_folder_name(self,folder):
95         cached_file_folder = '%s/%s' % (folder, self.path,)
96         print("Cached file name before escaping : %s" % cached_file_folder)
97         cached_file_folder = cached_file_folder.replace('<','&#60;').replace('>','&#62;').replace('?','&#63;').replace('*','&#42;').replace('\\','&#42;').replace(':','&#58;').replace('|','&#124;')
98         print("Cached file name after escaping (used for cache storage) : %s" % cached_file_folder)
99         return cached_file_folder
100     
101     def _get_cached_content_file_name(self,cached_file_folder):
102         return "%s/.file" % (cached_file_folder,)
103     
104     def _get_cached_header_file_name(self,cached_file_folder):
105         return "%s/.header" % (cached_file_folder,)
106     
107     def _execute_content_generated_cases(self,http_type):
108      print("Testing special cases, cache files will be sent to :" +TMP_ROOT)
109      cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
110      cached_file_content = self._get_cached_content_file_name(cached_file_folder)
111      cached_file_header = self._get_cached_header_file_name(cached_file_folder)
112      _file_available = os.path.exists(cached_file_content)
113     
114      if self.path.startswith("/dcae-service-types?asdcResourceId=") and http_type == "GET":
115         if not _file_available:
116             print "self.path start with /dcae-service-types?asdcResourceId=, generating response json..."
117             uuidGenerated = str(uuid.uuid4())
118             typeId = "typeId-" + uuidGenerated
119             typeName = "typeName-" + uuidGenerated
120             print "typeId generated: " + typeName + " and typeName: "+ typeId
121             jsonGenerated = "{\"totalCount\":1, \"items\":[{\"typeId\":\"" + typeId + "\", \"typeName\":\"" + typeName +"\"}]}"
122             print "jsonGenerated: " + jsonGenerated
123     
124             os.makedirs(cached_file_folder, 0777)
125             with open(cached_file_header, 'w') as f:
126                 f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
127             with open(cached_file_content, 'w') as f:
128                 f.write(jsonGenerated)
129         return True
130      elif self.path.startswith("/dcae-operationstatus/install") and http_type == "GET":
131         if not _file_available:
132             print "self.path start with /dcae-operationstatus/install, generating response json..."
133             jsonGenerated =  "{\"operationType\": \"install\", \"status\": \"succeeded\"}"
134             print "jsonGenerated: " + jsonGenerated
135     
136             try:
137                 os.makedirs(cached_file_folder, 0777)
138             except OSError as e:
139                 if e.errno != errno.EEXIST:
140                     raise
141                 print(cached_file_folder+" already exists")
142     
143             with open(cached_file_header, 'w') as f:
144                 f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
145             with open(cached_file_content, 'w') as f:
146                 f.write(jsonGenerated)
147         return True
148      elif self.path.startswith("/dcae-operationstatus/uninstall") and http_type == "GET":
149         if not _file_available:
150             print "self.path start with /dcae-operationstatus/uninstall, generating response json..."
151             jsonGenerated =  "{\"operationType\": \"uninstall\", \"status\": \"succeeded\"}"
152             print "jsonGenerated: " + jsonGenerated
153     
154             try:
155                 os.makedirs(cached_file_folder, 0777)
156             except OSError as e:
157                 if e.errno != errno.EEXIST:
158                     raise
159                 print(cached_file_folder+" already exists")
160     
161             with open(cached_file_header, 'w') as f:
162                 f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
163             with open(cached_file_content, 'w') as f:
164                 f.write(jsonGenerated)
165         return True
166      elif self.path.startswith("/sdc/v1/catalog/services/") and http_type == "POST":
167         if not _file_available:
168             print "self.path start with /sdc/v1/catalog/services/, generating response json..."
169             jsondata = json.loads(self.data_string)
170             jsonGenerated = "{\"artifactName\":\"" + jsondata['artifactName'] + "\",\"artifactType\":\"" + jsondata['artifactType'] + "\",\"artifactURL\":\"" + self.path + "\",\"artifactDescription\":\"" + jsondata['description'] + "\",\"artifactChecksum\":\"ZjJlMjVmMWE2M2M1OTM2MDZlODlmNTVmZmYzNjViYzM=\",\"artifactUUID\":\"" + str(uuid.uuid4()) + "\",\"artifactVersion\":\"1\"}"
171             print "jsonGenerated: " + jsonGenerated
172     
173             os.makedirs(cached_file_folder, 0777)
174             with open(cached_file_header, 'w') as f:
175                 f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
176             with open(cached_file_content, 'w') as f:
177                 f.write(jsonGenerated)
178         return True
179      elif self.path.startswith("/dcae-deployments/") and http_type == "PUT":
180             print "self.path start with /dcae-deployments/ DEPLOY, generating response json..."
181             #jsondata = json.loads(self.data_string)
182             jsonGenerated = "{\"operationType\":\"install\",\"status\":\"processing\",\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus/install\"}}"
183             print "jsonGenerated: " + jsonGenerated
184             if not os.path.exists(cached_file_folder):
185                 os.makedirs(cached_file_folder, 0777)
186             with open(cached_file_header, 'w+') as f:
187                 f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
188             with open(cached_file_content, 'w+') as f:
189                 f.write(jsonGenerated)
190                 return True
191      elif self.path.startswith("/dcae-deployments/") and http_type == "DELETE":
192             print "self.path start with /dcae-deployments/ UNDEPLOY, generating response json..."
193             #jsondata = json.loads(self.data_string)
194             jsonGenerated = "{\"operationType\":\"uninstall\",\"status\":\"processing\",\"links\":{\"status\":\"http:\/\/" + PROXY_ADDRESS + "\/dcae-operationstatus/uninstall\"}}"
195             print "jsonGenerated: " + jsonGenerated
196             if not os.path.exists(cached_file_folder):
197                 os.makedirs(cached_file_folder, 0777)
198             with open(cached_file_header, 'w+') as f:
199                 f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
200             with open(cached_file_content, 'w+') as f:
201                 f.write(jsonGenerated)
202             return True
203      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"):
204         print "self.path start with /pdp/api/, copying body to response ..."
205         if not os.path.exists(cached_file_folder):
206             os.makedirs(cached_file_folder, 0777)
207         with open(cached_file_header, 'w+') as f:
208             f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}")
209         with open(cached_file_content, 'w+') as f:
210             f.write(self.data_string)
211         return True
212      elif self.path.startswith("/policy/api/v1/policytypes/") and http_type == "POST":
213         print "self.path start with POST new policy API /pdp/api/, copying body to response ..."
214         if not os.path.exists(cached_file_folder):
215             os.makedirs(cached_file_folder, 0777)
216         with open(cached_file_header, 'w+') as f:
217             f.write("{\"Content-Length\": \"" + str(len(self.data_string)) + "\", \"Content-Type\": \""+str(self.headers['Content-Type'])+"\"}")
218         with open(cached_file_content, 'w+') as f:
219             f.write(self.data_string)
220         return True
221      elif self.path.startswith("/policy/api/v1/policytypes/") and http_type == "DELETE":
222         print "self.path start with DELETE new policy API /policy/api/v1/policytypes/ ..."
223         if not os.path.exists(cached_file_folder):
224             os.makedirs(cached_file_folder, 0777)
225     
226         with open(cached_file_header, 'w+') as f:
227                 f.write("{\"Content-Length\": \"" + str(len("")) + "\", \"Content-Type\": \""+str("")+"\"}")
228         with open(cached_file_content, 'w+') as f:
229                 f.write(self.data_string)
230         return True
231      elif self.path.startswith("/policy/pap/v1/pdps/policies") and http_type == "POST":
232         print "self.path start with POST new policy API /policy/pap/v1/pdps/ ..."
233         if not os.path.exists(cached_file_folder):
234             os.makedirs(cached_file_folder, 0777)
235         with open(cached_file_header, 'w+') as f:
236                 f.write("{\"Content-Length\": \"" + str(len("")) + "\", \"Content-Type\": \""+str("")+"\"}")
237         with open(cached_file_content, 'w+') as f:
238                 f.write(self.data_string)
239         return True
240      elif (self.path.startswith("/policy/api/v1/policytypes/") or self.path.startswith("/policy/pap/v1/policies/deployed/")) and http_type == "GET":
241         print "self.path start with /policy/api/v1/policytypes/, generating response json..."
242         jsonGenerated =  "{\"policyTypeId\": \"onap.policies.controlloop.operational\",\"policyTypeVersion\": \"1.0.0\",\"policyId\": \"OPERATIONAL_z711F_v1_0_ResourceInstanceName1_tca\"}"
243         print "jsonGenerated: " + jsonGenerated
244         if not os.path.exists(cached_file_folder):
245             os.makedirs(cached_file_folder, 0777)
246
247         with open(cached_file_header, 'w') as f:
248             f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}")
249         with open(cached_file_content, 'w') as f:
250             f.write(jsonGenerated)
251         return True
252      elif self.path.startswith("/dcae-service-types") and http_type == "GET":
253         if not _file_available:
254             self.path = "/dcae-service-types"
255             cached_file_folder = '%s/%s' % (TMP_ROOT, self.path)
256             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
257             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
258             print "self.path start with /dcae-service-types, generating response json..."
259             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\"}]}"
260             print "jsonGenerated: " + response
261
262             os.makedirs(cached_file_folder, 0777)
263             with open(cached_file_header, 'w') as f:
264                 f.write("{\"Content-Length\": \"" + str(len(response)) + "\", \"Content-Type\": \"application/json\"}")
265             with open(cached_file_content, 'w') as f:
266                 f.write(response)
267         return True
268      else:
269         return False
270
271     
272     def do_GET(self):
273         cached_file_folder = ""
274         cached_file_content =""
275         cached_file_header=""
276         print("\n\n\nGot a GET request for %s " % self.path)
277
278         self.print_headers()
279         self.check_credentials()
280         # Verify if it's a special case
281         is_special = self._execute_content_generated_cases("GET")
282         if is_special:
283             cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
284             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
285             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
286         else:
287             cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
288             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
289             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
290
291         _file_available = os.path.exists(cached_file_content)
292
293         if not _file_available:
294             print("Request for data currently not present in cache: %s" % (cached_file_folder,))
295
296             if not HOST:
297                 self.send_response(404)
298                 self.end_headers()
299                 self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!')
300                 return "404 Not found, no remote HOST specified on the emulator !!!"
301
302             url = '%s%s' % (HOST, self.path)
303             response = requests.get(url, auth=AUTH, headers=HEADERS, stream=True)
304
305             if response.status_code == 200:
306                 self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
307             else:
308                 print('Error when requesting file :')
309                 print('Requested url : %s' % (url,))
310                 print('Status code : %s' % (response.status_code,))
311                 print('Content : %s' % (response.content,))
312                 self.send_response(response.status_code)
313                 self.end_headers()
314                 self.wfile.write('404 Not found, nothing found on the remote server !!!')
315                 return response.content
316         else:
317             print("Request for data currently present in cache: %s" % (cached_file_folder,))
318
319         self._send_content(cached_file_header, cached_file_content)
320
321         if self.path.startswith("/dcae-service-types?asdcResourceId="):
322             print "DCAE case deleting folder created " + cached_file_folder
323             shutil.rmtree(cached_file_folder, ignore_errors=False, onerror=None)
324         elif self.path.startswith("/dcae-service-types"):
325             print "DCAE case deleting folder created " + cached_file_folder
326             shutil.rmtree(cached_file_folder, ignore_errors=False, onerror=None)
327         else:
328             print "NOT in DCAE case deleting folder created " + cached_file_folder
329
330     def do_POST(self):
331         cached_file_folder = ""
332         cached_file_content =""
333         cached_file_header=""
334         print("\n\n\nGot a POST for %s" % self.path)
335         self.check_credentials()
336         self.data_string = self.rfile.read(int(self.headers['Content-Length']))
337         print("data-string:\n %s" % self.data_string)
338         print("self.headers:\n %s" % self.headers)
339
340         is_special = self._execute_content_generated_cases("POST")
341         if is_special:
342             cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
343             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
344             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
345         else:
346             cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
347             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
348             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
349
350         _file_available = os.path.exists(cached_file_content)
351
352         if not _file_available:
353         
354             if not HOST:
355                 self.send_response(404)
356                 self.end_headers()
357                 self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!')
358                 return "404 Not found, no remote HOST specified on the emulator !!!"
359
360             print("Request for data currently not present in cache: %s" % (cached_file_folder,))
361
362             url = '%s%s' % (HOST, self.path)
363             print("url: %s" % (url,))
364             response = requests.post(url, data=self.data_string, headers=self.headers, stream=True)
365
366             if response.status_code == 200:
367                 self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
368             else:
369                 print('Error when requesting file :')
370                 print('Requested url : %s' % (url,))
371                 print('Status code : %s' % (response.status_code,))
372                 print('Content : %s' % (response.content,))
373                 self.send_response(response.status_code)
374                 self.end_headers()
375                 self.wfile.write('404 Not found, nothing found on the remote server !!!')
376                 return response.content
377         else:
378             print("Request for data present in cache: %s" % (cached_file_folder,))
379
380         self._send_content(cached_file_header, cached_file_content)
381
382     def do_PUT(self):
383         cached_file_folder = ""
384         cached_file_content =""
385         cached_file_header=""
386         print("\n\n\nGot a PUT for %s " % self.path)
387         self.check_credentials()
388         self.data_string = self.rfile.read(int(self.headers['Content-Length']))
389         print("data-string:\n %s" % self.data_string)
390         print("self.headers:\n %s" % self.headers)
391
392         is_special = self._execute_content_generated_cases("PUT")
393         if is_special:
394             cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
395             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
396             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
397         else:
398             cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
399             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
400             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
401
402         _file_available = os.path.exists(cached_file_content)
403
404         if not _file_available:
405             if not HOST:
406                 self.send_response(404)
407                 self.end_headers()
408                 self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!')
409                 return "404 Not found, no remote HOST specified on the emulator !!!"
410
411             print("Request for data currently not present in cache: %s" % (cached_file_folder,))
412
413             url = '%s%s' % (HOST, self.path)
414             print("url: %s" % (url,))
415             response = requests.put(url, data=self.data_string, headers=self.headers, stream=True)
416
417             if response.status_code == 200:
418                 self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
419             else:
420                 print('Error when requesting file :')
421                 print('Requested url : %s' % (url,))
422                 print('Status code : %s' % (response.status_code,))
423                 print('Content : %s' % (response.content,))
424                 self.send_response(response.status_code)
425                 self.end_headers()
426                 self.wfile.write('404 Not found, nothing found on the remote server !!!')
427                 return response.content
428         else:
429             print("Request for data present in cache: %s" % (cached_file_folder,))
430
431         self._send_content(cached_file_header, cached_file_content)
432
433
434     def do_DELETE(self):
435         cached_file_folder = ""
436         cached_file_content =""
437         cached_file_header=""
438         print("\n\n\nGot a DELETE for %s " % self.path)
439         self.check_credentials()
440         if self.headers.get('Content-Length') is not None:
441             self.data_string = self.rfile.read(int(self.headers['Content-Length']))
442         else:
443             self.data_string = "empty generated"
444         print("self.headers:\n %s" % self.headers)
445
446         is_special = self._execute_content_generated_cases("DELETE")
447         if is_special:
448             cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT)
449             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
450             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
451         else:
452             cached_file_folder = self._get_cached_file_folder_name(CACHE_ROOT)
453             cached_file_content = self._get_cached_content_file_name(cached_file_folder)
454             cached_file_header = self._get_cached_header_file_name(cached_file_folder)
455
456         _file_available = os.path.exists(cached_file_content)
457
458         if not _file_available:
459             if not HOST:
460                 self.send_response(404)
461                 self.end_headers()
462                 self.wfile.write('404 Not found, no remote HOST specified on the emulator !!!')
463                 return "404 Not found, no remote HOST specified on the emulator !!!"
464
465             print("Request for data currently not present in cache: %s" % (cached_file_folder,))
466
467             url = '%s%s' % (HOST, self.path)
468             print("url: %s" % (url,))
469             response = requests.put(url, data=self.data_string, headers=self.headers, stream=True)
470
471             if response.status_code == 200:
472                 self._write_cache(cached_file_folder, cached_file_header, cached_file_content, response)
473             else:
474                 print('Error when requesting file :')
475                 print('Requested url : %s' % (url,))
476                 print('Status code : %s' % (response.status_code,))
477                 print('Content : %s' % (response.content,))
478                 self.send_response(response.status_code)
479                 self.end_headers()
480                 self.wfile.write('404 Not found, nothing found on the remote server !!!')
481                 return response.content
482         else:
483             print("Request for data present in cache: %s" % (cached_file_folder,))
484
485         self._send_content(cached_file_header, cached_file_content)
486
487
488
489 # Main code that start the HTTP server
490 httpd = SocketServer.ForkingTCPServer(('', PORT), Proxy)
491 httpd.allow_reuse_address = True
492 print "Listening on port "+ str(PORT) + "(Press Ctrl+C/Ctrl+Z to stop HTTPD Caching script)"
493 print "Caching folder " + CACHE_ROOT + ", Tmp folder for generated files " + TMP_ROOT 
494 signal.signal(signal.SIGINT, signal_handler)
495 httpd.serve_forever()