/** * @see FileBackendStore::doStoreInternal() * @return Status */ protected function doStoreInternal(array $params) { $status = Status::newGood(); list($dstCont, $dstRel) = $this->resolveStoragePathReal($params['dst']); if ($dstRel === null) { $status->fatal('backend-fail-invalidpath', $params['dst']); return $status; } // (a) Check the destination container and object try { $dContObj = $this->getContainer($dstCont); } catch (NoSuchContainerException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); return $status; } catch (CloudFilesException $e) { // some other exception? $this->handleException($e, $status, __METHOD__, $params); return $status; } // (b) Get a SHA-1 hash of the object wfSuppressWarnings(); $sha1Hash = sha1_file($params['src']); wfRestoreWarnings(); if ($sha1Hash === false) { // source doesn't exist? $status->fatal('backend-fail-copy', $params['src'], $params['dst']); return $status; } $sha1Hash = wfBaseConvert($sha1Hash, 16, 36, 31); // (c) Actually store the object try { // Create a fresh CF_Object with no fields preloaded. // We don't want to preserve headers, metadata, and such. $obj = new CF_Object($dContObj, $dstRel, false, false); // skip HEAD $obj->setMetadataValues(array('Sha1base36' => $sha1Hash)); // The MD5 here will be checked within Swift against its own MD5. $obj->set_etag(md5_file($params['src'])); // Use the same content type as StreamFile for security $obj->content_type = StreamFile::contentTypeFromPath($params['dst']); if (!strlen($obj->content_type)) { // special case $obj->content_type = 'unknown/unknown'; } // Set any other custom headers if requested if (isset($params['headers'])) { $obj->headers += $this->sanitizeHdrs($params['headers']); } if (!empty($params['async'])) { // deferred wfSuppressWarnings(); $fp = fopen($params['src'], 'rb'); wfRestoreWarnings(); if (!$fp) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); } else { $op = $obj->write_async($fp, filesize($params['src']), true); $status->value = new SwiftFileOpHandle($this, $params, 'Store', $op); $status->value->resourcesToClose[] = $fp; $status->value->affectedObjects[] = $obj; } } else { // actually write the object in Swift $obj->load_from_filename($params['src'], true); // calls $obj->write() $this->purgeCDNCache(array($obj)); } } catch (CDNNotEnabledException $e) { // CDN not enabled; nothing to see here } catch (BadContentTypeException $e) { $status->fatal('backend-fail-contenttype', $params['dst']); } catch (IOException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); } catch (CloudFilesException $e) { // some other exception? $this->handleException($e, $status, __METHOD__, $params); } return $status; }
/** * @see FileBackendStore::doStoreInternal() */ protected function doStoreInternal(array $params) { $status = Status::newGood(); list($dstCont, $dstRel) = $this->resolveStoragePathReal($params['dst']); if ($dstRel === null) { $status->fatal('backend-fail-invalidpath', $params['dst']); return $status; } // (a) Check the destination container and object try { unset($this->objCache[$params['dst']]); $dContObj = $this->getContainer($dstCont); if (empty($params['overwrite']) && $this->fileExists(array('src' => $params['dst'], 'latest' => 1))) { $status->fatal('backend-fail-alreadyexists', $params['dst']); return $status; } } catch (NoSuchContainerException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); $this->logException($e, __METHOD__, $params); return $status; } catch (InvalidResponseException $e) { $status->fatal('backend-fail-connect', $this->name); $this->logException($e, __METHOD__, $params); return $status; } catch (Exception $e) { // some other exception? $status->fatal('backend-fail-internal', $this->name); $this->logException($e, __METHOD__, $params); return $status; } // (b) Get a SHA-1 hash of the object $sha1Hash = sha1_file($params['src']); if ($sha1Hash === false) { // source doesn't exist? $status->fatal('backend-fail-copy', $params['src'], $params['dst']); return $status; } $sha1Hash = wfBaseConvert($sha1Hash, 16, 36, 31); // (c) Actually store the object try { // Create a fresh CF_Object with no fields preloaded. // We don't want to preserve headers, metadata, and such. $obj = new CF_Object($dContObj, $dstRel, false, false); // skip HEAD // Note: metadata keys stored as [Upper case char][[Lower case char]...] $obj->metadata = array('Sha1base36' => $sha1Hash); // The MD5 here will be checked within Swift against its own MD5. $obj->set_etag(md5_file($params['src'])); // Use the same content type as StreamFile for security $obj->content_type = $this->getFileProps($params)['mime']; // Wikia cnange: use the same logic as for DB row (BAC-1199) // Actually write the object in Swift $obj->load_from_filename($params['src'], True); // calls $obj->write() } catch (BadContentTypeException $e) { $status->fatal('backend-fail-contenttype', $params['dst']); $this->logException($e, __METHOD__, $params); } catch (IOException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); $this->logException($e, __METHOD__, $params); } catch (InvalidResponseException $e) { $status->fatal('backend-fail-connect', $this->name); $this->logException($e, __METHOD__, $params); } catch (Exception $e) { // some other exception? $status->fatal('backend-fail-internal', $this->name); $this->logException($e, __METHOD__, $params); } wfRunHooks('SwiftFileBackend::doStoreInternal', array($params, &$status)); return $status; }