1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* AppserverIo\SingleApp\ServletEngine\SimpleServletEngine |
5
|
|
|
* |
6
|
|
|
* NOTICE OF LICENSE |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
9
|
|
|
* that is available through the world-wide-web at this URL: |
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
11
|
|
|
* |
12
|
|
|
* PHP version 5 |
13
|
|
|
* |
14
|
|
|
* @author Tim Wagner <[email protected]> |
15
|
|
|
* @copyright 2015 TechDivision GmbH <[email protected]> |
16
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
17
|
|
|
* @link https://github.com/appserver-io/single-app |
18
|
|
|
* @link http://www.appserver.io |
19
|
|
|
*/ |
20
|
|
|
|
21
|
|
|
namespace AppserverIo\SingleApp\ServletEngine; |
22
|
|
|
|
23
|
|
|
use AppserverIo\Http\HttpResponseStates; |
24
|
|
|
use AppserverIo\Server\Dictionaries\ServerVars; |
25
|
|
|
use AppserverIo\Server\Dictionaries\ModuleHooks; |
26
|
|
|
use AppserverIo\Server\Exceptions\ModuleException; |
27
|
|
|
use AppserverIo\Psr\HttpMessage\Protocol; |
28
|
|
|
use AppserverIo\Psr\HttpMessage\RequestInterface; |
29
|
|
|
use AppserverIo\Psr\HttpMessage\ResponseInterface; |
30
|
|
|
use AppserverIo\Server\Interfaces\RequestContextInterface; |
31
|
|
|
use AppserverIo\Appserver\ServletEngine\Http\Request; |
32
|
|
|
use AppserverIo\Appserver\ServletEngine\Http\Response; |
33
|
|
|
use AppserverIo\Appserver\ServletEngine\ServletEngine; |
34
|
|
|
use AppserverIo\Appserver\ServletEngine\RequestHandler; |
35
|
|
|
use AppserverIo\Appserver\ServletEngine\BadRequestException; |
36
|
|
|
use AppserverIo\Appserver\ServletEngine\SessionManagerInterface; |
37
|
|
|
use AppserverIo\Appserver\ServletEngine\Security\AuthenticationManagerInterface; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* A servlet engine implementation to handle a single app container. |
41
|
|
|
* |
42
|
|
|
* @author Tim Wagner <[email protected]> |
43
|
|
|
* @copyright 2015 TechDivision GmbH <[email protected]> |
44
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
45
|
|
|
* @link https://github.com/appserver-io/single-app |
46
|
|
|
* @link http://www.appserver.io |
47
|
|
|
*/ |
48
|
|
|
class FlatServletEngine extends ServletEngine |
49
|
|
|
{ |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Simply returns the first application, assuming we only have one. If no application |
53
|
|
|
* has been deployed, an exception will be thrown. |
54
|
|
|
* |
55
|
|
|
* @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext Context of the current request |
56
|
|
|
* |
57
|
|
|
* @return null|\AppserverIo\Psr\Application\ApplicationInterface |
58
|
|
|
* @throws \AppserverIo\Appserver\ServletEngine\BadRequestException Is thrown if no application is available |
59
|
|
|
*/ |
60
|
|
View Code Duplication |
protected function findRequestedApplication(RequestContextInterface $requestContext) |
|
|
|
|
61
|
|
|
{ |
62
|
|
|
|
63
|
|
|
// return the first application (we only have one) |
64
|
|
|
foreach ($this->applications as $application) { |
65
|
|
|
return $application; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
// if we did not find anything we should throw a bad request exception |
69
|
|
|
throw new BadRequestException( |
70
|
|
|
sprintf( |
71
|
|
|
'Can\'t find application for URL %s%s', |
72
|
|
|
$requestContext->getServerVar(ServerVars::HTTP_HOST), |
73
|
|
|
$requestContext->getServerVar(ServerVars::X_REQUEST_URI) |
74
|
|
|
), |
75
|
|
|
404 |
76
|
|
|
); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Process servlet request. |
81
|
|
|
* |
82
|
|
|
* @param \AppserverIo\Psr\HttpMessage\RequestInterface $request A request object |
83
|
|
|
* @param \AppserverIo\Psr\HttpMessage\ResponseInterface $response A response object |
84
|
|
|
* @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext A requests context instance |
85
|
|
|
* @param integer $hook The current hook to process logic for |
86
|
|
|
* |
87
|
|
|
* @return boolean |
88
|
|
|
* |
89
|
|
|
* @throws \AppserverIo\Server\Exceptions\ModuleException |
90
|
|
|
*/ |
91
|
|
|
public function process( |
92
|
|
|
RequestInterface $request, |
93
|
|
|
ResponseInterface $response, |
94
|
|
|
RequestContextInterface $requestContext, |
95
|
|
|
$hook |
96
|
|
|
) { |
97
|
|
|
|
98
|
|
|
// if false hook is coming do nothing |
99
|
|
|
if (ModuleHooks::REQUEST_POST !== $hook) { |
100
|
|
|
return; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
// check if we are the handler that has to process this request |
104
|
|
|
if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) !== $this->getModuleName()) { |
105
|
|
|
return; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
// load the application associated with this request |
109
|
|
|
$application = $this->findRequestedApplication($requestContext); |
110
|
|
|
$application->registerClassLoaders(); |
111
|
|
|
|
112
|
|
|
// check if the application has already been connected |
113
|
|
|
if ($application->isConnected() === false) { |
|
|
|
|
114
|
|
|
throw new \Exception(sprintf('Application %s has not connected yet', $application->getName()), 503); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
// create a copy of the valve instances |
118
|
|
|
$valves = $this->valves; |
119
|
|
|
$handlers = $this->handlers; |
120
|
|
|
|
121
|
|
|
// create a new request instance from the HTTP request |
122
|
|
|
$servletRequest = new Request(); |
123
|
|
|
$servletRequest->injectHandlers($handlers); |
124
|
|
|
$servletRequest->injectHttpRequest($request); |
125
|
|
|
$servletRequest->injectServerVars($requestContext->getServerVars()); |
126
|
|
|
$servletRequest->init(); |
|
|
|
|
127
|
|
|
|
128
|
|
|
// initialize servlet response |
129
|
|
|
$servletResponse = new Response(); |
130
|
|
|
$servletResponse->init(); |
131
|
|
|
|
132
|
|
|
// load the session and the authentication manager |
133
|
|
|
$sessionManager = $application->search(SessionManagerInterface::IDENTIFIER); |
134
|
|
|
$authenticationManager = $application->search(AuthenticationManagerInterface::IDENTIFIER); |
135
|
|
|
|
136
|
|
|
// inject the sapplication and servlet response |
137
|
|
|
$servletRequest->injectContext($application); |
|
|
|
|
138
|
|
|
$servletRequest->injectResponse($servletResponse); |
139
|
|
|
$servletRequest->injectSessionManager($sessionManager); |
|
|
|
|
140
|
|
|
$servletRequest->injectAuthenticationManager($authenticationManager); |
|
|
|
|
141
|
|
|
|
142
|
|
|
// prepare the request instance |
143
|
|
|
$servletRequest->prepare(); |
144
|
|
|
|
145
|
|
|
// initialize static request and application context |
146
|
|
|
RequestHandler::$requestContext = $servletRequest; |
147
|
|
|
RequestHandler::$applicationContext = $application; |
148
|
|
|
|
149
|
|
|
// process the valves |
150
|
|
|
foreach ($valves as $valve) { |
151
|
|
|
$valve->invoke($servletRequest, $servletResponse); |
152
|
|
|
if ($servletRequest->isDispatched() === true) { |
153
|
|
|
break; |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
// copy response values to the HTTP response |
158
|
|
|
$response->setState($servletResponse->getState()); |
|
|
|
|
159
|
|
|
$response->setVersion($servletResponse->getVersion()); |
|
|
|
|
160
|
|
|
$response->setStatusCode($servletResponse->getStatusCode()); |
161
|
|
|
$response->setStatusReasonPhrase($servletResponse->getStatusReasonPhrase()); |
|
|
|
|
162
|
|
|
|
163
|
|
|
// copy the body content to the HTTP response |
164
|
|
|
$response->appendBodyStream($servletResponse->getBodyStream()); |
165
|
|
|
|
166
|
|
|
// copy headers to the HTTP response |
167
|
|
|
foreach ($servletResponse->getHeaders() as $headerName => $headerValue) { |
168
|
|
|
$response->addHeader($headerName, $headerValue); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
// copy cookies to the HTTP response |
172
|
|
|
$response->setCookies($servletResponse->getCookies()); |
|
|
|
|
173
|
|
|
|
174
|
|
|
// append the servlet engine's signature |
175
|
|
|
$response->addHeader(Protocol::HEADER_X_POWERED_BY, get_class($this), true); |
|
|
|
|
176
|
|
|
|
177
|
|
|
// set response state to be dispatched after this without calling other modules process |
178
|
|
|
$response->setState(HttpResponseStates::DISPATCH); |
|
|
|
|
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.