示例#1
0
int handle_http_proppatch(http_req * req, http_rsp * rsp)
{
    HashElement * e = NULL;
    char * propxml = NULL;
    int contentlen = 0;
    char * vpath = req->uri;

    WEBLOG_API();

#ifdef WEBCFG_SUPPORT_AUTH
    /* Authentication has a very high priority. */
    if (OK != CheckAuthorization(req, rsp))
    {
        return handle_http_error(401, req, rsp);
    }
#endif

    if(OK != Webdav_CheckPath(req->uri))
    {
        WEBLOG_ERROR("<%s> PROPFIND is not allowed for non-webdav path [%s].\n", __FUNCTION__, req->uri);
        return handle_http_error(403, req, rsp);
    }

    if(0 == strlen(vpath))
    {
        strcat(vpath, "/");
        WEBLOG_VERBOSE("<%s> redirect to root path. [%s].\n", __FUNCTION__, vpath);
    }

#ifdef WEBCFG_MINIMIZE_SERVER
#else
    if(OK != Webdav_CheckPath(req->uri))
    {
        WEBLOG_ERROR("<%s> PROPFIND is not allowed for non-webdav path [%s].\n", __FUNCTION__, req->uri);
        return handle_http_error(403, req, rsp);
    }


    e = HashLookup(req->headOptions, "Content-Type");
    if(e && strstr(e->value.data.string, "xml"))
    {
        char * xmlsockbuf = NULL;
        char * p = NULL;

        WEBLOG_INFO("<%s> Client provide props value in a xml body.\n", __FUNCTION__);

        e = HashLookup(req->headOptions, "Content-Length");
        if(!e)
        {
            /* RFC2616, 14.23. */
            WEBLOG_ERROR("<%s> Missing \"Content-Length\" for xml body.\n", __FUNCTION__);
            return handle_http_error(400, req, rsp);
        }
        contentlen = atoi(e->value.data.string);

        xmlsockbuf = (char *)webmalloc(contentlen+1);
        memset(xmlsockbuf, 0, contentlen+1);

        if(req->datalen > 0) // data left in head buffer.
        {
            memcpy(xmlsockbuf, req->sockbuf, req->datalen);
            WEBLOG_VERBOSE("<%s> previous buffered %d/%d bytes consumed.\n",
                           __FUNCTION__, req->datalen, contentlen);
        }
        /* if there's more data in socket.... */
        if (req->datalen < contentlen)
        {
            /* read rest of data from socket. */
            p = xmlsockbuf + req->datalen;
            req->datalen = recv(req->sock, p, contentlen-req->datalen, 0);
            WEBLOG_VERBOSE("<%s> %d/%d bytes read from socket.\n",
                           __FUNCTION__, req->datalen, contentlen);
            dumpText(xmlsockbuf, contentlen);
        }

    }

#endif

    return handle_http_error(501, req, rsp);
}
示例#2
0
int handle_http_propfind(http_req * req, http_rsp * rsp)
{
    int ret = OK;
    HashElement * e = NULL;
    int depth = -1;
    HashHandle props = NULL_HANDLE;
    CacheHandle cache = NULL_HANDLE;
    char * propxml = NULL;
    int contentlen = 0;
    char * vpath = req->uri;
    struct stat buf;

    WEBLOG_API();

#ifdef WEBCFG_SUPPORT_AUTH
    /* Authentication has a very high priority. */
    if (OK != CheckAuthorization(req, rsp))
    {
        return handle_http_error(401, req, rsp);
    }
#endif

    if(OK != Webdav_CheckPath(req->uri))
    {
        WEBLOG_ERROR("<%s> PROPFIND is not allowed for non-webdav path [%s].\n", __FUNCTION__, req->uri);
        handle_http_error(403, req, rsp);
        ret = NG;
        goto __error_out;
    }

    if(0 == strlen(vpath))
    {
        strcat(vpath, "/");
        WEBLOG_VERBOSE("<%s> redirect to root path. [%s].\n", __FUNCTION__, vpath);
    }

    WEBLOG_INFO("<%s> stat the file \"%s\".\n", __FUNCTION__, vpath);
    ret = stat(vpath, &buf);

    /* Check if statistics are valid: */
    if(ret != 0)
    {
        WEBLOG_ERROR("<%s> fail to stat the file \"%s\".\n", __FUNCTION__, vpath);
        switch (errno)
        {
            case ENOENT:
                WEBLOG_ERROR("<%s> File %s not found.\n", __FUNCTION__, vpath);
                handle_http_error(404, req, rsp);
                ret = NG;
                goto __error_out;

            case EINVAL: /* no break */
            default:
                /* Should never be reached. */
                WEBLOG_ERROR("<%s> Unexpected error in _stat.\n", __FUNCTION__);
                handle_http_error(500, req, rsp);
                ret = NG;
                goto __error_out;
        }
    }


    props = HashTableCreate(64);
    ASSERT(props != NULL_HANDLE);

    /* get depth. */
    e = HashLookup(req->headOptions, "Depth");
    if(!e) depth = -1;
    else if(e->value.data.string[0] == '0') depth = 0;
    else if(e->value.data.string[0] == '1') depth = 1;
    else depth = -1;

    if(depth == -1 && TRUE == Webdav_isFolder(vpath))
    {
        WEBLOG_ERROR("<%s> PROPFIND a collection with infinite depth is not allowed.\n", __FUNCTION__);
        handle_http_error(403, req, rsp);
        ret = NG;
        goto __error_out;
    }

#ifdef WEBCFG_MINIMIZE_SERVER
#else
    e = HashLookup(req->headOptions, "Content-Type");
    if(e && strstr(e->value.data.string, "xml"))
    {
        char * xmlsockbuf = NULL;
        char strbuf[128] = {0};
        char *end, *p, *q;
        HashValue eeee = HashString("", FALSE); // empty value!

        WEBLOG_INFO("<%s> Client request props in a xml body.\n", __FUNCTION__);

        e = HashLookup(req->headOptions, "Content-Length");
        if(!e)
        {
            /* RFC2616, 14.23. */
            WEBLOG_ERROR("<%s> Missing \"Content-Length\" for xml body.\n", __FUNCTION__);
            handle_http_error(400, req, rsp);
            ret = NG;
            goto __error_out;
        }
        contentlen = atoi(e->value.data.string);

        xmlsockbuf = (char *)webmalloc(contentlen+1);
        memset(xmlsockbuf, 0, contentlen+1);

        if(req->datalen > 0) // data left in head buffer.
        {
            memcpy(xmlsockbuf, req->sockbuf, req->datalen);
            WEBLOG_VERBOSE("<%s> previous buffered %d/%d bytes consumed.\n",
                           __FUNCTION__, req->datalen, contentlen);
        }
        /* if there's more data in socket.... */
        if (req->datalen < contentlen)
        {
            /* read rest of data from socket. */
            p = xmlsockbuf + req->datalen;
            req->datalen = recv(req->sock, p, contentlen-req->datalen, 0);
            WEBLOG_VERBOSE("<%s> %d/%d bytes read from socket.\n",
                           __FUNCTION__, req->datalen, contentlen);
            dumpText(xmlsockbuf, contentlen);
        }

        p = strstr(xmlsockbuf, "<prop>") + 6;
        end = strstr(xmlsockbuf, "</prop>");

        if(strstr(xmlsockbuf, "<allprop/>"))
        {
            WEBLOG_INFO("<%s> client request all props.\n", __FUNCTION__);
        }
        else
        {
            ASSERT(p<end);
            *end = '\0'; /* good for str api. */

            /* Possible Value:
            WinXP: <propname/>
            Cadaver: <propname xmlns="DAV:"/>
            */
            do
            {
                p = strchr(p, '<');
                if(!p) break;
                else p++;
                q = strstr(p, "/>");
                ASSERT(q && (q-p < sizeof(strbuf)));

                strncpy(strbuf, p, q-p);
                p = strchr(strbuf, ' ');
                if(p) *p = '\0';
                p = strtrim(strbuf);

                WEBLOG_INFO("<%s> client request prop: <%s>\n", __FUNCTION__, p);
                HashAdd(props, p, eeee);
                p = q + 2;
            }
            while(p<end); /* <xxx/>\r\n</prop> */
        }
    }

#endif

    cache = CacheCreate();
    Webdav_Props(props, cache, vpath, depth);
    contentlen = CacheGetData(cache, &propxml);
    ASSERT(propxml);
    dumpText(propxml, contentlen);
    WEBLOG_INFO("<%s> response xml ready. len %d.\n", __FUNCTION__, contentlen);

    rsp->code = 207;
    rsp->body = propxml;
    http_add_rspoption(rsp, "Content-Type", "text/xml");
    http_send_response(rsp);

__error_out:

    if (props != NULL_HANDLE) HashTableDestroy(props);
    if (cache != NULL_HANDLE) CacheDestroy(cache);
    return ret;
}
示例#3
0
 mce_match_element(reader, NULL, NULL) {
     dumpText(ctx, reader, level, textMode, parMode, cellMode, rowMode, prop_mode);
 }