public function testFromFileName() { $this->assertEquals(CopixMIMETypes::getFromFileName('c:\\mon\\fichier/avec/un/truc long/et des accents é/myFile.txt'), 'text/plain'); $this->assertEquals(CopixMIMETypes::getFromFileName('c:\\mon\\fichier.files/avec/un/truc long/et des accents é/myFile.txt'), 'text/plain'); $this->assertEquals(CopixMIMETypes::getFromFileName('c:\\mon\\fichier.files/avec/un/truc long/et des accents é/myFile'), 'application/octet-stream'); $this->assertEquals(CopixMIMETypes::getFromFileName('/avec/un/truc long/et des accents é/myFile.xls'), 'application/vnd.ms-excel'); }
/** * Recupère la ressource * * @throws CopixResourceForbiddenException si l'accès à la ressource est interdit, * CopixResourceNotFoundException si la ressource n'a pas été trouvée. */ public function fetch() { // Vérifie qu'on ait pas de "backward" $unescapedPath = utf8_decode($this->_path); // Pas de blague avec l'UTF8 if (preg_match('@\\.\\.[/\\\\]@', $unescapedPath)) { throw new CopixResourceForbiddenException($this->_path); } // Vérifie l'existence du theme if (!$this->_theme || !is_dir('themes/' . $this->_theme)) { throw new CopixResourceNotFoundException($this->_theme); } $arModules = $this->_getArModules(); // Si on a bien un module if ($this->_module) { // Vérifie l'existence du module if (isset($arModules[$this->_module])) { $this->_modulePath = $arModules[$this->_module] . $this->_module . '/'; } else { throw new CopixResourceNotFoundException($this->_module); } // Vérifie l'existence du chemin 'www' du module if (!is_dir($this->_modulePath . "www")) { throw new CopixResourceNotFoundException($this->_module); } } // Récupère la config $config = $this->_getCopixConfig(); // Recherche le fichier if (!($filePath = CopixResource::findResourcePath($this->_path, $this->_module, $this->_modulePath, $this->_theme, $config->i18n_path_enabled, $this->_lang, $this->_country))) { throw new CopixResourceNotFoundException($this->_path); } // Récupère le type MIME $mimeType = CopixMIMETypes::getFromFileName($filePath); // La substitution ne touche que les fichiers des modules if ($this->_modulePath && substr($filePath, 0, strlen($this->_modulePath)) == $this->_modulePath) { $filePath = $this->_processModuleFile($filePath, $mimeType); } // Mode DEBUG ? if (isset($_REQUEST['DEBUG'])) { _dump(array('this' => $this, 'filePath' => $filePath, 'mimeType' => $mimeType, 'included_files' => get_included_files())); exit; } // Envoie le fichier $this->_sendFile($filePath, $mimeType); }
/** * Lancement d'une requête * * @param CopixHTTPClientRequest $pRequest * @return unknown */ private function _launchRequest(CopixHTTPClientRequest $pRequest) { if (CopixConfig::get('default|proxyEnabled')) { //proxy_host, proxy_port, proxy_login et proxy_password curl_setopt($this->_curl, CURLOPT_HTTPPROXYTUNNEL, true); if (CopixConfig::get('default|proxyHost') != null) { curl_setopt($this->_curl, CURLOPT_PROXY, str_replace('http://', '', CopixConfig::get('default|proxyHost'))); } if (CopixConfig::get('default|proxyPort') != null) { curl_setopt($this->_curl, CURLOPT_PROXYPORT, intval(CopixConfig::get('default|proxyPort'))); } if (CopixConfig::get('default|proxyUser') != null) { $proxyUserPass = CopixConfig::get('default|proxyUser'); if (CopixConfig::get('default|proxyPass') != null) { $proxyUserPass .= ':' . CopixConfig::get('default|proxyPass'); } curl_setopt($this->_curl, CURLOPT_PROXYUSERPWD, $proxyUserPass); } } curl_setopt($this->_curl, CURLOPT_TIMEOUT, $pRequest->getTimeout()); // Choix de l'interface à utiliser $interfaceUsed = $pRequest->getInterface(); // Si pas d'interface on récupère celle en configuration if ($interfaceUsed !== '') { $interfaceUsed = CopixConfig::get('default|webservicesInterface'); } // Mise en place de l'interface if (isset($interfaceUsed)) { curl_setopt($this->_curl, CURLOPT_INTERFACE, $interfaceUsed); } if ($pRequest->getIgnoreCertificate()) { curl_setopt($this->_curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->_curl, CURLOPT_SSL_VERIFYHOST, false); } curl_setopt($this->_curl, CURLOPT_URL, $pRequest->getUrl()); curl_setopt($this->_curl, CURLOPT_VERBOSE, 1); if ($pRequest->getHeader()) { curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $pRequest->getHeader()); } if ($pRequest->getCookie()) { curl_setopt($this->_curl, CURLOPT_COOKIE, $pRequest->getCookie()); } if (count($pRequest->getPost())) { if ($pRequest->getFile()) { $boundary = uniqid('------------------'); $MPboundary = '--' . $boundary; $endMPboundary = $MPboundary . '--'; $postBody = 'Content-type: multipart/form-data, boundary=' . $boundary . "\r\n\r\n"; foreach ($pRequest->getPost() as $name => $content) { $postBody .= $MPboundary . "\r\n"; $postBody .= 'content-disposition: form-data; name="' . $name . '"' . "\r\n\r\n"; $postBody .= $content . "\r\n"; } $file = $pRequest->getFile(); $fileContent = file_get_contents($file); $postBody .= $MPboundary . "\r\n"; $postBody .= 'Content-Disposition: form-data; name="file"; filename="' . basename($file) . '"' . "\r\n"; $postBody .= 'Content-Type: ' . CopixMIMETypes::getFromFileName($file) . "\r\n"; $postBody .= 'Content-Transfer-Encoding: binary' . "\r\n\r\n"; $postBody .= $fileContent; $postBody .= "\r\n" . $endMPboundary; curl_setopt($this->_curl, CURLOPT_POST, true); curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $postBody); curl_setopt($this->_curl, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data; boundary={$boundary}")); curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true); } else { curl_setopt($this->_curl, CURLOPT_POST, true); curl_setopt($this->_curl, CURLOPT_POSTFIELDS, CopixUrl::valueToUrl(null, $pRequest->getPost())); } } if ($pRequest->getFollowRedirect()) { curl_setopt($this->_curl, CURLOPT_FOLLOWLOCATION, 1); } else { curl_setopt($this->_curl, CURLOPT_FOLLOWLOCATION, 0); } return new CopixHTTPRequestResult($pRequest, $this->_curl); }
/** * Réalise les derniers traitements (généralement d'affichage ou de redirection). * * En fonction du code retour de l'action CopixActionReturn::CONST, Copix réalise * un certain nombre de traitements pour terminer la requête en cours. * * @param CopixActionReturn $pToProcess Ce qui a été retourné par CopixActionGroup::process () * @see CopixActionGroup */ protected function _processResult($toProcess) { $config = CopixConfig::instance(); //appel les plugins de post-processing. foreach (CopixPluginRegistry::getRegistered() as $name => $plugin) { $plugin->afterProcess($toProcess); } //Analyse du résultat du process switch ($toProcess->code) { case CopixActionReturn::ERROR: //erreur header("Content-Type: text/html"); $tpl = new CopixTpl(); if (($assignedTitlePage = $tpl->getAssigned('TITLE_PAGE')) !== null) { $tpl->assign('TITLE_PAGE', '[' . _i18n('copix:common.messages.error') . ']' . $assignedTitlePage); } else { $tpl->assign('TITLE_PAGE', '[' . _i18n('copix:common.messages.error') . ']'); } $this->_processStandard($tpl); $tpl->assign('HTML_HEAD', '<$HTML_HEAD />'); $tpl->assign('MAIN', $toProcess->data); $content = $tpl->fetch('|error.tpl'); CopixContext::clear(); $this->_beforeDisplay($content); echo $content; break; case CopixActionReturn::DISPLAY: $charset = CopixI18N::getCharset(); header("Content-Type: text/html;charset=" . $charset); $this->_processStandard($toProcess->data); //appel de la méthode de préparation de la page standard. $toProcess->data->assign('HTML_HEAD', '<$HTML_HEAD />'); //Par ex, bandeaux de pub, menus dynamiques, ... (propres aux projets.) CopixContext::clear(); $content = $toProcess->data->fetch($config->mainTemplate); $this->_beforeDisplay($content); echo $content; break; case CopixActionReturn::DISPLAY_IN: $charset = CopixI18N::getCharset(); header("Content-Type: text/html;charset=" . $charset); $this->_processStandard($toProcess->data); //appel de la méthode de préparation de la page standard. $toProcess->data->assign('HTML_HEAD', '<$HTML_HEAD />'); //Par ex, bandeaux de pub, menus dynamiques, ... (propres aux projets.) $content = $toProcess->data->fetch($toProcess->more); $this->_beforeDisplay($content); echo $content; break; case CopixActionReturn::FILE: case CopixActionReturn::CONTENT: $contentDisposition = 'inline'; $contentTransfertEnconding = 'binary'; $contentType = null; $fileNameOnly = null; if ($toProcess->code == CopixActionReturn::FILE) { $fileName = $toProcess->data; $fileNameOnly = explode('/', str_replace('\\', '/', $fileName)); $fileNameOnly = $fileNameOnly[count($fileNameOnly) - 1]; } if (is_array($toProcess->more)) { if (isset($toProcess->more['content-disposition'])) { $contentDisposition = $toProcess->more['content-disposition']; } if (isset($toProcess->more['filename'])) { $fileNameOnly = $toProcess->more['filename']; } if (isset($toProcess->more['content-type'])) { $contentType = $toProcess->more['content-type']; } if (isset($toProcess->more['content-transfer-encoding'])) { $contentTransfertEnconding = $toProcess->more['content-transfer-encoding']; } } elseif (strlen(trim($toProcess->more))) { $contentType = $toProcess->more; } if ($contentType === null) { $contentType = CopixMIMETypes::getFromFileName($fileNameOnly); } header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: protected", false); header("Content-Type: " . $contentType); header("Content-Disposition: " . $contentDisposition . "; filename=\"" . $fileNameOnly . "\";"); header("Content-Transfer-Encoding: " . $contentTransfertEnconding); header("Content-Length: " . ($toProcess->code == CopixActionReturn::FILE ? filesize($fileName) : strlen($toProcess->data))); if ($toProcess->code == CopixActionReturn::FILE) { readfile($fileName); } else { echo $toProcess->data; } flush(); break; case CopixActionReturn::PPO: $contentType = 'text/html'; $cacheControl = false; $mainTemplate = $config->mainTemplate; $charset = CopixI18N::getCharset(); if (is_array($toProcess->more)) { $template = $toProcess->more['template']; if (isset($toProcess->more['content-type'])) { $contentType = $toProcess->more['content-type']; } if (array_key_exists('mainTemplate', $toProcess->more)) { $mainTemplate = $toProcess->more['mainTemplate']; } if (isset($toProcess->more['charset'])) { $charset = $toProcess->more['charset']; } if (isset($toProcess->more['cache-control'])) { $cacheControl = $toProcess->more['cache-control']; } } else { $template = $toProcess->more; } $tplContent = new CopixTpl(); $tplContent->assign('ppo', $toProcess->data); header("Content-Type: " . $contentType . ";charset=" . $charset); if ($cacheControl !== false) { header('Cache-Control: ' . $cacheControl); } if ($mainTemplate !== null) { $tplMain = new CopixTpl(); $tplMain->assign('TITLE_PAGE', isset($toProcess->data->TITLE_PAGE) ? $toProcess->data->TITLE_PAGE : null); $tplMain->assign('TITLE_BAR', isset($toProcess->data->TITLE_BAR) ? $toProcess->data->TITLE_BAR : null); $tplMain->assign('POPUP', isset($toProcess->data->POPUP) ? $toProcess->data->POPUP : null); $tplMain->assign('MENU', isset($toProcess->data->MENU) ? $toProcess->data->MENU : null); $tplMain->assign('CAN_CLOSE', isset($toProcess->data->CAN_CLOSE) ? $toProcess->data->CAN_CLOSE : null); $tplMain->assign('BODY_ON_LOAD', isset($toProcess->data->BODY_ON_LOAD) ? $toProcess->data->BODY_ON_LOAD : null); $tplMain->assign('BODY_ON_UNLOAD', isset($toProcess->data->BODY_ON_UNLOAD) ? $toProcess->data->BODY_ON_UNLOAD : null); $tplMain->assign('MAIN', $tplContent->fetch($template)); $tplContent = null; //on libère la mémoire $tplMain->assign('ppo', $toProcess->data); $this->_processStandard($tplMain); $tplMain->assign('HTML_HEAD', '<$HTML_HEAD />'); $content = $tplMain->fetch($mainTemplate); } else { $tplContent->assign('TITLE_PAGE', isset($toProcess->data->TITLE_PAGE) ? $toProcess->data->TITLE_PAGE : null); $tplContent->assign('TITLE_BAR', isset($toProcess->data->TITLE_BAR) ? $toProcess->data->TITLE_BAR : null); $tplContent->assign('BODY_ON_LOAD', isset($toProcess->data->BODY_ON_LOAD) ? $toProcess->data->BODY_ON_LOAD : null); $tplContent->assign('BODY_ON_UNLOAD', isset($toProcess->data->BODY_ON_UNLOAD) ? $toProcess->data->BODY_ON_UNLOAD : null); $this->_processStandard($tplContent); $tplContent->assign('HTML_HEAD', '<$HTML_HEAD />'); $content = $tplContent->fetch($template); } CopixContext::clear(); $this->_beforeDisplay($content); echo $content; break; case CopixActionReturn::REDIRECT: //redirection standard, message http. header('location: ' . $toProcess->data); break; case CopixActionReturn::HTTPCODE: foreach ($toProcess->data as $code) { header($code); } echo $toProcess->more; break; case CopixActionReturn::NONE: break; } //Appel des méthodes afterDisplay des plugins foreach (CopixPluginRegistry::getRegistered() as $name => $plugin) { $plugin->afterDisplay(); } session_write_close(); }