bool ZWebDAV::sHandle_MOVE(const ZTrail& iPrefix, ZNode iRoot, const ZStreamR&, const ZStreamW& iStreamW, const ZTuple& iHeader, const ZTrail& iTrail, const ZTuple& iParam) { ZHTTP::Response r; r.Set("date", sAsString_WebDAV(ZTime::sNow())); r.Set("Content-Length", 0); ZNode theNode = iRoot.Trail(iTrail); if (!theNode.Exists()) { r.SetResult(404); } else { string thePath = sGetPathFromURL(ZHTTP::sGetString0(iHeader.GetValue("destination"))); ZTrail theTrail = sStripPrefix(iPrefix, ZHTTP::sDecodeTrail(thePath)); ZNode theDestNode = iRoot.Trail(theTrail); if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV::sHandle_MOVE")) { s << "thePath: " << thePath << "\n"; s << "theTrail: " << theTrail.AsString() << "\n"; } bool doneIt = false; if (!doneIt) doneIt = theNode.MoveTo(theDestNode); // if (!doneIt) // doneIt = theDestNode.MoveFrom(theNode); if (!doneIt) { if (ZRef<ZStreamerR> sourceStreamer = theNode.OpenR(false)) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV::sHandle_MOVE")) s << "Got a source streamer, "; const ZStreamR& source = sourceStreamer->GetStreamR(); if (ZRef<ZStreamerWPos> destStreamer = theDestNode.CreateWPos(true, false)) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV::sHandle_MOVE")) s << "and a dest streamer"; const ZStreamWPos& dest = destStreamer->GetStreamWPos(); dest.Truncate(); dest.CopyAllFrom(source); theNode.Delete(); doneIt = true; } } } if (doneIt) r.SetResult(204); else r.SetResult(400); } r.Send(iStreamW); return true; }
bool ZWebDAV::sHandle_GET(const ZTrail& iPrefix, ZNode iRoot, const ZStreamR&, const ZStreamW& iStreamW, const ZTuple& iHeader, const ZTrail& iTrail, const ZTuple& iParam) { ZNode theNode = iRoot.Trail(iTrail); ZHTTP::Response r; r.Set("date", sAsString_WebDAV(ZTime::sNow())); if (iHeader.Has("range")) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV")) s << "GET with range:\n" << iHeader; } if (theNode.Exists()) { r.SetResult(200); if (theNode.CanHaveChildren()) { r.Set("Content-Type", "text/html; charset=\"utf-8\""); r.Set("Transfer-Encoding", "chunked"); r.Send(iStreamW); ZHTTP::StreamW_Chunked chunkedStream(iStreamW); ZStrimW_StreamUTF8 theStrimW(chunkedStream); ZStrimW_ML s(false, theStrimW); s.Begin("html"); s.Begin("title"); s << theNode.Name(); s.End("title"); s.Begin("body"); for (ZNodeIter i = theNode; i; i.Advance()) { s.Begin("p"); s.Begin("a"); if (i.Current().CanHaveChildren()) { s.Attr("href", ZHTTP::sEncodeComponent(i.Current().Name()) + "/"); s << i.Current().Name() << "/"; } else { s.Attr("href", ZHTTP::sEncodeComponent(i.Current().Name())); s << i.Current().Name(); } s.End("a"); s.End("p"); } s.End("body"); s.End("html"); } else if (ZRef<ZStreamerRPos> theStreamer = theNode.OpenRPos()) { const ZStreamRPos& theStreamRPos = theStreamer->GetStreamRPos(); uint64 sentSize = theStreamRPos.GetSize(); if (ZTupleValue rangeParam = iHeader.GetValue("range")) { vector<pair<size_t, size_t> > ranges; if (!ZHTTP::sOrganizeRanges(sentSize, rangeParam, ranges)) { iStreamW.WriteString("HTTP/1.1 406 Unsatisfiable range\r\n\r\n"); return false; } r.SetResult(206, "Partial Content"); r.Set("Content-Range", ZString::sFormat("bytes %d-%d/%d", ranges.front().first, ranges.front().second - 1, sentSize)); theStreamRPos.SetPosition(ranges.front().first); sentSize = ranges.front().second - ranges.front().first; } else { r.SetResult(200); } string theMIMEType = "application/octet-stream"; ZTupleValue theMIMEValue; if (theNode.GetProp("MIMEType", theMIMEValue)) { string asString; if (theMIMEValue.GetString(asString)) theMIMEType = asString; } r.Set("Content-Type", theMIMEType); ZTupleValue theValue; if (theNode.GetProp("lastModified", theValue)) { if (ZTime theTime = theValue.GetTime()) r.Set("Last-Modified", sAsString_WebDAV(theTime)); } r.Set("Content-Transfer-Encoding", "binary"); r.Set("Content-Length", ZString::sFromUInt64(sentSize)); r.Send(iStreamW); iStreamW.CopyFrom(theStreamRPos, sentSize); } } else { r.SetResult(404); r.Send(iStreamW); r.Set("Content-Length", 0); } return true; }
static void sWriteAsXML(ZStrimW_ML& s, const ZTuple& iTuple) { for (ZTuple::const_iterator i = iTuple.begin(); i != iTuple.end(); ++i) sWriteAsXML(s, iTuple.NameOf(i), iTuple.GetValue(i)); }
bool ZTBSpec::Criterion::Matches(const ZTuple& iTuple) const { ZTuple::const_iterator propIter = iTuple.IteratorOf(this->GetPropName()); if (propIter == iTuple.end()) { // iTuple does not have a property named fPropName. For // 'Lacks' and 'LacksOfType' relationships that means // we match iTuple, for all other relationships we don't. return this->GetComparator().fRel == eRel_Lacks || this->GetComparator().fRel == eRel_LacksOfType; } switch (this->GetComparator().fRel) { case eRel_Has: { return true; } case eRel_HasOfType: { return iTuple.TypeOf(propIter) == this->GetTupleValue().GetType(); } case eRel_Lacks: { // iTuple has a property named fPropName, // so it doesn't lack a property named fPropName. return false; } case eRel_LacksOfType: { return iTuple.TypeOf(propIter) != this->GetTupleValue().GetType(); } case eRel_VectorContains: { if (iTuple.TypeOf(propIter) != eZType_Vector) return false; const vector<ZTupleValue>& theVector = iTuple.GetVector(propIter); for (vector<ZTupleValue>::const_iterator i = theVector.begin(); i != theVector.end(); ++i) { if (*i == this->GetTupleValue()) return true; #if 0 //## if ((*i).TypeOf() == this->GetTupleValue().TypeOf()) { if ((*i).UncheckedEqual(this->GetTupleValue())) return true; } #endif } return false; } case eRel_StringContains: { string pattern; if (!this->GetTupleValue().GetString(pattern) || pattern.empty()) return true; string target; if (!iTuple.GetString(propIter, target) || target.empty()) return false; if (!fRep->fTextCollator) { fRep->fTextCollator = ZTextCollator(this->GetComparator().fStrength); } return fRep->fTextCollator.Contains(pattern, target); } case eRel_Regex: { #if ZCONFIG_API_Enabled(Regex) string target; if (!iTuple.GetString(propIter, target) || target.empty()) return false; if (!fRep->fRegex) { fRep->fRegex = ZRegex(this->GetTupleValue().GetString(), this->GetComparator().fStrength); } if (!fRep->fRegex) return false; return fRep->fRegex.Matches(target); #else return false; #endif } default: { const ZTupleValue& leftValue = iTuple.GetValue(propIter); ZType leftType = leftValue.TypeOf(); ZType rightType = this->GetTupleValue().TypeOf(); if (this->GetComparator().fRel == eRel_Equal) { if (leftType != rightType) { return false; } else { if (leftType == eZType_String && this->GetComparator().fStrength != 0) { // We're doing string compares where the strength is non zero and // so we need to use a collator to do the comparison. if (!fRep->fTextCollator) { fRep->fTextCollator = ZTextCollator(this->GetComparator().fStrength); } return fRep->fTextCollator.Equals( leftValue.GetString(), this->GetTupleValue().GetString()); } else { // The type matches, so do the appropriate comparison. // return leftValue.pUncheckedEqual(this->GetTupleValue()); return leftValue == this->GetTupleValue(); } } } else { int compare; if (leftType != rightType) { compare = int(leftType) - int(rightType); } else { if (leftType == eZType_String && this->GetComparator().fStrength != 0) { // We're doing string compares where the strength is non zero and // so we need to use a collator to do the comparison. if (!fRep->fTextCollator) { fRep->fTextCollator = ZTextCollator(this->GetComparator().fStrength); } compare = fRep->fTextCollator.Compare( leftValue.GetString(), this->GetTupleValue().GetString()); } else { // The type matches, so do the appropriate comparison. // compare = leftValue.pUncheckedCompare(this->GetTupleValue()); compare = leftValue.Compare(this->GetTupleValue()); } } switch (this->GetComparator().fRel) { case eRel_Less: return compare < 0; case eRel_LessEqual: return compare <= 0; case eRel_GreaterEqual: return compare >= 0; case eRel_Greater: return compare > 0; } } } } // Can't get here. ZUnimplemented(); return false; }
ZTBSpec::Criterion::Rep::Rep(const ZTuple& iTuple) : fPropName(iTuple.GetString("PropName")), fComparator(sRelFromString(iTuple.GetString("Rel")), iTuple.GetInt32("Strength")), fTupleValue(iTuple.GetValue("Value")) {}
static void sToStrim_Tuple(const ZStrimW& s, const ZTuple& iTuple, size_t iLevel, const ZUtil_Tuple::Options& iOptions, bool iMayNeedInitialLF) { if (iTuple.Empty()) { // We've got an empty tuple. s.Write("{}"); return; } const ZTuple::const_iterator theBegin = iTuple.begin(); const ZTuple::const_iterator theEnd = iTuple.end(); bool needsIndentation = false; if (iOptions.DoIndentation()) { for (ZTuple::const_iterator i = theBegin; i != theEnd; ++i) { if (sIsComplex(iOptions, iTuple.GetValue(i))) { needsIndentation = true; break; } } } if (needsIndentation) { if (iMayNeedInitialLF) { // We're going to be indenting, but need to start // a fresh line to have our { and contents line up. sWriteLFIndent(s, iLevel, iOptions); } s.Write("{"); for (ZTuple::const_iterator i = theBegin; i != theEnd; ++i) { sWriteLFIndent(s, iLevel, iOptions); ZUtil_Tuple::sWrite_PropName(s, iTuple.NameOf(i)); s << " = "; sToStrim_TupleValue(s, iTuple.GetValue(i), iLevel + 1, iOptions, true); s.Write(";"); } sWriteLFIndent(s, iLevel, iOptions); s.Write("}"); } else { s.Write("{"); for (ZTuple::const_iterator i = theBegin; i != theEnd; ++i) { s.Write(" "); ZUtil_Tuple::sWrite_PropName(s, iTuple.NameOf(i)); s << " = "; sToStrim_TupleValue(s, iTuple.GetValue(i), iLevel + 1, iOptions, true); s.Write(";"); } s.Write(" }"); } }