webdav search
Best, Jan-Pascal van
j.p.vanbest at tbm.tudelft.nl
Fri Apr 26 16:47:31 BST 2002
Hi all,
>From the kfm-devel mailing list I guessed that you were the people
working on the http ioslave. Please let
me know if I should send this somewhere else
>From the kdepim/korganizer context, I've been working on
support for exchange 2000 calendar servers with webdav.
I'm made some changes to my local kdelibs tree which I think
could be useful for more people.
At the end of this message is a patch to http.c/http.h that
- implements a davSearch() method
- implements the SEARCH function as a special().
- adds a "translate: f" header flag for all webdav GETs. This should
be an option of some kind, but i don't know how and where. Any
ideas?
- add a content-type: text/xml for dav search in httpOpen().
I guess this should be done somewhere else, but I don't know
where. I've tried an addMetadata() in davSearch, but that
didn't work
- do not finish the header when there is still davData to send (this
fixes a bug that just hasn't shown up yet)
- Strange thing: I had to substract 1 from the content-size header
before Exchange would swallow my search requests. Maybe something to
do with zero-terminated strings?
I'm also attaching searchjob.cpp and searchjob.h, which implement
a SearchJob class, which looks a lot like the ListJob class.
So, what do you think? Should this ultimately go into kdelibs,
and what should be done before that?
Cheers
Jan-Pascal
PS: This is the first thing I ever wrote for KDE. Let me know if
I'm doing something stupid...
--
Jan-Pascal van Best
Delft University of Technology
http://www.tbm.tudelft.nl/webstaf/janb/index.htm
Index: http.cc
===================================================================
RCS file: /home/kde/kdelibs/kioslave/http/http.cc,v
retrieving revision 1.494
diff -u -3 -p -r1.494 http.cc
--- http.cc 22 Apr 2002 13:00:20 -0000 1.494
+++ http.cc 26 Apr 2002 13:18:32 -0000
@@ -1175,6 +1175,96 @@ void HTTPProtocol::davUnlock( const KURL
davError();
}
+void HTTPProtocol::davSearch( const KURL &url, const QCString& query )
+{
+ UDSEntry entry;
+ UDSAtom atom;
+
+ kdDebug() << "(" << m_pid << ") HTTPProtocol::davSearch "
+ << url.prettyURL() << endl;
+
+ if ( !checkRequestURL( url ) )
+ return;
+
+ m_request.method = DAV_SEARCH;
+ m_request.path = url.path();
+ m_request.query = QString::null;
+ m_request.cache = DEFAULT_CACHE_CONTROL;
+ m_request.doProxy = m_bUseProxy;
+
+ // This doesn't work setMetaData("content-type", "text/xml");
+
+ /* Create appropriate search XML request. */
+/*
+ QDomDocument searchReq;
+
+ QDomElement searchInfo = searchReq.createElementNS( "DAV:",
"searchrequest" );
+ // searchInfo.appendChild( searchReq.createTextNode( query ) );
+ QDomCharacterData data;
+ data.setData(query);
+ searchInfo.appendChild ( data );
+ searchReq.appendChild( searchInfo );
+*/
+
+ QCString request = "<?xml version=\"1.0\"?>\r\n";
+ request.append("<g:searchrequest xmlns:g=\"DAV:\">\r\n");
+ request.append(query);
+ request.append("</g:searchrequest>\r\n");
+
+ // insert the document into the POST buffer
+ m_bufPOST = request;
+
+ retrieveContent( true );
+
+ if ( m_responseCode == 207 ) {
+ // success
+ QDomDocument multiResponse;
+ multiResponse.setContent( m_intData, true );
+
+ kdDebug() << m_intData << endl;
+
+ for ( QDomElement thisResponse =
multiResponse.documentElement().firstChild().toElement();
+ !thisResponse.isNull();
+ thisResponse = thisResponse.nextSibling().toElement() )
+ {
+ QDomElement href = thisResponse.namedItem( "href" ).toElement();
+ if ( !href.isNull() )
+ {
+ entry.clear();
+
+ KURL thisURL = KURL::decode_string( href.text() );
+ kdDebug() << thisURL.prettyURL() << endl;
+
+ // don't list the base dir of a listDir()
+ if ( thisURL.path(+1).length() == url.path(+1).length() )
+ continue;
+
+ atom.m_uds = KIO::UDS_NAME;
+ atom.m_str = thisURL.filename();
+ entry.append( atom );
+
+ QDomNodeList propstats = thisResponse.elementsByTagName(
"propstat" );
+
+ davParsePropstats( propstats, entry );
+
+ kdDebug() << "Calling listEntry() from
HTTPProtocol::davSearch()" << endl;
+ listEntry( entry, false );
+ }
+ else
+ {
+ kdDebug(7113) << "Error: no URL contained in response to SEARCH
on "
+ << url.prettyURL() << endl;
+ }
+ }
+ listEntry( entry, true );
+ finished();
+
+ } else {
+ kdDebug(7113) << m_intData << endl;
+ davError();
+ }
+}
+
QString HTTPProtocol::davError( int code /* = -1 */, QString url )
{
bool callError = false;
@@ -1214,6 +1304,9 @@ QString HTTPProtocol::davError( int code
case DAV_LOCK:
action = i18n( "lock the specified file or directory" );
break;
+ case DAV_SEARCH:
+ action = i18n( "search the specified directory using a special
query" );
+ break;
case DAV_UNLOCK:
action = i18n( "unlock the specified file or directory" );
break;
@@ -1807,6 +1900,8 @@ bool HTTPProtocol::httpOpen()
{
case HTTP_GET:
header = "GET ";
+ if (m_protocol == "webdav" || m_protocol == "webdavs")
+ davHeader = "Translate: f\r\n";
break;
case HTTP_PUT:
header = "PUT ";
@@ -1880,6 +1975,12 @@ bool HTTPProtocol::httpOpen()
davHeader = "Lock-token: " + metaData("davLockToken") + "\r\n";
m_bCachedWrite = false; // Do not put any result in the cache
break;
+ case DAV_SEARCH:
+ header = "SEARCH ";
+ davHeader = "Content-Type: text/xml; charset=utf-8\r\n";
+ davData = true;
+ m_bCachedWrite = false;
+ break;
}
if ( isSSLTunnelEnabled() )
@@ -2109,9 +2210,11 @@ bool HTTPProtocol::httpOpen()
if ( m_protocol == "webdav" || m_protocol == "webdavs" )
header += davProcessLocks();
- if ( !moreData )
+ if ( !moreData && !davData) {
header += "\r\n"; /* end header */
-
+ }
+
kdDebug(7103) << "(" << m_pid << ") ============ Sending Header:" <<
endl;
QStringList headerOutput = QStringList::split("\r\n", header);
@@ -3205,7 +3308,8 @@ bool HTTPProtocol::sendBody()
if ( !m_bufPOST.isNull() )
{
kdDebug(7113) << "(" << m_pid << ") POST'ing saved data..." <<
endl;
- length = m_bufPOST.size();
+ length = m_bufPOST.size()-1; // FIXME: JPvB: substracted because
the Exchange server complains if I don't
+ kdDebug() << "Length is " << length << endl;
result = 0;
}
else
@@ -3374,6 +3480,15 @@ void HTTPProtocol::special( const QByteA
KURL url;
stream >> url;
davUnlock( url );
+ break;
+ }
+ case 7: // WebDAV search
+ {
+ KURL url;
+ QString query;
+ stream >> url >> query;
+ kdDebug() << "URL, query " << url.prettyURL() << "," <<
query.utf8() << endl;
+ davSearch( url, query.utf8() );
break;
}
default:
Index: http.h
===================================================================
RCS file: /home/kde/kdelibs/kioslave/http/http.h,v
retrieving revision 1.127
diff -u -3 -p -r1.127 http.h
--- http.h 17 Apr 2002 07:25:35 -0000 1.127
+++ http.h 26 Apr 2002 13:18:33 -0000
@@ -60,7 +60,7 @@ public:
/** HTTP / DAV method **/
enum HTTP_METHOD {HTTP_GET, HTTP_PUT, HTTP_POST, HTTP_HEAD,
HTTP_DELETE,
HTTP_OPTIONS, DAV_PROPFIND, DAV_PROPPATCH,
DAV_MKCOL,
- DAV_COPY, DAV_MOVE, DAV_LOCK, DAV_UNLOCK };
+ DAV_COPY, DAV_MOVE, DAV_LOCK, DAV_UNLOCK,
DAV_SEARCH };
/** State of the current Connection **/
typedef struct
@@ -147,6 +147,9 @@ public:
void davLock( const KURL& url, const QString& scope,
const QString& type, const QString& owner );
void davUnlock( const KURL& url );
+
+ // Search using a query in a language the server supports
+ void davSearch( const KURL &url, const QCString& query );
// Calls httpClose() and finished()
void davFinished();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: searchjob.cpp
Type: application/octet-stream
Size: 4505 bytes
Desc: searchjob.cpp
URL: <https://mail.kde.org/mailman/private/kfm-devel/attachments/20020426/7b8c2a23/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: searchjob.h
Type: application/octet-stream
Size: 2756 bytes
Desc: searchjob.h
URL: <https://mail.kde.org/mailman/private/kfm-devel/attachments/20020426/7b8c2a23/attachment-0001.obj>
More information about the kfm-devel
mailing list