public function fromHTTPRequest(Request $request) { $body = $request->getBody(); $meta = array(); // override method $rqMethodHeader = 'X-Psc-Cms-Request-Method'; if (in_array($method = $request->getHeaderField($rqMethodHeader), array(Service::PUT, Service::DELETE))) { $this->log('Request-Method durch HTTP-Header ' . $rqMethodHeader . ' überschrieben zu: ' . $method); unset($body->{$rqMethodHeader}); } else { $method = constant('Psc\\Net\\Service::' . $request->getMethod()); // Request::GET => ServiceRequest::GET } // revision $revisionHeader = 'X-Psc-Cms-Revision'; if (($revision = $request->getHeaderField($revisionHeader)) != '') { $meta['revision'] = $revision; unset($body->{$revisionHeader}); } // convert bodyAsJSON to native if (is_object($body) && count($body) === 1 && isset($body->bodyAsJSON)) { $body = $this->jsonConverter->parse($body->bodyAsJSON); } // convert json request to native if (is_string($body) && $request->isContentType('application/json')) { $body = $this->jsonConverter->parse($body); } return new ServiceRequest($method, $request->getParts(), $body, $request->getQuery(), $request->getFiles(), $meta); }
/** * Erstellt einen Request aus den Umgebungsvariablen * * wird eine Umgebungsvariable mit NULL übergeben (oder ausgelassen), wird die global Umgebungsvariable genommen * infer() ist also äquivalent mit: * infer($_GET, $_POST, $_COOKIE, $_SERVER) * * ist $_GET['mod_rewrite_request'] gesetzt wird dies als resource genommen * * @TODO Symfony hierfür nehmen (am besten ganz ersetzen) * * @deprecated das übergeben von Variablen ist strongly discouraged! */ public static function infer(SfRequest $sfRequest = NULL) { if (!isset($sfRequest)) { $sfRequest = SfRequest::createFromGlobals(); } // alternativ könnten wir den code aus sf kopieren oder sf mal patchen.. $method = NULL; switch ($sfRequest->getMethod()) { // wertet schon X-HTTP-METHOD-OVERRIDE aus case 'POST': $method = Request::POST; break; case 'PUT': $method = Request::PUT; break; case 'DELETE': $method = Request::DELETE; break; case 'PATCH': $method = Request::PATCH; break; case 'GET': default: $method = Request::GET; break; } $request = new Request($method, rawurldecode($sfRequest->getPathInfo())); $request->setQuery($sfRequest->query->all()); $request->setReferer($sfRequest->server->get('HTTP_REFERER')); $request->setUserAgent($sfRequest->server->get('HTTP_USER_AGENT')); $request->setPreferredLanguages($sfRequest->getLanguages()); $header = $request->getHeader(); foreach ($sfRequest->headers->all() as $key => $value) { // wir verschönern hier z.B. X_REQUESTED_WITH zu X-Requested-With $key = mb_strtolower($key); $key = \Psc\Preg::replace_callback($key, '/(^|-)([a-z]{1})/', function ($m) { return ($m[1] === '' ? NULL : '-') . mb_strtoupper($m[2]); }); // das ist voll doof, aber aus legacy gründen müssen wir das machen // schöner wäre auch die sf Requests / Header zu benutzen, dann wären wir durch if (count($value) === 1) { // unwrap arrays mit nur einem eintrag $value = current($value); } $header->setField($key, $value); } /* Body */ if (mb_strpos($request->getHeaderField('Content-Type'), 'application/x-www-form-urlencoded') === 0) { $request->setBody($sfRequest->request->all()); } elseif (mb_strpos($request->getHeaderField('Content-Type'), 'multipart/form-data') === 0) { $request->setBody($sfRequest->request->all()); $files = array(); foreach ($sfRequest->files->all() as $key => $sfFile) { if ($sfFile instanceof \Symfony\Component\HttpFoundation\File\UploadedFile) { if (!$sfFile->isValid()) { throw new \Psc\Exception('Cannot Upload File: ' . $sfFile->getClientOriginalName() . ' Error Code: ' . $sfFile->getErorr() . ' size: ' . $sfFile->getClientSize()); } else { $files[$key] = $f = new \Psc\System\UploadedFile($sfFile->getPathName()); $f->setOriginalName($sfFile->getClientOriginalName()); } $request->setFiles($files); } // FIXME else: kann auch ein array von files sein oder ein array von array ... // aber wie machen wir das in den files array rein? } } else { $request->setBody($sfRequest->getContent()); // really raw } return $request; }
/** * @return Response */ public function handle(Request $request) { $this->log($request->debug()); $this->request = $request; try { $serviceRequest = $this->createServiceRequest($this->request); $serviceResponse = $this->route($serviceRequest); $this->response = $this->convertResponse($serviceResponse); } catch (HTTPResponseException $e) { $this->response = Response::create($e->getCode(), $e->getResponseBody(), $e->getHeaders()); } catch (HTTPException $e) { // die darstellung sollte eigentlich woanders sein, nicht hier // eigentlich müssten wir hier auch request->content-type auswerten und response umwandeln $this->response = Response::create($e->getCode(), sprintf("%s\n\n%s\n%s", $e->getResponseBody(), $request->getResource(), $this->getDebugInfo()), $e->getHeaders()); } catch (NoServiceFoundException $e) { $this->logError($e, $this->debugLevel, 1); $e->setCode(404); $this->response = Response::create(404, sprintf("Es wurde kein Service für: %s gefunden\n\n%s", $request->getResource(), $this->getDebugInfo())); } catch (\Psc\CMS\Service\ControllerRouteException $e) { $this->logError($e, $this->debugLevel, 5); // nicht 1 da das mit dem Klassennamen ja schon "interna" sind $e->setCode(404); $this->response = Response::create(404, sprintf($e->getMessage() . "\n\n%s", $this->getDebugInfo())); } catch (\Exception $e) { $this->logError($e, $this->debugLevel, 1); $this->response = Response::create(500, sprintf("Es ist ein Fehler aufgetreten. URL: %s%s\n\n%s", $request->getResource(), $this->debugLevel >= 5 ? "\nFehler: " . $e->getMessage() : NULL, $this->getDebugInfo()), $this->getErrorMessageHeaders($e)); } if (isset($e)) { // oder halt code >= 400 if (!$this->isIgnoredError($e)) { $contextInfo = 'im RequestHandler. ' . "\n"; $contextInfo .= ' ' . $request->getMethod() . ' /' . implode('/', $request->getParts()) . "\n"; $contextInfo .= ' Accept: ' . $request->getHeaderField('Accept') . "\n"; $contextInfo .= ' Referer: ' . $request->getReferer() . "\n"; $contextInfo .= ' User-Agent: ' . $request->getUserAgent(); if (isset($this->contextInfo)) { $contextInfo .= "\n" . $this->contextInfo; } $contextInfo .= "\n\n" . $this->dumpRequest($request); \Psc\PSC::getEnvironment()->getErrorHandler()->handleCaughtException($e, $contextInfo); } } return $this->response; }
public function initRequest(Request $request = NULL) { $this->request = $request ?: Request::infer(); // infer() von $_GET usw ... $con = $this->request->getHeaderField('X-Psc-Cms-Connection'); if (!empty($con)) { $this->setConnectionName($con); } if ($this->request->hasHeaderField('X-Psc-Cms-Debug-Level')) { $this->setDebugLevel((int) $this->request->getHeaderField('X-Psc-Cms-Debug-Level')); } // so rum überschreiben wir den X-Psc-Cms-Connection Header (was ja safe ist) if ($this->isTesting()) { $this->setConnectionName('tests'); } }