1<?php
2require_once 'portabilityLayer.php';
3
4// This script acts as a stateful proxy for retrieving files. When the state is set to
5// offline, it simulates a network error with a nonsense response.
6
7if (!sys_get_temp_dir()) {
8    echo "FAIL: No temp dir was returned.\n";
9    exit();
10}
11
12function setState($newState, $file)
13{
14    file_put_contents($file, $newState);
15}
16
17function getState($file)
18{
19    if (!file_exists($file)) {
20        return "Uninitialized";
21    }
22    return file_get_contents($file);
23}
24
25function contentType($path)
26{
27    if (preg_match("/\.html$/", $path))
28        return "text/html";
29    if (preg_match("/\.manifest$/", $path))
30        return "text/cache-manifest";
31    if (preg_match("/\.js$/", $path))
32        return "text/javascript";
33    if (preg_match("/\.xml$/", $path))
34        return "application/xml";
35    if (preg_match("/\.xhtml$/", $path))
36        return "application/xhtml+xml";
37    if (preg_match("/\.svg$/", $path))
38        return "application/svg+xml";
39    if (preg_match("/\.xsl$/", $path))
40        return "application/xslt+xml";
41    if (preg_match("/\.gif$/", $path))
42        return "image/gif";
43    if (preg_match("/\.jpg$/", $path))
44        return "image/jpeg";
45    if (preg_match("/\.png$/", $path))
46        return "image/png";
47    return "text/plain";
48}
49
50function generateNoCacheHTTPHeader()
51{
52    header("Expires: Thu, 01 Dec 2003 16:00:00 GMT");
53    header("Cache-Control: no-cache, no-store, must-revalidate");
54    header("Pragma: no-cache");
55}
56
57function generateResponse($path)
58{
59    global $stateFile;
60    $state = getState($stateFile);
61    if ($state == "Offline") {
62        # Simulate a network error by replying with a nonsense response.
63        header('HTTP/1.1 307 Temporary Redirect');
64        header('Location: ' . $_SERVER['REQUEST_URI']); # Redirect to self.
65        header('Content-Length: 1');
66        header('Content-Length: 5', false); # Multiple content-length headers, some network stacks can detect this condition faster.
67        echo "Intentionally incorrect response.";
68    } else {
69        // A little securuty checking can't hurt.
70        if (strstr($path, ".."))
71            exit;
72
73        if ($path[0] == '/')
74            $path = '..' . $path;
75
76        generateNoCacheHTTPHeader();
77
78        if (file_exists($path)) {
79            header("Last-Modified: " . gmdate("D, d M Y H:i:s T", filemtime($path)));
80            header("Content-Type: " . contentType($path));
81
82            print file_get_contents($path);
83        } else {
84            header('HTTP/1.1 404 Not Found');
85        }
86    }
87}
88
89function handleIncreaseResourceCountCommand($path)
90{
91    $resourceCountFile = sys_get_temp_dir() . "/resource-count";
92    $resourceCount = getState($resourceCountFile);
93    $pieces = explode(" ", $resourceCount);
94    $count = 0;
95    if (count($pieces) == 2 && $pieces[0] == $path) {
96        $count = 1 + $pieces[1];
97    } else {
98        $count = 1;
99    }
100    file_put_contents($resourceCountFile, $path . " " . $count);
101    generateResponse($path);
102}
103
104function handleResetResourceCountCommand()
105{
106    $resourceCountFile = sys_get_temp_dir() . "/resource-count";
107    file_put_contents($resourceCountFile, 0);
108    generateNoCacheHTTPHeader();
109    header('HTTP/1.1 200 OK');
110}
111
112function handleGetResourceCountCommand($path)
113{
114    $resourceCountFile = sys_get_temp_dir() . "/resource-count";
115    $resourceCount = getState($resourceCountFile);
116    $pieces = explode(" ", $resourceCount);
117    generateNoCacheHTTPHeader();
118    header('HTTP/1.1 200 OK');
119    if (count($pieces) == 2 && $pieces[0] == $path) {
120        echo $pieces[1];
121    } else {
122        echo 0;
123    }
124}
125
126function handleStartResourceRequestsLog()
127{
128    $resourceLogFile = sys_get_temp_dir() . "/resource-log";
129    file_put_contents($resourceLogFile,  "");
130}
131
132function handleClearResourceRequestsLog()
133{
134    $resourceLogFile = sys_get_temp_dir() . "/resource-log";
135    file_put_contents($resourceLogFile, "");
136}
137
138function handleGetResourceRequestsLog()
139{
140    $resourceLogFile = sys_get_temp_dir() . "/resource-log";
141
142    generateNoCacheHTTPHeader();
143    header("Content-Type: text/plain");
144
145    print file_get_contents($resourceLogFile);
146}
147
148function handleLogResourceRequest($path)
149{
150    $resourceLogFile = sys_get_temp_dir() . "/resource-log";
151
152    $newData = "\n".$path;
153    // Documentation says that appends are atomic.
154    file_put_contents($resourceLogFile, $newData, FILE_APPEND);
155    generateResponse($path);
156}
157
158$stateFile = sys_get_temp_dir() . "/network-simulator-state";
159$command = $_GET['command'];
160if ($command) {
161    if ($command == "connect")
162        setState("Online", $stateFile);
163    else if ($command == "disconnect")
164        setState("Offline", $stateFile);
165    else if ($command == "increase-resource-count")
166        handleIncreaseResourceCountCommand($_GET['path']);
167    else if ($command == "reset-resource-count")
168        handleResetResourceCountCommand();
169    else if ($command == "get-resource-count")
170        handleGetResourceCountCommand($_GET['path']);
171    else if ($command == "start-resource-request-log")
172        handleStartResourceRequestsLog();
173    else if ($command == "clear-resource-request-log")
174        handleClearResourceRequestsLog();
175    else if ($command == "get-resource-request-log")
176        handleGetResourceRequestsLog();
177    else if ($command == "log-resource-request")
178        handleLogResourceRequest($_GET['path']);
179    else
180        echo "Unknown command: " . $command . "\n";
181    exit();
182}
183
184$requestedPath = $_GET['path'];
185generateResponse($requestedPath);
186?>
187