Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion controller/notesapicontroller.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ private function excludeFields(Note $note, array $exclude) {
}


private function excludeIfNotModified(Note $note, array $etags) {
$etag = $note->getEtag();
if($etag!==null && in_array($etag, $etags)) {
$vars = get_object_vars($note);
unset($vars['id']);
$this->excludeFields($note, array_keys($vars));
}
return $note;
}


/**
* @NoAdminRequired
* @CORS
Expand All @@ -74,11 +85,14 @@ private function excludeFields(Note $note, array $exclude) {
*/
public function index($exclude='') {
$exclude = explode(',', $exclude);
$etags = array_key_exists('HTTP_X_NOTES_ETAGS', $_SERVER) ? $_SERVER['HTTP_X_NOTES_ETAGS'] : '';
$etags = str_split($etags, 20);
$notes = $this->service->getAll($this->userId);
foreach ($notes as $note) {
$note = $this->excludeFields($note, $exclude);
$note = $this->excludeIfNotModified($note, $etags);
}
return new DataResponse($notes);
return (new DataResponse($notes))->addHeader('Vary', 'X-Notes-Etags');
}


Expand Down
29 changes: 29 additions & 0 deletions db/note.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* Class Note
* @method integer getId()
* @method void setId(integer $value)
* @method string getEtag()
* @method void setEtag(string $value)
* @method integer getModified()
* @method void setModified(integer $value)
* @method string getTitle()
Expand All @@ -33,6 +35,7 @@
*/
class Note extends Entity {

public $etag;
public $modified;
public $title;
public $category;
Expand Down Expand Up @@ -60,8 +63,34 @@ public static function fromFile(File $file, Folder $notesFolder, $tags=[]){
$note->setFavorite(true);
//unset($tags[array_search(\OC\Tags::TAG_FAVORITE, $tags)]);
}
$note->updateETag();
$note->resetUpdatedFields();
return $note;
}

private function updateETag() {
$etag = '';
// collect all relevant attributes
$data = '';
foreach(get_object_vars($this) as $key => $val) {
if($key!=='etag') {
$data .= $val;
}
}
// create binary checksum
$md5 = md5($data, true);
// binary-to-text using a base85 derivate:
// - only 25% larger than binary data
// - replace problematic characters by not-used ones (no escaping necessary in JSON or HTTP-header)
// - the result has always the same length (20 characters for 16byte md5-checksum)
foreach(unpack('N*', $md5) as $chunk) {
for ($a = 0; $a < 5; $a++) {
$b = intval($chunk / (pow(85,4 - $a)));
$chr = str_replace(array('\\', '/', '<', '>'), array('z', '|', '{', '}'), chr($b + 35));
$etag .= $chr;
$chunk -= $b * pow(85,4 - $a);
}
}
$this->setEtag($etag);
}
}
3 changes: 3 additions & 0 deletions tests/unit/controller/NotesApiControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ public function testGetAllHide(){

$this->assertEquals(json_encode([
[
'etag' => null,
'modified' => 123,
'category' => null,
'favorite' => false,
'id' => 3,
],
[
'etag' => null,
'modified' => 111,
'category' => null,
'favorite' => false,
Expand Down Expand Up @@ -139,6 +141,7 @@ public function testGetHide(){
$response = $this->controller->get(3, 'title,content');

$this->assertEquals(json_encode([
'etag' => null,
'modified' => 123,
'category' => null,
'favorite' => false,
Expand Down