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

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

Webmaster