Annotation of libwww/Library/src/HTDAV.c, revision 1.3

1.1       kirschpi    1: /*
                      2: ** WebDAV MANAGER
                      3: **
1.3     ! kirschpi    4: **      (c) COPYRIGHT MIT 1995.
        !             5: **      Please first read the full copyright statement in the file COPYRIGH.
1.1       kirschpi    6: **
                      7: ** Authors
1.3     ! kirschpi    8: **      MKP     Manuele Kirsch Pinheiro, Manuele.Kirsch_Pinheiro@inrialpes.fr 
        !             9: **                                       manuele@inf.ufrgs.br
1.1       kirschpi   10: **
                     11: ** History
1.3     ! kirschpi   12: **      15 Fev 02 Writen
        !            13: **      15 Mar 02 Changed - All methods will use entity callback and not the
        !            14: **                message body functions. This modification was demanded by
        !            15: **                Jose Kahan.
        !            16: **      30 May 02 Changed - wwwsys.h becames the first include file
1.1       kirschpi   17: **
1.2       kirschpi   18: **      $Log: HTDAV.c,v $
1.3     ! kirschpi   19: **      Revision 1.2  2002/05/29 16:09:13  kirschpi
        !            20: **
        !            21: **      Fixes for windows plataform concerning WebDAV and Extension
        !            22: **      methods. In HTMethod and HTRequest, functions defined for
        !            23: **      the Extension Methods are now defined always, but return
        !            24: **      fail values when HT_EXT is not defined. In addition, the
        !            25: **      files "Library/src/WWWDAV.html" and "Library/src/windows/wwwdav.files"
        !            26: **      have been added. These files and modifications were needed
        !            27: **      to produce the correct "*.def" files, for windows plataform.
        !            28: **
1.2       kirschpi   29: **      Revision 1.1  2002/03/21 14:16:27  kirschpi
                     30: **      Missing files
                     31: **      Manuele Kirsch
1.1       kirschpi   32: **
1.2       kirschpi   33: **
1.3     ! kirschpi   34: ** $Id: HTDAV.c,v 1.2 2002/05/29 16:09:13 kirschpi Exp $
1.1       kirschpi   35: */
                     36: 
1.2       kirschpi   37: 
1.1       kirschpi   38: /* Library include files */
1.2       kirschpi   39: #include "wwwsys.h"
1.1       kirschpi   40: #include "WWWLib.h"
                     41: #include "WWWInit.h"
                     42: #include "WWWUtil.h"
                     43: #include "WWWStream.h"
1.3     ! kirschpi   44: #include "HTDAV.h"              /* implemented here */
1.1       kirschpi   45: 
                     46: #ifdef HT_DAV
                     47: 
                     48: struct _HTStream {
1.3     ! kirschpi   49:     const HTStreamClass *       isa;
        !            50:     HTStream *                  target;
        !            51:     HTRequest *                 request;
        !            52:     int                         version;
        !            53:     BOOL                        endHeader;
        !            54:     BOOL                        transparent;
1.1       kirschpi   55: };
                     56: 
                     57: 
                     58: /* --------------------------------------------------------------------------*/
                     59: /*                           WebDAV REQUEST HEADERS                          */
                     60: /* --------------------------------------------------------------------------*/
                     61: 
                     62: /* Headers defined in WebDAV - RC2518 
                     63: ** If: state list _ may be a tagged or a non-tag list of state tokens and Etags
                     64: ** Depth: how depth the method should be executed. Values are: 0,1,infinity
                     65: ** Destination: destination URI for COPY and MOVE methods
                     66: ** Overwrite: should the method overwrite any existant resource? Values: T or F
                     67: ** LockToken: lock identification (used only in UNLOCK method)
                     68: ** Timeout: lock timeout. Values: Second-nnn,Infinite or Extend file (RFC2068) 
                     69: */
                     70: struct _HTDAVHeaders {
                     71:     char * If;
                     72:     char * Depth;
                     73:     char * Destination;
                     74:     char * LockToken;
                     75:     char * Timeout;
                     76:     char Overwrite;
                     77: };
                     78: 
                     79: 
                     80: /*
                     81: ** Creates a new HTDAVHeaders struct 
                     82: */ 
                     83: PUBLIC HTDAVHeaders * HTDAVHeaders_new (void) {
                     84:     HTDAVHeaders *me;
                     85: 
                     86:     if ( (me = (HTDAVHeaders *) HT_CALLOC (1,sizeof(HTDAVHeaders))) == NULL)
                     87:         HT_OUTOFMEM ("HTDAVHeaders_new");
                     88: 
                     89:     /* set everything to an empty value */
                     90:     me->If = NULL;
                     91:     me->Depth = NULL;
                     92:     me->Destination = NULL;
                     93:     me->LockToken = NULL;
                     94:     me->Timeout = NULL;
                     95:     me->Overwrite = ' ';
                     96: 
                     97:     HTTRACE (PROT_TRACE,"HTDAV.... HTDAVHeaders object created\n");
                     98: 
                     99:     return me;
                    100: } 
                    101: 
                    102: 
                    103: /*
                    104: ** Deletes a HTDAVHeaders object
                    105: */
                    106: PUBLIC BOOL HTDAVHeaders_delete (HTDAVHeaders *me) {
                    107:     if (me) {
                    108:         if (me->If) HT_FREE (me->If);
                    109:         if (me->Depth) HT_FREE (me->Depth);
                    110:         if (me->Destination) HT_FREE (me->Destination);
                    111:         if (me->LockToken) HT_FREE (me->LockToken);
                    112:         if (me->Timeout) HT_FREE (me->Timeout);
                    113:         HT_FREE (me);
                    114: 
                    115:         HTTRACE (PROT_TRACE,"HTDAV.... HTDAVHeaders object removed\n");
                    116: 
                    117:         return YES;
                    118:     }
                    119:     return NO;
                    120: }
                    121: 
                    122: 
                    123: /*
                    124: ** Set the If header - see section 9.4 of RFC2518 
                    125: */ 
                    126: PUBLIC BOOL HTDAV_setIfHeader (HTDAVHeaders *me, const char *If) {
                    127:     if (me && If && *If) {
                    128:         HTTRACE (PROT_TRACE,"HTDAV.... If Header set\n");
                    129:         StrAllocCopy (me->If,If);
                    130:         return YES;
                    131:     }
                    132:     return NO;
                    133: }
                    134: 
                    135: /*
                    136: ** Removes the "If" header.
                    137: */
                    138: PUBLIC BOOL HTDAV_deleteIfHeader (HTDAVHeaders * me) {
                    139:     if (me && me->If) {
                    140:         HT_FREE(me->If);
                    141:         me->If = NULL;
                    142:         return YES;
                    143:     }
                    144:     return NO;
                    145: }
                    146: 
                    147: /*
                    148: ** Return the "If" header, NULL if this header is not set.
                    149: ** The caller should FREE the returned string
                    150: */
                    151: PUBLIC char * HTDAV_ifHeader (HTDAVHeaders *me) {
                    152:     char *copy = NULL;
                    153:     if (me && me->If) {
                    154:         StrAllocCopy (copy,me->If);
                    155:     }
                    156:     return copy;
                    157: }
                    158: 
                    159: 
                    160: /*
                    161: ** Set the Depth header - see section 9.2 of RFC2518 
                    162: */ 
                    163: PUBLIC BOOL HTDAV_setDepthHeader (HTDAVHeaders *me, const char *Depth) {
                    164:     if (me && Depth && *Depth) {
                    165:         HTTRACE (PROT_TRACE,"HTDAV.... Depth Header set\n");
                    166:         StrAllocCopy (me->Depth,Depth);
                    167:         return YES;
                    168:     }
                    169:     return NO;
                    170: }
                    171: 
                    172: 
                    173: /*
                    174: ** Removes the "Depth" header.
                    175: */
                    176: PUBLIC BOOL HTDAV_deleteDepthHeader (HTDAVHeaders * me) {
                    177:     if (me && me->Depth) {
1.3     ! kirschpi  178:         HT_FREE (me->Depth);
1.1       kirschpi  179:         me->Depth = NULL;
                    180:         return YES;
                    181:     }
                    182:     return NO;
                    183: }
                    184: 
                    185: 
                    186: /*
                    187: ** Return the "Depth" header, NULL if this header is not set.
                    188: ** The caller should FREE the returned string
                    189: */
                    190: PUBLIC char * HTDAV_DepthHeader (HTDAVHeaders *me) {
                    191:     char *copy = NULL;
                    192:     if (me && me->Depth) {
                    193:         StrAllocCopy (copy,me->Depth);
                    194:     }
                    195:     return copy;
                    196: }
                    197: 
                    198: 
                    199: /*
                    200: ** Set the LockToken header - see section 9.5 of RFC2518 
                    201: */ 
                    202: PUBLIC BOOL HTDAV_setLockTokenHeader (HTDAVHeaders *me, const char *LockToken) {
                    203:     if (me && LockToken && *LockToken) {
                    204:         HTTRACE (PROT_TRACE,"HTDAV.... Lock-Token Header set\n");
                    205:         StrAllocCopy (me->LockToken,LockToken);
                    206:         return YES;
                    207:     }
                    208:     return NO;
                    209: }
                    210: 
                    211: 
                    212: /*
                    213: ** Removes the "LockToken" header.
                    214: */
                    215: PUBLIC BOOL HTDAV_deleteLockTokenHeader (HTDAVHeaders * me) {
                    216:     if (me && me->LockToken) {
1.3     ! kirschpi  217:         HT_FREE (me->LockToken);
1.1       kirschpi  218:         me->LockToken = NULL;
                    219:         return YES;
                    220:     }
                    221:     return NO;
                    222: }
                    223: 
                    224: 
                    225: /*
                    226: ** Return the "LockToken" header, NULL if this header is not set.
                    227: ** The caller should FREE the returned string
                    228: */
                    229: PUBLIC char * HTDAV_LockTokenHeader (HTDAVHeaders *me) {
                    230:     char *copy = NULL;
                    231:     if (me && me->LockToken) {
                    232:         StrAllocCopy (copy,me->LockToken);
                    233:     }
                    234:     return copy;
                    235: }
                    236: 
                    237: 
                    238: /*
                    239: ** Set the Destination header - see section 9.3 of RFC2518 
                    240: */ 
                    241: PUBLIC BOOL HTDAV_setDestinationHeader (HTDAVHeaders *me, const char *Destination) {
                    242:     if (me && Destination && *Destination) {
                    243:         HTTRACE (PROT_TRACE,"HTDAV.... Destination Header set\n");
                    244:         StrAllocCopy (me->Destination,Destination);
                    245:         return YES;
                    246:     }
                    247:     return NO;
                    248: }
                    249: 
                    250: 
                    251: /*
                    252: ** Removes the "Destination" header.
                    253: */
                    254: PUBLIC BOOL HTDAV_deleteDestinationHeader (HTDAVHeaders * me) {
                    255:     if (me && me->Destination) {
1.3     ! kirschpi  256:         HT_FREE (me->Destination);
1.1       kirschpi  257:         me->Destination = NULL;
                    258:         return YES;
                    259:     }
                    260:     return NO;
                    261: }
                    262: 
                    263: 
                    264: /*
                    265: ** Return the "Destination" header, NULL if this header is not set.
                    266: ** The caller should FREE the returned string
                    267: */
                    268: PUBLIC char * HTDAV_DestinationHeader (HTDAVHeaders *me) {
                    269:     char *copy = NULL;
                    270:     if (me && me->Destination) {
                    271:         StrAllocCopy (copy,me->Destination);
                    272:     }
                    273:     return copy;
                    274: }
                    275: 
                    276: 
                    277: 
                    278: /*
                    279: ** Set the Timeout header - see section 9.8 of RFC2518 
                    280: */ 
                    281: PUBLIC BOOL HTDAV_setTimeoutHeader (HTDAVHeaders *me, const char *Timeout) {
                    282:     if (me && Timeout && *Timeout) {
                    283:         HTTRACE (PROT_TRACE,"HTDAV.... Timeout Header set\n");
                    284:         StrAllocCopy (me->Timeout,Timeout);
                    285:         return YES;
                    286:     }
                    287:     return NO;
                    288: }
                    289: 
                    290: 
                    291: /*
                    292: ** Removes the "Timeout" header.
                    293: */
                    294: PUBLIC BOOL HTDAV_deleteTimeoutHeader (HTDAVHeaders * me) {
                    295:     if (me && me->Timeout) {
1.3     ! kirschpi  296:         HT_FREE (me->Timeout);
1.1       kirschpi  297:         me->Timeout = NULL;
                    298:         return YES;
                    299:     }
                    300:     return NO;
                    301: }
                    302: 
                    303: 
                    304: /*
                    305: ** Return the "Timeout" header, NULL if this header is not set.
                    306: ** The caller should FREE the returned string
                    307: */
                    308: PUBLIC char * HTDAV_TimeoutHeader (HTDAVHeaders *me) {
                    309:     char *copy = NULL;
                    310:     if (me && me->Timeout) {
                    311:         StrAllocCopy (copy,me->Timeout);
                    312:     }
                    313:     return copy;
                    314: }
                    315: 
                    316: 
                    317: /*
                    318: ** Set the Overwrite header - see section 9.6 of RFC2518
                    319: */
                    320: PUBLIC BOOL HTDAV_setOverwriteHeader (HTDAVHeaders *me, BOOL Overwrite) {
                    321:     if (me) {
                    322:         HTTRACE (PROT_TRACE,"HTDAV.... Overwrite Header set\n");
                    323:         me->Overwrite = (Overwrite)?'T':'F';
                    324:         return YES;
                    325:     }
                    326:     return NO;
                    327: }
                    328: 
                    329: /*
                    330: ** Removes the "Overwirte" header.
                    331: */
                    332: PUBLIC BOOL HTDAV_deleteOverwriteHeader (HTDAVHeaders * me) {
                    333:     if (me) {
                    334:         me->Overwrite = ' ';
                    335:         return YES;
                    336:     }
                    337:     return NO;
                    338: }
                    339: 
                    340: 
                    341: /*
                    342: ** Returns the "Overwrite" header. If it is not set, returns the
                    343: ** default value (YES == TRUE)
                    344: */
                    345: PUBLIC BOOL HTDAV_OverwriteHeader (HTDAVHeaders * me) {
                    346:     if (me) {
                    347:       return (me->Overwrite==' ' || me->Overwrite=='T')?YES:NO;
                    348:     }
                    349:     return YES;
                    350: }
                    351: 
                    352: 
                    353: 
                    354: /* --------------------------------------------------------------------------*/
                    355: /*                           ENTITY CALLBACK                                 */
                    356: /* --------------------------------------------------------------------------*/
                    357: 
                    358: 
                    359: /*
                    360: ** Entity Callback - IDEM HTAccess.c
                    361: */
                    362: PRIVATE int HTEntity_callback (HTRequest * request, HTStream * target)
                    363: {
                    364:     HTParentAnchor * entity = HTRequest_entityAnchor(request);
                    365:     HTTRACE(APP_TRACE, "Posting Data from callback function\n");
                    366:     if (!request || !entity || !target) return HT_ERROR;
                    367:     {
                    368:         BOOL chunking = NO;
                    369:         int status;
                    370:         char * document = (char *) HTAnchor_document(entity);
                    371:         int len = HTAnchor_length(entity);
                    372:         if (!document) {
                    373:            HTTRACE(PROT_TRACE, "Posting Data No document\n");
                    374:            return HT_ERROR;
                    375:         }
                    376: 
                    377:         /*
                    378:         ** If the length is unknown (-1) then see if the document is a text
                    379:         ** type and in that case take the strlen. If not then we don't know
                    380:         ** how much data we can write and must stop
                    381:         */
                    382:         if (len < 0) {
                    383:             HTFormat actual = HTAnchor_format(entity);
                    384:             HTFormat tmplate = HTAtom_for("text/*");
                    385:             if (HTMIMEMatch(tmplate, actual)) {
1.3     ! kirschpi  386:                 len = strlen(document);                 /* Naive! */
1.1       kirschpi  387:                 chunking = YES;
                    388:             } else {
                    389:                 HTTRACE(PROT_TRACE, "Posting Data Must know the length of document %p\n" _ 
                    390:                              document);
                    391:                 return HT_ERROR;
                    392:             }
                    393:        }
                    394: 
                    395:         /* Send the data down the pipe */
                    396:         status = (*target->isa->put_block)(target, document, len);
                    397:         if (status == HT_WOULD_BLOCK) {
                    398:             HTTRACE(PROT_TRACE, "Posting Data Target WOULD BLOCK\n");
                    399:             return HT_WOULD_BLOCK;
                    400:         } else if (status == HT_PAUSE) {
                    401:             HTTRACE(PROT_TRACE, "Posting Data Target PAUSED\n");
                    402:             return HT_PAUSE;
                    403:         } else if (chunking && status == HT_OK) {
                    404:             HTTRACE(PROT_TRACE, "Posting Data Target is SAVED using chunked\n");
                    405:             return (*target->isa->put_block)(target, "", 0);
                    406:         } else if (status == HT_LOADED || status == HT_OK) {
                    407:             HTTRACE(PROT_TRACE, "Posting Data Target is SAVED\n");
                    408:             (*target->isa->flush)(target);
                    409:             return HT_LOADED;
1.3     ! kirschpi  410:         } else if (status > 0) {              /* Stream specific return code */
1.1       kirschpi  411:             HTTRACE(PROT_TRACE, "Posting Data. Target returns %d\n" _ status);
                    412:             return status;
1.3     ! kirschpi  413:         } else {                                     /* we have a real error */
1.1       kirschpi  414:             HTTRACE(PROT_TRACE, "Posting Data Target ERROR %d\n" _ status);
                    415:             return status;
                    416:         }
                    417:     }
                    418: }
                    419: 
                    420: 
                    421: 
                    422: /* --------------------------------------------------------------------------*/
                    423: /*                            LOCK REQUESTS                                  */
                    424: /* --------------------------------------------------------------------------*/
                    425: 
                    426: 
                    427: /*
                    428: ** LOCK REQUESTS
                    429: ** 
                    430: ** LOCK requests may create a lock specified by "lockinfo" XML element
                    431: ** on the Request URI. LOCK request should have a XML request entity body,
                    432: ** which contains "owner" XML element, or the request should be a lock
                    433: ** refresh request.
                    434: ** Headers:
1.3     ! kirschpi  435: **      If header is mandatory for lock refresh request
        !           436: **      Depth header may be "0" or "infinity" (default: infinity)
        !           437: **      Timeout header may be used
1.1       kirschpi  438: */
                    439: 
                    440: PUBLIC BOOL HTLOCKDocumentAnchor (HTRequest * request, 
                    441:                                   HTAnchor * dst,
                    442:                                   HTParentAnchor * xmlbody,
                    443:                                   HTDAVHeaders * headers) {
                    444:     
                    445:     if (request && dst) {
                    446:         /* set method and request-URI */
                    447:         HTRequest_setMethod (request,METHOD_LOCK);
                    448:         HTRequest_setAnchor (request,dst);
                    449:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to LOCK\n");
                    450: 
                    451:         /* set headers */
                    452:         HTTRACE (PROT_TRACE,"HTDAV.... Seting default Headers \n");
                    453:         HTRequest_addCacheControl (request,"no-cache","");
                    454:         HTRequest_addEnHd (request,HT_E_CONTENT_ENCODING);
                    455:         HTRequest_addEnHd (request,HT_E_CONTENT_LENGTH);
                    456:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                    457:  
                    458:         if (headers) { /* WebDAV specific headers */
                    459:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV headers \n");
                    460:             if (headers->If)
                    461:                 HTRequest_addExtraHeader (request,"If",headers->If);
                    462: 
                    463:             if (headers->Depth) { /* Depth: 0 or infinity only */
                    464:                 if (!strcasecomp(headers->Depth,"0") || 
                    465:                             !strcasecomp(headers->Depth,"infinity"))
                    466:                     HTRequest_addExtraHeader (request,"Depth",headers->Depth);
                    467:             }
                    468: 
                    469:             if (headers->Timeout)
                    470:                 HTRequest_addExtraHeader (request,"Timeout",headers->Timeout);
                    471:         }
                    472: 
                    473:         /* set body - if there is no body, we expect that is a lock refresh */
                    474:         if (xmlbody) {
                    475:             HTTRACE (PROT_TRACE,"HTDAV.... Setting Entity Body \n");
                    476:             HTRequest_setEntityAnchor (request,xmlbody); 
                    477:             HTRequest_setPostCallback(request, HTEntity_callback);
                    478:         }
                    479: 
                    480:         return HTLoad (request,NO);
                    481:     }
                    482:     return NO;
                    483: }
                    484: 
                    485: 
                    486: /*
                    487: ** LOCK the URI indicated by HTAnchor *dst using the informations
                    488: ** in xmlbody string. 
                    489: */ 
                    490: PUBLIC BOOL HTLOCKAnchor (HTRequest * request,
                    491:                           HTAnchor * dst,
                    492:                           char * xmlbody,
                    493:                           HTDAVHeaders * headers) {
                    494: 
                    495:     if (request && dst) {
                    496:         HTParentAnchor * src = NULL;
                    497:         if (xmlbody) {
                    498:             src = HTTmpAnchor(NULL);
                    499:             HTAnchor_setDocument(src, xmlbody);
                    500:             HTAnchor_setFormat(src, HTAtom_for ("text/xml"));
                    501:             HTAnchor_setLength(src, strlen(xmlbody));
                    502:         }
                    503:         return (HTLOCKDocumentAnchor (request,dst,src,headers));
                    504:     }
                    505:     return NO;
                    506: }
                    507: 
                    508: 
                    509: /*
                    510: ** LOCK the resource indicated by an absolute URI, using the informations
                    511: ** in xmlbody string.
                    512: */ 
                    513: PUBLIC BOOL HTLOCKAbsolute (HTRequest * request,
                    514:                             const char * uri,
                    515:                             char * xmlbody,
                    516:                             HTDAVHeaders * headers){
                    517:     if (request && uri && *uri) {
                    518:         HTAnchor *dst = HTAnchor_findAddress (uri);
                    519:         HTParentAnchor *src = NULL;
                    520: 
                    521:         if (xmlbody) {
                    522:             src = HTTmpAnchor(NULL);
                    523:             HTAnchor_setDocument(src, xmlbody);
                    524:             HTAnchor_setFormat(src, HTAtom_for ("text/xml"));
                    525:             HTAnchor_setLength(src, strlen(xmlbody));
                    526:         }
                    527:  
                    528:         return (HTLOCKDocumentAnchor (request,dst,src,headers));
                    529:     }
                    530:     return NO;
                    531: }
                    532: 
                    533: 
                    534: /*
                    535: ** LOCK the resource indicated by a relative URI, which is made
                    536: ** absolute by using the base anchor.
                    537: */
                    538: PUBLIC BOOL HTLOCKRelative (HTRequest * request,
                    539:                             const char * relative,
                    540:                             HTParentAnchor * base,
                    541:                             char * xmlbody,
                    542:                             HTDAVHeaders * headers){
                    543:     BOOL status = NO;
                    544:     if (request && relative && base) {
                    545:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
                    546:          char * full_uri = HTParse(relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
                    547:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                    548: 
                    549:          status = HTLOCKAbsolute (request,full_uri,xmlbody,headers);
                    550:          HT_FREE (full_uri);
                    551:          HT_FREE (base_uri);
                    552:     }
                    553:     return status;
                    554: }
                    555: 
                    556: 
                    557: /* --------------------------------------------------------------------------*/
                    558: /*                            UNLOCK REQUESTS                                */
                    559: /* --------------------------------------------------------------------------*/
                    560: 
                    561: /*
                    562: ** UNLOCK REQUEST
                    563: **
                    564: ** UNLOCK request removes the lock identified by Lock-Token header from
                    565: ** the Request-URI.
                    566: ** Headers:
1.3     ! kirschpi  567: **      Lock-Token header must be present
1.1       kirschpi  568: */
                    569: PUBLIC BOOL HTUNLOCKAnchor (HTRequest * request,
                    570:                             HTAnchor * dst,
                    571:                             HTDAVHeaders * headers) {
                    572:     if (request && dst) {
                    573:         /* set method and request-uri */
                    574:         HTRequest_setMethod (request,METHOD_UNLOCK);
                    575:         HTRequest_setAnchor (request,dst);
                    576:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to UNLOCK\n");
                    577: 
                    578:         /* set headers */
                    579:         HTTRACE (PROT_TRACE,"HTDAV.... Setting default Headers \n");
                    580:         HTRequest_addCacheControl (request, "no-cache","");
                    581:         HTRequest_addEnHd (request,HT_E_CONTENT_ENCODING);
                    582:         HTRequest_addEnHd (request,HT_E_CONTENT_LENGTH);
                    583:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                    584:  
                    585:         if (headers && headers->LockToken) {
                    586:             HTTRACE (PROT_TRACE,"HTDAV.... Seting Lock-Token \n");
                    587:             if (headers->LockToken == NULL) {
                    588:                 HTTRACE (PROT_TRACE,"HTDAV.... FAILED Lock-Token is NULL\n");
                    589:                 return NO;
                    590:             }
                    591:             HTRequest_addExtraHeader (request,"Lock-Token",headers->LockToken);
                    592: 
                    593:             return HTLoad (request,NO);
                    594:         }
                    595:     }
                    596:     return NO;
                    597: }
                    598: 
                    599: 
                    600: /*
                    601: ** UNLOCK the resource indicated by an absolute URI, using the lock tocken
                    602: ** defined in HTDAVHeaders * headers parameter.
                    603: */
                    604: PUBLIC BOOL HTUNLOCKAbsolute (HTRequest * request,
                    605:                               const char * uri,
                    606:                               HTDAVHeaders * headers) {
                    607:  
                    608:     if (request && uri && *uri) {
                    609:         HTAnchor *dst = HTAnchor_findAddress (uri);
                    610:         return HTUNLOCKAnchor (request,dst,headers);
                    611:     }
                    612:     return NO;
                    613: }
                    614: 
                    615: 
                    616: /*
                    617: ** UNLOCK the resource indicated by a relative URI, which is made
                    618: ** absolute by using the base anchor.
                    619: */
                    620: PUBLIC BOOL HTUNLOCKRelative (HTRequest * request,
                    621:                               const char * relative,
                    622:                               HTParentAnchor * base,
                    623:                               HTDAVHeaders * headers) {
                    624:     BOOL status = NO;
                    625:     if (request && relative && base) {
                    626:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
1.3     ! kirschpi  627:          char * full_uri = HTParse (relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
1.1       kirschpi  628:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                    629: 
                    630:          status = HTUNLOCKAbsolute (request,full_uri,headers);
                    631:          HT_FREE (full_uri);
                    632:          HT_FREE (base_uri);
                    633:     }
                    634:     return status;
                    635: }
                    636: 
                    637: 
                    638: /* --------------------------------------------------------------------------*/
                    639: /*                            PROPFIND REQUESTS                              */
                    640: /* --------------------------------------------------------------------------*/
                    641: 
                    642: 
                    643: /*
                    644: ** PROPFIND Requests
                    645: ** PROPFIND requests returns properties defined for the resource.
                    646: ** The request may contain xml message body with a "propfind" element,
                    647: ** which may include an "allprop" element (to get all properties), a
                    648: ** "propname" element (the name of all properties defined), and a "prop"
                    649: ** element containing the desired properties.
                    650: ** Headers:
1.3     ! kirschpi  651: **      Depth header may be "0", "1" or "infinity".
1.1       kirschpi  652: */
                    653: PUBLIC BOOL HTPROPFINDDocumentAnchor (HTRequest * request,
                    654:                                       HTAnchor * dst,
                    655:                                       HTParentAnchor * xmlbody,
                    656:                                       HTDAVHeaders * headers) {
                    657:  
                    658:     if (request && dst) {
                    659:         /* set method and request-URI */
                    660:         HTRequest_setMethod (request,METHOD_PROPFIND);
                    661:         HTRequest_setAnchor (request,dst);
                    662:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to PROPFIND\n");
                    663:  
                    664:         /* set headers */
                    665:         HTTRACE (PROT_TRACE,"HTDAV.... Seting default Headers \n");
                    666:         HTRequest_addCacheControl (request,"no-cache","");
                    667:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                    668:  
                    669:         if (headers) { /* WebDAV specific headers */
                    670:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV headers \n");
                    671:             if (headers->Depth) /* only Depth header may be used */
                    672:                 if (!strcasecomp(headers->Depth,"0") || /* values 0, 1 */
                    673:                     !strcasecomp(headers->Depth,"1") || /* or infinity */
                    674:                     !strcasecomp(headers->Depth,"infinity"))
                    675:                         HTRequest_addExtraHeader(request,"Depth",headers->Depth);
                    676:         }
                    677: 
                    678:         /* set body - if there is a body */
                    679:         if (xmlbody) {
                    680:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV Entity Request Body \n");
                    681:             HTRequest_setEntityAnchor (request,xmlbody); 
                    682:             HTRequest_setPostCallback (request, HTEntity_callback);
                    683:         }
                    684: 
                    685:         return HTLoad (request,NO);
                    686:     }
                    687: 
                    688:     return NO;
                    689: }
                    690: 
                    691: 
                    692: 
                    693: PUBLIC BOOL HTPROPFINDAnchor (HTRequest * request,
                    694:                               HTAnchor * dst,
                    695:                               const char * xmlbody,
                    696:                               HTDAVHeaders * headers) {
                    697:     if (request && dst) {
                    698:         HTParentAnchor * body = NULL;
                    699:         if (xmlbody) {    
                    700:             body = HTTmpAnchor(NULL);
                    701:             HTAnchor_setDocument(body, (void *)xmlbody);
                    702:             HTAnchor_setFormat(body, HTAtom_for ("text/xml"));
                    703:             HTAnchor_setLength(body, strlen(xmlbody));        
                    704:         }
                    705:         return HTPROPFINDDocumentAnchor (request,dst,body,headers);
                    706:     }
                    707: 
                    708:     return NO;
                    709: }
                    710: 
                    711: 
                    712: /*
                    713: ** This PROPFIND request returns the properties of the resource 
                    714: ** indicated by the absolute URI (parameter uri). 
                    715: */
                    716: PUBLIC BOOL HTPROPFINDAbsolute (HTRequest * request,
                    717:                                 const char * uri,
                    718:                                 const char * xmlbody,
                    719:                                 HTDAVHeaders * headers) {
                    720:     if (request && uri && *uri) {
                    721:         HTAnchor *dst = HTAnchor_findAddress (uri);
                    722:         return HTPROPFINDAnchor (request,dst,xmlbody,headers);
                    723:     }
                    724:     return NO;
                    725: }
                    726: 
                    727: 
                    728: /*
                    729: ** This PROPFIND request returns the properties of the resource 
                    730: ** indicated by a relative URI, which is made absolute by using 
                    731: ** the base anchor.
                    732: */
                    733: PUBLIC BOOL HTPROPFINDRelative (HTRequest * request, 
                    734:                                 const char * relative,
                    735:                                 HTParentAnchor * base,
                    736:                                 const char * xmlbody,
                    737:                                 HTDAVHeaders * headers) {
                    738:     BOOL status = NO;
                    739:     if (request && relative && base) {
                    740:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
                    741:          char * full_uri = HTParse(relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
                    742:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                    743: 
                    744:          status = HTPROPFINDAbsolute (request,full_uri,xmlbody,headers);
                    745:          HT_FREE (full_uri);
                    746:          HT_FREE (base_uri);
                    747:     }
                    748:     return status;
                    749: }
                    750: 
                    751: 
                    752: 
                    753: /* --------------------------------------------------------------------------*/
                    754: /*                            PROPPATCH REQUESTS                             */
                    755: /* --------------------------------------------------------------------------*/
                    756: 
                    757: 
                    758: /*
                    759: ** PROPPATCH Requests
                    760: ** PROPPATCH requests sets/removes the properties values for the resource.
                    761: ** The request must contain a xml message body with a "propertyupdate" element,
                    762: ** which may include an "set" element (to set the properties value) or
                    763: ** a "remove" element (to remove the properties).
                    764: ** Headers: (the RFC is not very clair about it)
1.3     ! kirschpi  765: **      If header, indicating a state token for the resource.
1.1       kirschpi  766: */
                    767: PUBLIC BOOL HTPROPPATCHDocumentAnchor (HTRequest * request,
                    768:                                       HTAnchor * dst,
                    769:                                       HTParentAnchor * xmlbody,
                    770:                                       HTDAVHeaders * headers) {
1.3     ! kirschpi  771:         
1.1       kirschpi  772:     if (request && dst && xmlbody) {
                    773: 
                    774:         /* set method and request-URI */
                    775:         HTRequest_setMethod (request,METHOD_PROPPATCH);
                    776:         HTRequest_setAnchor (request,dst);
                    777:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to PROPPATCH\n");
                    778: 
                    779:         /* set headers */
                    780:         HTTRACE (PROT_TRACE,"HTDAV.... Seting default Headers \n");
                    781:         HTRequest_addCacheControl (request,"no-cache","");
                    782:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                    783: 
                    784:         if (headers) { /* WebDAV specific headers*/
                    785:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV headers \n");
                    786:             if (headers->If) 
                    787:                 HTRequest_addExtraHeader (request,"If",headers->If);
                    788:         }
                    789: 
                    790:         /* set body - mandatory! */
                    791:         HTTRACE (PROT_TRACE,"HTDAV.... Setting Entity Body \n");
                    792:         HTRequest_setEntityAnchor (request,xmlbody); 
                    793:         HTRequest_setPostCallback (request, HTEntity_callback);
                    794: 
                    795:         return HTLoad (request,NO);
                    796:     }
                    797:     return NO;
                    798:  
                    799: }
                    800: 
                    801: 
                    802:  
                    803: PUBLIC BOOL HTPROPPATCHAnchor (HTRequest * request,
                    804:                                HTAnchor * dst,
                    805:                                const char * xmlbody,
                    806:                                HTDAVHeaders * headers) {
                    807:     if (request && dst && xmlbody) {
                    808:        HTParentAnchor * body = HTTmpAnchor(NULL);
1.3     ! kirschpi  809:        HTAnchor_setDocument (body, (void *)xmlbody);
        !           810:        HTAnchor_setFormat (body, HTAtom_for ("text/xml"));
        !           811:        HTAnchor_setLength (body, strlen(xmlbody));
        !           812:                
1.1       kirschpi  813:        return HTPROPPATCHDocumentAnchor (request,dst,body,headers);
                    814:     }
                    815:     return NO;
                    816: }
                    817: 
                    818: 
                    819: /*
                    820: ** This PROPPATCH request set or removes properties from the resource 
                    821: ** indicated by the absolute URI (parameter uri). 
                    822: */
                    823: PUBLIC BOOL HTPROPPATCHAbsolute (HTRequest * request,
                    824:                                 const char * uri,
                    825:                                 const char * xmlbody,
                    826:                                 HTDAVHeaders * headers) {
                    827:     if (request && uri && *uri && xmlbody && *xmlbody) {
                    828:         HTAnchor *dst = HTAnchor_findAddress (uri);
                    829:         return HTPROPPATCHAnchor (request,dst,xmlbody,headers);
                    830:     }
                    831:     return NO;
                    832: }
                    833: 
                    834: 
                    835: /*
                    836: ** This PROPPATCH request sets/removes the properties from the resource 
                    837: ** indicated by a relative URI, which is made absolute by using 
                    838: ** the base anchor.
                    839: */
                    840: PUBLIC BOOL HTPROPPATCHRelative (HTRequest * request, 
                    841:                                 const char * relative,
                    842:                                 HTParentAnchor * base,
                    843:                                 const char * xmlbody,
                    844:                                 HTDAVHeaders * headers) {
                    845:     BOOL status = NO;
                    846:     if (request && relative && base && xmlbody && *xmlbody) {
                    847:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
1.3     ! kirschpi  848:          char * full_uri = HTParse (relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
1.1       kirschpi  849:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                    850: 
                    851:          status = HTPROPPATCHAbsolute (request,full_uri,xmlbody,headers);
                    852:          HT_FREE (full_uri);
                    853:          HT_FREE (base_uri);
                    854:     }
                    855:     return status;
                    856: }
                    857: 
                    858: 
                    859: /* --------------------------------------------------------------------------*/
                    860: /*                             MKCOL REQUESTS                                */
                    861: /* --------------------------------------------------------------------------*/
                    862: 
                    863: 
                    864: /*
                    865: ** MKCOL Requests
                    866: ** MKCOL requests creates a collection. The resource indicated by HTAnchor *
                    867: ** dst parameter must not be a "non-null" resource, but all it ancestors
                    868: ** must exist.
                    869: ** Headers:
1.3     ! kirschpi  870: **      If header may be used.
1.1       kirschpi  871: */
                    872: PUBLIC BOOL HTMKCOLAnchor (HTRequest * request, 
                    873:                            HTAnchor * dst,
                    874:                            HTDAVHeaders * headers) {
                    875:     if (request && dst) {
                    876:         /* set method and request-URI */
                    877:         HTRequest_setMethod (request,METHOD_MKCOL);
                    878:         HTRequest_setAnchor (request,dst);
                    879:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to MKCOL\n");
                    880:         
                    881:         /* set headers */
                    882:         HTTRACE (PROT_TRACE,"HTDAV.... Seting default Headers \n");
                    883:         HTRequest_addCacheControl (request,"no-cache","");
                    884:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                    885:         
                    886:         if (headers) { /* WebDAV specific headers */
                    887:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV headers \n");
                    888:             if (headers->If) /* only IF header may be used */
1.3     ! kirschpi  889:                 HTRequest_addExtraHeader (request,"If",headers->If);
1.1       kirschpi  890:         }
                    891: 
                    892:         return HTLoad (request,NO);
                    893:     }
                    894: 
                    895:     return NO;
                    896: }
                    897: 
                    898: 
                    899: 
                    900: /*
                    901: ** This MKCOL request tries to create the resource 
                    902: ** indicated by the absolute URI (parameter uri). 
                    903: */
                    904: PUBLIC BOOL HTMKCOLAbsolute (HTRequest * request,
                    905:                              const char * uri,
                    906:                              HTDAVHeaders * headers) {
                    907:     if (request && uri && *uri) {
                    908:         HTAnchor *dst = HTAnchor_findAddress (uri);
                    909:         return HTMKCOLAnchor (request,dst,headers);
                    910:     }
                    911:     return NO;
                    912: }
                    913: 
                    914: 
                    915: /*
                    916: ** This MKCOL request tries to create the resource indicated
                    917: ** by a relative URI, which is made absolute by using the
                    918: ** base anchor.
                    919: */
                    920: PUBLIC BOOL HTMKCOLRelative (HTRequest * request, 
                    921:                              const char * relative,
                    922:                              HTParentAnchor * base,
                    923:                              HTDAVHeaders * headers) {
                    924:     BOOL status = NO;
                    925:     if (request && relative && base) {
                    926:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
1.3     ! kirschpi  927:          char * full_uri = HTParse (relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
1.1       kirschpi  928:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                    929: 
                    930:          status = HTMKCOLAbsolute (request,full_uri,headers);
                    931:          HT_FREE (full_uri);
                    932:          HT_FREE (base_uri);
                    933:     }
                    934:     return status;
                    935: }
                    936: 
                    937: 
                    938: 
                    939: /* --------------------------------------------------------------------------*/
                    940: /*                              COPY REQUESTS                                */
                    941: /* --------------------------------------------------------------------------*/
                    942: 
                    943: 
                    944: /*
                    945: ** COPY Requests
                    946: ** COPY requests copies the Request-URI resource (indicated by the parameter
                    947: ** HTAnchor *src) to the resource indicated by the Destination header (it must
                    948: ** be set in HTDAVHeaders object - so, this object must NOT be NULL).
                    949: ** A xml message body may also be set, with the propertybehavior xml element,
                    950: ** which indicates what should be the server behavior when copying the resouce
                    951: ** properties.
                    952: ** Headers:
1.3     ! kirschpi  953: **      Destination header is mandatory!
        !           954: **      If header may be used.
        !           955: **      Depth header may be "0" or "infinity"
        !           956: **      Overwrite header may be used
1.1       kirschpi  957: */
                    958: PUBLIC BOOL HTCOPYDocumentAnchor (HTRequest * request,
                    959:                                   HTAnchor * src,
                    960:                                   HTParentAnchor * xmlbody,
                    961:                                   HTDAVHeaders * headers) {
1.3     ! kirschpi  962:         
1.1       kirschpi  963:     if (request && src && headers) {
                    964: 
                    965:         /* set method and request-URI */
                    966:         HTRequest_setMethod (request,METHOD_COPY);
                    967:         HTRequest_setAnchor (request,src);
                    968:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to COPY\n");
                    969: 
                    970:         /* set headers */
                    971:         HTTRACE (PROT_TRACE,"HTDAV.... Seting default Headers \n");
                    972:         HTRequest_addCacheControl (request,"no-cache","");
                    973:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                    974: 
                    975:          /* WebDAV specific headers - Destination is mandatory! */
                    976:         if (headers->Destination && *headers->Destination) { 
                    977:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV headers \n");
1.3     ! kirschpi  978:             HTRequest_addExtraHeader (request,"Destination",headers->Destination);
1.1       kirschpi  979: 
                    980:             if (headers->If) /* If header may be used */
1.3     ! kirschpi  981:                 HTRequest_addExtraHeader (request,"If",headers->If);
1.1       kirschpi  982: 
                    983:             if (headers->Overwrite != ' ') {
                    984:                 char over[] = { headers->Overwrite, '\0' };
1.3     ! kirschpi  985:                 HTRequest_addExtraHeader (request,"Overwirte", over );
1.1       kirschpi  986:              }
                    987: 
                    988:             if (headers->Depth) {
1.3     ! kirschpi  989:                 if (!strcasecomp (headers->Depth,"0") || 
        !           990:                     !strcasecomp (headers->Depth,"infinity")) 
        !           991:                       HTRequest_addExtraHeader (request,"Depth",headers->Depth);
1.1       kirschpi  992:             }
                    993:         } 
                    994:         else return NO;
                    995: 
                    996:         /* set body - if there is a body */
                    997:         if (xmlbody) {
                    998:             HTTRACE (PROT_TRACE,"HTDAV.... Setting Entity Body \n");
                    999:             HTRequest_setEntityAnchor (request,xmlbody); 
                   1000:             HTRequest_setPostCallback (request, HTEntity_callback);
                   1001:         }
                   1002:         return HTLoad (request,NO);
                   1003:     }
                   1004: 
                   1005:     return NO;
                   1006: }
                   1007: 
                   1008: 
                   1009: 
                   1010: PUBLIC BOOL HTCOPYAnchor (HTRequest * request, 
                   1011:                            HTAnchor * src,
                   1012:                            const char * xmlbody,
                   1013:                            HTDAVHeaders * headers) {
                   1014:      
                   1015:     if (request && src && headers) {
                   1016:         HTParentAnchor * body = NULL;
                   1017:         if (xmlbody) {
                   1018:             body = HTTmpAnchor(NULL);
1.3     ! kirschpi 1019:             HTAnchor_setDocument (body, (void *)xmlbody);
        !          1020:             HTAnchor_setFormat (body, HTAtom_for ("text/xml"));
        !          1021:             HTAnchor_setLength (body, strlen(xmlbody));
1.1       kirschpi 1022:         }
                   1023:         return HTCOPYDocumentAnchor (request,src,body,headers);  
                   1024:     }
                   1025:     return NO;
                   1026: }
                   1027: 
                   1028: 
                   1029: /*
                   1030: ** This COPY request copies the resource indicated by an absolute URI
                   1031: ** (parameter uri) to the URI in Destination header. 
                   1032: */
                   1033: PUBLIC BOOL HTCOPYAbsolute (HTRequest * request,
                   1034:                             const char * uri,
                   1035:                             const char * xmlbody,
                   1036:                             HTDAVHeaders * headers) {
                   1037:     if (request && uri && *uri && headers) {
                   1038:         HTAnchor *src = HTAnchor_findAddress (uri);
                   1039:         return HTCOPYAnchor (request,src,xmlbody,headers);
                   1040:     }
                   1041:     return NO;
                   1042: }
                   1043: 
                   1044: 
                   1045: /*
                   1046: ** This COPY request copies the resource indicated by a relative URI,
                   1047: ** which is made absolute by using the base anchor. 
                   1048: */
                   1049: PUBLIC BOOL HTCOPYRelative (HTRequest * request, 
                   1050:                                 const char * relative,
                   1051:                                 HTParentAnchor * base,
                   1052:                                 const char * xmlbody,
                   1053:                                 HTDAVHeaders * headers) {
                   1054:     BOOL status = NO;
                   1055:     if (request && relative && base && headers) {
                   1056:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
1.3     ! kirschpi 1057:          char * full_uri = HTParse (relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
1.1       kirschpi 1058:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                   1059: 
                   1060:          status = HTCOPYAbsolute (request,full_uri,xmlbody,headers);
                   1061:          HT_FREE (full_uri);
                   1062:          HT_FREE (base_uri);
                   1063:     }
                   1064:     return status;
                   1065: }
                   1066: 
                   1067: 
                   1068: 
                   1069: /* --------------------------------------------------------------------------*/
                   1070: /*                              MOVE REQUESTS                                */
                   1071: /* --------------------------------------------------------------------------*/
                   1072: 
                   1073: 
                   1074: /*
                   1075: ** MOVE Requests
                   1076: ** MOVE requests moves the Request-URI resource (indicated by the parameter
                   1077: ** HTAnchor *src) to the resource indicated by the Destination header (it must
                   1078: ** be set in HTDAVHeaders object - so, this object must NOT be NULL).
                   1079: ** A xml message body may also be set, with the propertybehavior xml element,
                   1080: ** which indicates what should be the server behavior when copying the resouce
                   1081: ** properties.
                   1082: ** Headers:
1.3     ! kirschpi 1083: **      Destination header is mandatory!
        !          1084: **      If header may be used.
        !          1085: **      Depth header may be "0" or "infinity" (for collections, it MUST be "infinity")
        !          1086: **      Overwrite header may be used
1.1       kirschpi 1087: */
                   1088: PUBLIC BOOL HTMOVEDocumentAnchor (HTRequest * request,
                   1089:                                   HTAnchor * src,
                   1090:                                   HTParentAnchor * xmlbody,
                   1091:                                   HTDAVHeaders * headers) {
                   1092: 
                   1093:     if (request && src && headers) {
                   1094: 
                   1095:         /* set method and request-URI */
                   1096:         HTRequest_setMethod (request,METHOD_MOVE);
                   1097:         HTRequest_setAnchor (request,src);
                   1098:         HTTRACE (PROT_TRACE,"HTDAV.... Method set to MOVE\n");
                   1099: 
                   1100:         /* set headers */
                   1101:         HTTRACE (PROT_TRACE,"HTDAV.... Seting default Headers \n");
                   1102:         HTRequest_addCacheControl (request,"no-cache","");
                   1103:         HTRequest_addGnHd (request,HT_G_PRAGMA_NO_CACHE);
                   1104: 
                   1105:          /* WebDAV specific headers - Destination is mandatory! */
                   1106:         if (headers->Destination && *headers->Destination) { 
                   1107:             HTTRACE (PROT_TRACE,"HTDAV.... Setting WebDAV headers \n");
1.3     ! kirschpi 1108:             HTRequest_addExtraHeader (request,"Destination",headers->Destination);
1.1       kirschpi 1109: 
                   1110:             if (headers->If) /* If header may be used */
1.3     ! kirschpi 1111:                 HTRequest_addExtraHeader (request,"If",headers->If);
1.1       kirschpi 1112: 
                   1113:             if (headers->Overwrite != ' ') {
                   1114:                 char over[] = { headers->Overwrite, '\0' };
1.3     ! kirschpi 1115:                 HTRequest_addExtraHeader (request,"Overwirte", over );
1.1       kirschpi 1116:              }
                   1117: 
1.3     ! kirschpi 1118:             if (headers->Depth) {
        !          1119:                 if (!strcasecomp (headers->Depth,"0") || 
        !          1120:                     !strcasecomp (headers->Depth,"infinity")) 
1.1       kirschpi 1121:                      HTRequest_addExtraHeader(request,"Depth",headers->Depth);
                   1122:             }
                   1123:         } 
                   1124:         else return NO;
                   1125:         
                   1126:         /* set body - if there is a body */
                   1127:         if (xmlbody) {
                   1128:             HTTRACE (PROT_TRACE,"HTDAV.... Setting Entity Body \n");
                   1129:             HTRequest_setEntityAnchor (request,xmlbody); 
1.3     ! kirschpi 1130:             HTRequest_setPostCallback (request,HTEntity_callback);              
        !          1131:         }       
1.1       kirschpi 1132:         return HTLoad (request,NO);
                   1133:     }
                   1134: 
1.3     ! kirschpi 1135:     return NO;  
1.1       kirschpi 1136: }
                   1137: 
                   1138: 
                   1139: 
                   1140: PUBLIC BOOL HTMOVEAnchor (HTRequest * request, 
                   1141:                           HTAnchor * src,
                   1142:                           const char * xmlbody,
                   1143:                           HTDAVHeaders * headers) {
                   1144:  
                   1145:     if (request && src && headers) {
                   1146:         HTParentAnchor * body = NULL;
                   1147:         if (xmlbody) {
1.3     ! kirschpi 1148:             body = HTTmpAnchor (NULL);
1.1       kirschpi 1149:             HTAnchor_setDocument(body, (void *) xmlbody);
1.3     ! kirschpi 1150:             HTAnchor_setFormat (body, HTAtom_for ("text/xml"));
        !          1151:             HTAnchor_setLength (body, strlen(xmlbody));
1.1       kirschpi 1152:         }    
                   1153:         return HTMOVEDocumentAnchor (request,src,body,headers);
                   1154:     }
                   1155:     return NO;
                   1156: }
                   1157: 
                   1158: 
                   1159: /*
                   1160: ** This MOVE request moves the resource indicated by an absolute URI
                   1161: ** (parameter uri) to the URI in Destination header. 
                   1162: */
                   1163: PUBLIC BOOL HTMOVEAbsolute (HTRequest * request,
                   1164:                             const char * uri,
                   1165:                             const char * xmlbody,
                   1166:                             HTDAVHeaders * headers) {
                   1167:     if (request && uri && *uri && headers) {
                   1168:         HTAnchor *src = HTAnchor_findAddress (uri);
                   1169:         return HTMOVEAnchor (request,src,xmlbody,headers);
                   1170:     }
                   1171:     return NO;
                   1172: }
                   1173: 
                   1174: 
                   1175: /*
                   1176: ** This MOVE request moves the resource indicated by a relative URI,
                   1177: ** which is made absolute by using the base anchor. 
                   1178: */
                   1179: PUBLIC BOOL HTMOVERelative (HTRequest * request, 
                   1180:                             const char * relative,
                   1181:                             HTParentAnchor * base,
                   1182:                             const char * xmlbody,
                   1183:                             HTDAVHeaders * headers) {
                   1184:     BOOL status = NO;
                   1185:     if (request && relative && base && headers) {
                   1186:          char * base_uri = HTAnchor_address ((HTAnchor *)base);
1.3     ! kirschpi 1187:          char * full_uri = HTParse (relative,base_uri,PARSE_ACCESS|PARSE_HOST| \
1.1       kirschpi 1188:                                                  PARSE_PATH|PARSE_PUNCTUATION);
                   1189: 
                   1190:          status = HTMOVEAbsolute (request,full_uri,xmlbody,headers);
                   1191:          HT_FREE (full_uri);
                   1192:          HT_FREE (base_uri);
                   1193:     }
                   1194:     return status;
                   1195: }
                   1196: 
                   1197: 
                   1198: #endif /* HT_DAV */

Webmaster