-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the a parser for the 'If' header
- Loading branch information
1 parent
c4d3ace
commit e4e2208
Showing
3 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { IResource, ReturnCallback } from '../resource/IResource'; | ||
import { MethodCallArgs } from '../server/MethodCallArgs'; | ||
export declare function extractOneToken(ifHeader: string): string; | ||
export declare function parseIfHeader(ifHeader: string): (arg: MethodCallArgs, r: IResource, callback: ReturnCallback<boolean>) => void; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var IResource_1 = require("../resource/IResource"); | ||
var url = require("url"); | ||
function NoLock() { | ||
return function (r, callback) { | ||
r.getLocks(function (e, locks) { | ||
callback(e, locks ? locks.length === 0 : false); | ||
}); | ||
}; | ||
} | ||
function Token(token) { | ||
return function (r, callback) { | ||
r.getLock(token, function (e, lock) { | ||
callback(e, !!lock && !e); | ||
}); | ||
}; | ||
} | ||
function Tag(tag) { | ||
return function (r, callback) { | ||
r.lastModifiedDate(function (e, lastModifiedDate) { | ||
callback(e, !e && IResource_1.ETag.createETag(lastModifiedDate) === tag); | ||
}); | ||
}; | ||
} | ||
function Not(filter) { | ||
return function (r, callback) { | ||
filter(r, function (e, v) { | ||
callback(e, !v); | ||
}); | ||
}; | ||
} | ||
function parseInternal(group) { | ||
var rex = /((not)|<([^>]+)>|\[([^\]]+)\]|<(DAV:no-lock)>)/ig; | ||
var match = rex.exec(group); | ||
var isNot = false; | ||
var andArray = []; | ||
function add(filter) { | ||
andArray.push(isNot ? Not(filter) : filter); | ||
isNot = false; | ||
} | ||
while (match) { | ||
if (match[2]) { | ||
isNot = true; | ||
} | ||
else if (match[3]) { | ||
add(Token(match[3])); | ||
} | ||
else if (match[4]) { | ||
add(Tag(match[4])); | ||
} | ||
else if (match[5]) { | ||
add(NoLock()); | ||
} | ||
match = rex.exec(group); | ||
} | ||
if (andArray.length) | ||
return function (r, callback) { return callback(null, true); }; | ||
return function (r, callback) { | ||
var nb = andArray.length; | ||
function done(error, result) { | ||
if (nb <= 0) | ||
return; | ||
if (error) { | ||
nb = -1; | ||
callback(error, false); | ||
return; | ||
} | ||
--nb; | ||
if (nb === 0 || !result) { | ||
nb = -1; | ||
callback(null, result); | ||
} | ||
} | ||
andArray.forEach(function (a) { return a(r, done); }); | ||
}; | ||
} | ||
function extractOneToken(ifHeader) { | ||
var match = /^[ ]*\([ ]*<([^>]+)>[ ]*\)[ ]*$/.exec(ifHeader); | ||
if (!match) | ||
return null; | ||
else | ||
return match[1]; | ||
} | ||
exports.extractOneToken = extractOneToken; | ||
function parseIfHeader(ifHeader) { | ||
var rex = /(?:<([^>]+)>)?\s*\(([^\)]+)\)/g; | ||
var match = rex.exec(ifHeader); | ||
var orArray = []; | ||
var oldPath = undefined; | ||
while (match) { | ||
if (match[1]) | ||
oldPath = url.parse(match[1]).path; | ||
orArray.push({ | ||
path: oldPath, | ||
actions: parseInternal(match[2]) | ||
}); | ||
match = rex.exec(ifHeader); | ||
} | ||
if (orArray.length) | ||
return function (arg, r, callback) { return callback(null, true); }; | ||
return function (arg, r, callback) { | ||
var nb = orArray.length; | ||
function done(error, result) { | ||
if (nb <= 0) | ||
return; | ||
if (error) { | ||
nb = -1; | ||
callback(error, false); | ||
return; | ||
} | ||
--nb; | ||
if (nb === 0 || result) { | ||
nb = -1; | ||
callback(null, result); | ||
} | ||
} | ||
orArray.forEach(function (a) { | ||
if (!a.path) | ||
a.actions(r, done); | ||
else | ||
arg.server.getResourceFromPath(a.path, function (e, resource) { | ||
a.actions(resource, done); | ||
}); | ||
}); | ||
}; | ||
} | ||
exports.parseIfHeader = parseIfHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import { IResource, ReturnCallback, ETag } from '../resource/IResource' | ||
import { MethodCallArgs } from '../server/MethodCallArgs' | ||
import { Errors } from '../Errors' | ||
import * as url from 'url' | ||
|
||
type FnReturn = ReturnCallback<boolean> | ||
|
||
function NoLock() | ||
{ | ||
return function(r : IResource, callback : FnReturn) { | ||
r.getLocks((e, locks) => { | ||
callback(e, locks ? locks.length === 0 : false); | ||
}) | ||
} | ||
} | ||
|
||
function Token(token : string) | ||
{ | ||
return function(r : IResource, callback : FnReturn) { | ||
r.getLock(token, (e, lock) => { | ||
callback(e, !!lock && !e); | ||
}) | ||
} | ||
} | ||
|
||
function Tag(tag : string) | ||
{ | ||
return function(r : IResource, callback : FnReturn) { | ||
r.lastModifiedDate((e, lastModifiedDate) => { | ||
callback(e, !e && ETag.createETag(lastModifiedDate) === tag); | ||
}) | ||
} | ||
} | ||
|
||
function Not(filter) | ||
{ | ||
return function(r : IResource, callback : FnReturn) { | ||
filter(r, (e, v) => { | ||
callback(e, !v); | ||
}) | ||
} | ||
} | ||
|
||
function parseInternal(group : string) | ||
{ | ||
const rex = /((not)|<([^>]+)>|\[([^\]]+)\]|<(DAV:no-lock)>)/ig; | ||
let match = rex.exec(group); | ||
|
||
let isNot = false; | ||
const andArray = []; | ||
function add(filter) | ||
{ | ||
andArray.push(isNot ? Not(filter) : filter); | ||
isNot = false; | ||
} | ||
|
||
while(match) | ||
{ | ||
if(match[2]) | ||
{ // not | ||
isNot = true; | ||
} | ||
else if(match[3]) | ||
{ // lock-token | ||
add(Token(match[3])); | ||
} | ||
else if(match[4]) | ||
{ // tag | ||
add(Tag(match[4])); | ||
} | ||
else if(match[5]) | ||
{ // DAV:no-lock | ||
add(NoLock()); | ||
} | ||
match = rex.exec(group); | ||
} | ||
|
||
if(andArray.length) | ||
return (r, callback) => callback(null, true); | ||
|
||
return function(r : IResource, callback : FnReturn) { | ||
let nb = andArray.length; | ||
function done(error, result) | ||
{ | ||
if(nb <= 0) | ||
return; | ||
if(error) | ||
{ | ||
nb = -1; | ||
callback(error, false); | ||
return; | ||
} | ||
--nb; | ||
if(nb === 0 || !result) | ||
{ | ||
nb = -1; | ||
callback(null, result); | ||
} | ||
} | ||
|
||
andArray.forEach((a) => a(r, done)); | ||
}; | ||
} | ||
|
||
export function extractOneToken(ifHeader : string) | ||
{ | ||
const match = /^[ ]*\([ ]*<([^>]+)>[ ]*\)[ ]*$/.exec(ifHeader); | ||
if(!match) | ||
return null; | ||
else | ||
return match[1]; | ||
} | ||
|
||
export function parseIfHeader(ifHeader : string) | ||
{ | ||
const rex = /(?:<([^>]+)>)?\s*\(([^\)]+)\)/g; | ||
let match = rex.exec(ifHeader); | ||
|
||
const orArray = []; | ||
let oldPath = undefined; | ||
|
||
while(match) | ||
{ | ||
if(match[1]) | ||
oldPath = url.parse(match[1]).path; | ||
|
||
orArray.push({ | ||
path: oldPath, | ||
actions: parseInternal(match[2]) | ||
}) | ||
|
||
match = rex.exec(ifHeader); | ||
} | ||
|
||
if(orArray.length) | ||
return (arg : MethodCallArgs, r : IResource, callback : ReturnCallback<boolean>) => callback(null, true); | ||
|
||
return function(arg : MethodCallArgs, r : IResource, callback : ReturnCallback<boolean>) { | ||
let nb = orArray.length; | ||
function done(error, result) | ||
{ | ||
if(nb <= 0) | ||
return; | ||
if(error) | ||
{ | ||
nb = -1; | ||
callback(error, false); | ||
return; | ||
} | ||
--nb; | ||
if(nb === 0 || result) | ||
{ | ||
nb = -1; | ||
callback(null, result); | ||
} | ||
} | ||
|
||
orArray.forEach((a) => { | ||
if(!a.path) | ||
a.actions(r, done); | ||
else | ||
arg.server.getResourceFromPath(a.path, (e, resource) => { | ||
a.actions(resource, done); | ||
}); | ||
}) | ||
} | ||
} |