示例#1
0
int handle_http_delete(http_req * req, http_rsp * rsp)
{
    char * vpath = NULL;
    int ret = 0;

    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

    vpath = req->uri;
    ASSERT(vpath && vpath[0]);

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

    if(OK != Webdav_CheckPath(vpath))
    {
        return handle_http_error(403, req, rsp);
    }

    /* Note that the path can be either a folder, or a file.
    If it is a folder, it can be either empty, or with files.
    */
    if(TRUE == Webdav_isFolder(vpath))
        ret = Webdav_DeleteFolder(vpath);
    else
        ret = Webdav_DeleteFile(vpath);

    if(WEBDAVR_OK == ret)
    {
        rsp->code = 204;
        return http_send_response(rsp);
    }
    else
    {
        WEBLOG_INFO("<%s> Failed to remove %s.\n", __FUNCTION__, vpath);
        return handle_http_error(403, req, rsp);
    }
}
示例#2
0
DWORD WINAPI http_do_request(void *lPtr)
{
	socket_conn* conn = (socket_conn*)lPtr;
	if(conn == 0)
		return 0;

	printf("[%08x]new connection\n", GetCurrentThreadId());
	while(1)
	{
		int keepalive = 0;
		dynamic_object * req = dynamic_create();
		if(http_read_request(conn, req) == 0)
		{
			dynamic_delete(req);
			break;
		}
		char* path = dynamic_get_string(dynamic_map_find(req, "PATH"));
		char* method = dynamic_get_string(dynamic_map_find(req, "METHOD"));
		char* connection = dynamic_get_string(dynamic_map_find(req, HTTP_HEADER_CONNECTION));
		if(connection && strcmp(connection, "keep-alive")==0)
			keepalive = 1;
		printf("[%08x]%s %s\n", GetCurrentThreadId(), method, path);

		if(strcmp(path, "/hello") == 0)
		{
			char* html = "<html><body>Hello World!</body></html>";
			int htmllen = strlen(html);
			dynamic_object * res = dynamic_create();
			dynamic_string_printf(dynamic_map_insert(res, HTTP_HEADER_CONTENT_LENGTH), "%d", htmllen);
			dynamic_set_string(dynamic_map_insert(res, HTTP_HEADER_CONTENT_TYPE), "text/html");

			http_send_response(conn, 200, res);
			write_socket(conn, html, htmllen, -1);
			dynamic_delete(res);
		}else
		{
			http_send_file(conn, req);
		}
		dynamic_delete(req);
		if(keepalive == 0)
			break;
	}

	close_socket(conn);
	printf("[%08x]close connection\n", GetCurrentThreadId());
	return 0;
}
示例#3
0
/*
 * Handles an HTTP error.
 */
void http_error(socket_t s, unsigned http_code,
    const struct http_request_s *request)
{
    const char *content_filename;
    switch (http_code)
    {
        case 404:
            content_filename = "404.html";
            break;
        case 500:
            content_filename = "500.html";
            break;
        default:
            panic("unsupported HTTP code %u", http_code);
    }

    if (http_type(request->name) == HTTP_TYPE_HTML)
    {
        http_buffer_t content = http_lookup_content(content_filename);
        if (content != NULL)
        {
            if (http_send_response(s, http_code, content, request))
            {
                http_buffer_close(content);
                return;
            }
            http_buffer_close(content);
        }
    }

    // Emergency fall back:
    static const char http_header[] =
        "HTTP/1.1 500 Internal Server Error\r\n"
        "Connection: close\r\n"
        "\r\n";
    size_t http_header_length = sizeof(http_header)-1;
    if (send(s, http_header, http_header_length, 0) != http_header_length)
    {
        warning("unable to send HTTP 500 response of size " SIZE_T_FMT
            " bytes", http_header_length);
    }
}
示例#4
0
int handle_http_error(int errcode, http_req * req, http_rsp * rsp)
{
    char buffer[256]    = {0};
    http_status * stt   = get_http_status(errcode);

    WEBLOG_API();
    ASSERT(stt);

    sprintf(buffer, "<HTML><BODY><b>%s</b></BODY></HTML>", stt->s_name);

    rsp->code = errcode;
    rsp->body = buffer;
    http_add_rspoption(rsp, "Content-Type", "text/html");
    http_add_rspoption(rsp, "Connection", "close");

    WEBLOG_INFO("\n<%s> Response >>>>>>>>>>>\n", __FUNCTION__);
    http_send_response(rsp);
    WEBLOG_INFO("\n<%s> Response <<<<<<<<<<<\n", __FUNCTION__);
    return NG;  /* Allways return NG here. */
}
示例#5
0
static void error(struct http_response *rs,
                  enum pazpar2_error_code code,
                  const char *addinfo)
{
    struct http_channel *c = rs->channel;
    WRBUF text = wrbuf_alloc();
    const char *http_status = "417";
    const char *msg = get_msg(code);

    rs->msg = nmem_strdup(c->nmem, msg);
    strcpy(rs->code, http_status);

    wrbuf_printf(text, HTTP_COMMAND_RESPONSE_PREFIX "<error code=\"%d\" msg=\"%s\">", (int) code,
                 msg);
    if (addinfo)
        wrbuf_xmlputs(text, addinfo);
    wrbuf_puts(text, "</error>");

    yaz_log(YLOG_WARN, "HTTP %s %s%s%s", http_status,
            msg, addinfo ? ": " : "" , addinfo ? addinfo : "");
    rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(text));
    wrbuf_destroy(text);
    http_send_response(c);
}
示例#6
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;
}
示例#7
0
int handle_http_put(http_req * req, http_rsp * rsp)
{
    HashElement * e = NULL;
    char * vpath = NULL;
    int httpbodylen = 0;
    int readlen = 0;
    FILE * fp = NULL;
    int i = 0;
    unsigned char * buffer = NULL;
    int buflen = 1024*1024;
    char strbuf[128] = {0};

    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

    vpath = req->uri;
    ASSERT(vpath && vpath[0]);

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

    e = HashLookup(req->headOptions, "Content-Length");
    if(!e)
    {
        /* RFC2616, 14.23. */
        WEBLOG_ERROR("<%s> Missing \"Content-Length\" in POST/PUT.\n", __FUNCTION__);
        return handle_http_error(400, req, rsp);
    }
    httpbodylen = atoi(e->value.data.string);
    WEBLOG_INFO("<%s> Content-Length:%d.\n", __FUNCTION__, httpbodylen);

    if(OK != Webdav_CheckPath(vpath))
        return handle_http_error(501, req, rsp);

    if(WEBDAVR_OK != Webdav_CreateFile(vpath))
        return handle_http_error(501, req, rsp);

    /* read data from socket and save it into target file. */
    fp = fopen(vpath, "wb");
    if(!fp)
        return handle_http_error(501, req, rsp);

    if(req->datalen > 0) // data left in head buffer.
    {
        i = fwrite(req->sockbuf, 1, req->datalen, fp);
        ASSERT(i == req->datalen);
        WEBLOG_VERBOSE("<%s> write previous buffered %d bytes into %s.\n",
                       __FUNCTION__, req->datalen, vpath);
        readlen += req->datalen;
    }

    /* if there's more data in socket....
    req->sockbuf is too small for large files.
    */
    do
    {
        buflen /= 2;
        buffer = (char *)webmalloc(buflen);
    }
    while(!buffer);

    while(readlen < httpbodylen)
    {
        req->datalen = recv(req->sock, buffer, buflen, 0);
        if(req->datalen < 0)
        {
            print_socket_error();
            break;
        }
        else if(req->datalen == 0)
        {
            WEBLOG_INFO("<%s> client closed. data progress: %d/%d.\n",
                        __FUNCTION__, readlen, httpbodylen);
            break;
        }
        readlen += req->datalen;
        WEBLOG_VERBOSE("<%s> progress: %10d/%d, ", __FUNCTION__, readlen, httpbodylen);
        i = fwrite(buffer, 1, req->datalen, fp);
        WEBLOG_VERBOSE("R %d <- socket, W %d -> %s.\n", req->datalen, i, vpath);
        ASSERT(i == req->datalen);
    }

    rsp->code = 201;
    e = HashLookup(req->headOptions, "Host");
    if(!e)
    {
        /* RFC2616, 14.23. */
        WEBLOG_ERROR("<%s> Missing \"Host\" in POST/PUT.\n", __FUNCTION__);
        sprintf(strbuf, "/webdav%s", vpath);
    }
    else
    {
        sprintf(strbuf, "http://%s/webdav%s", e->value.data.string, vpath);
    }
    http_add_rspoption(rsp, "Location", strbuf);
    http_send_response(rsp);

    /******************************
    Double Confirm File Size!
    *******************************/

    fseek(fp, 0, SEEK_END);
    i = ftell(fp);
    WEBLOG_INFO("<%s> Double Confirm. file-size: %d. content-length: %d.\n",
                __FUNCTION__, i, httpbodylen);
    ASSERT(i == httpbodylen);

    webfree(buffer);
    fclose(fp);
    return OK;
}
示例#8
0
int handle_http_get(http_req * req, http_rsp * rsp)
{
    int ret           = OK;
    HashElement * e     = NULL;
    /* ------------------------------------ */
    FILE * fp           = NULL;
    char * timebuf      = NULL;
    /* ------------------------------------ */
    size_t total_length = 0;    /* total length of the file. */
    size_t task_length  = 0;    /* requested length. */
    char   strbuf[64]   = {0};
    size_t from         = -1;
    size_t to           = -1;
    char   path[256]    = {0};
    char * vpath        = path;
    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

    vpath = req->uri;
    ASSERT(vpath && vpath[0]);
    ASSERT(rsp->headOptions != NULL_HANDLE);

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

    /* Make sure the requesting URI is authorized. */
    if(strstr(vpath, "..") || strstr(vpath, "./"))
        return handle_http_error(403, req, rsp);

    /* Check if the requesting URI is a directory. */
    WEBLOG_INFO("<%s> stat the file \"%s\".\n", __FUNCTION__, vpath);
    ret = web_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);
                return handle_http_error(404, req, rsp);

            case EINVAL: /* no break */
            default:
                /* Should never be reached. */
                WEBLOG_ERROR("<%s> Unexpected error in _stat.\n", __FUNCTION__);
                return handle_http_error(500, req, rsp);
        }
    }
    else
    {
        WEBLOG_INFO("<%s> File size     : "sizett"\n", __FUNCTION__, buf.st_size );
        //WEBLOG_INFO("<%s> Drive         : %c:\n", __FUNCTION__, buf.st_dev + 'A' );
        timebuf = ctime(&buf.st_mtime);
        WEBLOG_INFO("<%s> Time modified : %s", __FUNCTION__, timebuf);

        if(S_IFDIR & buf.st_mode)
        {
#if 1 //#ifdef WEBCFG_SUPPORT_WEBDAV
            CacheHandle cache = CacheCreate();
            if (NULL_HANDLE == cache)
                return handle_http_error(500, req, rsp);
            rsp->code = 200;

            web_lsdir(cache, vpath);
            http_add_rspoption(rsp, "Content-Type", "text/html; charset=\"utf-8\"");
            CacheGetData(cache, &rsp->body);
            http_send_response(rsp);
            if (cache != NULL_HANDLE) CacheDestroy(cache);
            return OK;

#else
            WEBLOG_INFO("<%s> client requesting a directory!\n", __FUNCTION__);
            return handle_http_error(403, req, rsp);
#endif
        }
    }

#ifdef WEBCFG_SUPPORT_HTTPTIME
    /* RFC2616, 14.25. If-Modified-Since */
    e = HashLookup(req->headOptions, "If-Modified-Since");
    if(e)
    {
        time_t reqtime, acctime;
        ASSERT(e->value.type == eHashString);
        reqtime = get_http_time(e->value.data.string);
        acctime = get_http_time(timebuf);

        //WEBLOG_INFO("<%s> reqtime=[%u] vs [%u]=acctime\n", __FUNCTION__, reqtime, acctime);
        if(reqtime >= acctime)
        {
            rsp->code = 304;
            rsp->body = using_customized_body; // 304 has no body.
            http_add_rspoption(rsp, "Content-Length", "0");
            return http_send_response(rsp);
        }
    }
#endif

    fp = web_fopen(vpath,"rb");
    WEBLOG_INFO("<%s> fopen(%s) == %p \n", __FUNCTION__, vpath, fp);
    if(!fp)
    {
        WEBLOG_ERROR("<%s> failed to open file \"%s\" %s \n",
                     __FUNCTION__, vpath, strerror(errno));
        return handle_http_error(500, req, rsp);
    }
    ASSERT(fp); /* check if fp is NULL. */

    fseek(fp, 0, SEEK_END);
    total_length = ftell(fp);
    fseek(fp, 0, SEEK_SET);

#ifdef WEBCFG_SUPPORT_HTTPRANGE
    /* handle range request */
    e = HashLookup(req->headOptions, "Range");
    if(e)
    {
        char * p = e->value.data.string;
        ASSERT(e->value.type == eHashString);
        WEBLOG_INFO("<%s> client range request: %s\n", __FUNCTION__, p);

        /* figure out FROM-TO */
        if(0 == strncmp(p, " bytes=-", 8))
        {
            sscanf(p," bytes=-"sizett"", &task_length);
            from = total_length-task_length;
            to = total_length-1;
        }
        else
        {
            sscanf(p," bytes="sizett"-"sizett"", &from, &to);
            if(to < 0)
            {
                task_length = total_length - from;
                to = total_length-1;
            }
            else
            {
                task_length = to - from + 1;
            }
        }


        WEBLOG_INFO("<%s> request "sizett"-"sizett", total "sizett", we have "sizett".\n",
                    __FUNCTION__, from, to, task_length, total_length);

        if(from < 0 || to < 0 || to >= total_length || from >= total_length || from > to)
        {
            http_add_rspoption(rsp, "Accept-Ranges", "bytes");
            //http_add_rspoption(rsp, "Content-Type", mimetype(req->uri));
            http_add_rspoption(rsp, "Content-Range", "*/*");
            return handle_http_error(416, req, rsp);
        }
        else
        {
            rsp->code = 206;
            rsp->body = using_customized_body;
            http_add_rspoption(rsp, "Accept-Ranges", "bytes");
            //http_add_rspoption(rsp, "Content-Type", mimetype(req->uri));
            sprintf(strbuf, "bytes "sizett"-"sizett"/"sizett"", from, to, total_length);
            http_add_rspoption(rsp, "Content-Range", strbuf);
            sprintf(strbuf, sizett, task_length);
            http_add_rspoption(rsp, "Content-Length", strbuf);

            http_send_response(rsp);
        }
    }
    else
#endif /* WEBCFG_SUPPORT_HTTPRANGE */
    {
        from = 0;
        task_length = total_length;
        to = total_length-1;
        sprintf(strbuf, sizett, task_length);

        rsp->code = 200;
        rsp->body = using_customized_body;
#ifdef WEBCFG_SUPPORT_HTTPRANGE
        http_add_rspoption(rsp, "Accept-Ranges", "bytes");
#endif
        //http_add_rspoption(rsp, "Content-Type", mimetype(req->uri));
        http_add_rspoption(rsp, "Content-Length", strbuf);
        http_send_response(rsp);
    }

    ret = OK;

    /* Respond with data. For HEAD request, skip this. */
    if(HTTP_GET == req->method)
    {
        size_t  i           = 0;
        size_t  buflen      = 1024*1024;
        size_t  readsize    = 0;
        size_t  counter     = 0;
        char  * buffer      = NULL;

#define SPEED_REPORT
#ifdef SPEED_REPORT
        /* speed test */
        //size_t  data_1 = 0, data_2 = 0;
        time_t  time_1 = time(NULL), time_2;
#endif
        do
        {
            buflen /= 2;
            buffer = (char *)webmalloc(buflen);
        }
        while(!buffer);

        fseek(fp, from, SEEK_SET);
        while(1)
        {
            memset(buffer, 0, buflen);
            if(task_length-counter > buflen)
                readsize=fread(buffer, 1, buflen, fp);
            else
                readsize=fread(buffer, 1, task_length-counter, fp);

            if(readsize <= 0)
            {
                WEBLOG_ERROR("<%s> fread fail "sizett". %s.\n", __FUNCTION__, readsize, strerror(socketGetError()));
                ret = NG;
                break;
            }
            WEBLOG_VERBOSE("<%s> read "sizett" from %s, sent "sizett" to socket.\n ", __FUNCTION__, readsize, vpath, i);
            i = WebWrite(req->sock, buffer, readsize);
            if(i != readsize)
            {
                WEBLOG_ERROR("<%s> WebWrite fail "sizett". %s.\n", __FUNCTION__, i, strerror(socketGetError()));
                ret = NG;
                break;
            }
            //ASSERT(i==readsize);
            counter += readsize;
#ifdef SPEED_REPORT
            time_2 = time(NULL);
            if (time_2 - time_1 > 1)
                WEBLOG_VERBOSE("<%s> "sizett"KB/s\n", __FUNCTION__, counter/1024/(time_2-time_1));
#endif
            WEBLOG_VERBOSE("<%s> "sizett"/"sizett"\n", __FUNCTION__, counter, task_length);
            if(counter >= task_length)
                break;
        }

        webfree(buffer);
    }

    if(fp) fclose(fp);
    return ret;
}
示例#9
0
int handle_http_move(http_req * req, http_rsp * rsp)
{
    int ret = 0;
    char * from = NULL;
    char * to = NULL;
    char * tooooo = NULL;
    char * host = NULL;
    HashElement * e = NULL;

    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

    from = req->uri;
    ASSERT(from && from[0]);

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

    e = HashLookup(req->headOptions, "Destination");
    if(!e)
    {
        WEBLOG_ERROR("<%s> Missing \"Destination\" in Move/Copy.\n", __FUNCTION__);
        return handle_http_error(400, req, rsp);
    }

    ASSERT(e->value.type == eHashString);
    to = e->value.data.string;

    e = HashLookup(req->headOptions, "Host");
    ASSERT(e); // static int _simple_validation(http_req * req)
    host = e->value.data.string;

    /* example
    To: [http://x.x.x.x:y/webdav/1.txt]
    Host: [x.x.x.x:y]
    */

    tooooo = to + 7 + strlen(host); // 7 for "http://"

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

    url_decode(tooooo);

    WEBLOG_INFO("<%s> %s from %s to %s.\n", __FUNCTION__,
                (HTTP_MOVE == req->method)?"Move":"Copy", from, tooooo);

    e = HashLookup(req->headOptions, "Overwrite");
    if(e && e->value.data.string[0] == 'T')
    {
        if(HTTP_MOVE == req->method)
            ret = Webdav_Move(from, tooooo, TRUE);
        else
            ret = Webdav_Copy(from, tooooo, TRUE);
    }
    else
    {
        if(HTTP_MOVE == req->method)
            ret = Webdav_Move(from, tooooo, FALSE);
        else
            ret = Webdav_Copy(from, tooooo, FALSE);
    }

    switch(ret)
    {
        case WEBDAVR_OK:
            rsp->code = 201;
            http_add_rspoption(rsp, "Location", to);
            http_send_response(rsp);
            break;
        default:
            handle_http_error(502, req, rsp);
            break;
    }

    return OK;
}
示例#10
0
int main(int argc, char **argv) {
    WSADATA wsa_data;
    WSAStartup(MAKEWORD(2,0), &wsa_data); /* 初始化 WinSock 资源 */
    //web
    SOCKET	web_srv_soc = 0;
    unsigned short web_port = HTTP_DEF_PORT;
    web_srv_soc = socket(AF_INET, SOCK_STREAM, 0); /* 创建 socket */
    if (web_srv_soc == INVALID_SOCKET)
    {
        printf("[Web] socket() Fails, error = %d\n", WSAGetLastError());
        return -1;
    }
    struct sockaddr_in web_serv_addr;   /* 服务器地址  */
    web_serv_addr.sin_family = AF_INET;
    web_serv_addr.sin_port = htons(web_port);
    web_serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    int result;
    result = bind(web_srv_soc, (struct sockaddr *) &web_serv_addr, sizeof(web_serv_addr));
    if (result == SOCKET_ERROR) /* 绑定失败 */
    {
        closesocket(web_srv_soc);
        printf("[Web Server] Fail to bind, error = %d\n", WSAGetLastError());
        return -1;
    }
    result = listen(web_srv_soc, SOMAXCONN);
    printf("[Web] The server is running ... ...\n");

    //FTP
    SOCKET	ftp_srv_soc = 0;
    unsigned short ftp_port = FTP_DEF_PORT;
    ftp_srv_soc = socket(AF_INET, SOCK_STREAM, 0); /* 创建 socket */
    if (ftp_srv_soc == INVALID_SOCKET)
    {
        printf("[FTP] socket() Fails, error = %d\n", WSAGetLastError());
        return -1;
    }
    struct sockaddr_in ftp_serv_addr;   /* 服务器地址  */
    ftp_serv_addr.sin_family = AF_INET;
    ftp_serv_addr.sin_port = htons(ftp_port);
    ftp_serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    result = bind(ftp_srv_soc, (struct sockaddr *) &ftp_serv_addr, sizeof(ftp_serv_addr));
    if (result == SOCKET_ERROR) /* 绑定失败 */
    {
        closesocket(ftp_srv_soc);
        printf("[FTP Server] Fail to bind, error = %d\n", WSAGetLastError());
        return -1;
    }
    result = listen(ftp_srv_soc, SOMAXCONN);
    printf("[FTP] The server is running ... ...\n");

    fd_set afds;
    FD_ZERO(&afds);
    FD_SET(web_srv_soc, &afds);
    FD_SET(ftp_srv_soc, &afds);

    fd_set rfds;
    SOCKET web_conn_soc;
    SOCKET ftp_conn_soc;
    while(1) {
        FD_ZERO(&rfds);
        memcpy(&rfds, &afds, sizeof(rfds));
        if(select(FD_SETSIZE, &rfds, (fd_set*)0, (fd_set*)0,
                  (struct timeval *)0)== SOCKET_ERROR)
            printf("select error\n");
        if(FD_ISSET(web_srv_soc, &rfds)) {
            struct sockaddr_in conn_addr;   /* 客户端地址  */
            int conn_addr_len = sizeof(conn_addr);
            web_conn_soc = accept(web_srv_soc, (struct sockaddr*)&conn_addr,&conn_addr_len);
            if(web_conn_soc == INVALID_SOCKET) {
                printf("[Web] Fail to accept, error = %d\n", WSAGetLastError());
                break;
            }
            printf("[Web] Accepted address:[%s], port:[%d]\n",
                   inet_ntoa(conn_addr.sin_addr), ntohs(conn_addr.sin_port));
            char recv_buf[BUF_SIZE];
            int recv_len;
            recv_len = recv(web_conn_soc, recv_buf, BUF_SIZE, 0);
            if (recv_len == SOCKET_ERROR) /* 接收失败 */
            {
                closesocket(web_conn_soc);
                printf("[Web] Fail to recv, error = %d\n", WSAGetLastError());
                break;
            }

            recv_buf[recv_len] = 0;

            /* 向客户端发送响应数据 */
            http_send_response(web_conn_soc, recv_buf, recv_len);
            closesocket(web_conn_soc);
        }
        if(FD_ISSET(ftp_srv_soc, &rfds)) {
            struct sockaddr_in conn_addr;   /* 客户端地址  */
            int conn_addr_len = sizeof(conn_addr);
            ftp_conn_soc = accept(ftp_srv_soc, (struct sockaddr*)&conn_addr,&conn_addr_len);
            if(ftp_conn_soc == INVALID_SOCKET) {
                printf("[FTP] Fail to accept, error = %d\n", WSAGetLastError());
                break;
            }
            printf("[FTP] Accepted address:[%s], port:[%d]\n",
                   inet_ntoa(conn_addr.sin_addr), ntohs(conn_addr.sin_port));
            char recv_buf[BUF_SIZE];
            int recv_len;
            recv_len = recv(ftp_conn_soc, recv_buf, BUF_SIZE, 0);
            if (recv_len == SOCKET_ERROR) /* 接收失败 */
            {
                closesocket(ftp_conn_soc);
                printf("[FTP] Fail to recv, error = %d\n", WSAGetLastError());
                break;
            }

            recv_buf[recv_len] = 0;

            /* 向客户端发送响应数据 */
            ftp_send_response(ftp_conn_soc, recv_buf, recv_len);
            closesocket(ftp_conn_soc);
        }

    }

    closesocket(web_srv_soc);
    closesocket(ftp_srv_soc);
    WSACleanup();
    printf("[web] The server is stopped.\n");
    printf("[FTP] The server is stopped.\n");
    return 0;
}
示例#11
0
int main(int argc, char **argv)
{
	WSADATA wsa_Data;
	SOCKET	srv_soc = 0, acpt_soc; /* socket 句柄 */
	struct sockaddr_in serv_addr; /* 服务器地址 */
	struct sockaddr_in from_addr; /* 客户端地址 */
	char recv_buf[HTTP_BUF_SIZE];
	unsigned short port = HTTP_DEF_PORT;
	unsigned long from_len = sizeof(from_addr);
	int	result = 0, recv_len;

	if (argc == 2) /* 端口号 */
		port = atoi(argv[1]);

	WSAStartup(MAKEWORD(2, 0), &wsa_Data); /* 初始化Winsock资源 */

	srv_soc = socket(AF_INET, SOCK_STREAM, 0); /* 创建socket */
	if (srv_soc == INVALID_SOCKET)
	{
		printf("[Web] socket() Fails, error = %d\n", WSAGetLastError());
		return -1;
	}

	/* 服务器地址 */
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port	 = htons(port);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	result = bind(srv_soc, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
	if (result == SOCKET_ERROR) /* 绑定失败 */
	{
		closesocket(srv_soc);
		printf("[Web] Fail to bind, error = %d\n", WSAGetLastError());
		return -1;
	}

	result = listen(srv_soc, SOMAXCONN);
	printf("[Web] The server is running ... ...\n");

	while (1)
	{
		acpt_soc = accept(srv_soc, (struct sockaddr *) &from_addr,  &from_len); /* 这里有警告 */
		if (acpt_soc == INVALID_SOCKET) /* 接受失败 */
		{
			printf("[Web] Fail to accept, error = %d\n", WSAGetLastError());
			break;
		}

		printf("[Web] Accepted address:[%s], port:[%d]\n", \
				inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port));

		recv_len = recv(acpt_soc, recv_buf, HTTP_BUF_SIZE, 0);
		if (recv_len == SOCKET_ERROR) /* 接受失败 */
		{
			closesocket(acpt_soc);
			printf("[Web] Fail to recv, error = %d\n", WSAGetLastError());
			break;
		}

		recv_buf[recv_len] = 0;

		/* 向客户端发送响应数据 */
		result = http_send_response(acpt_soc, recv_buf, recv_len);
		closesocket(acpt_soc);
	}
	closesocket(acpt_soc);
	WSACleanup();
	printf("[Web] the server is stopped.\n");

	return 0;
}
示例#12
0
/*
 * Launch a http server that listens on the given port.
 */
void http_server(uint16_t port, void (*callback)(struct http_user_vars_s *),
    bool launch)
{
    socket_t s_listen = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
    if (s_listen == INVALID_SOCKET)
    {
        error("unable to create a socket for the configuration server");
    }
    struct sockaddr_in6 listen_addr;
    memset(&listen_addr, 0x0, sizeof(listen_addr));
    listen_addr.sin6_family = AF_INET6;
    listen_addr.sin6_port   = htons(port);
    listen_addr.sin6_addr   = in6addr_any;
    int on = 1;
    setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
    // For Windows we must explicitly allow IPv4 connections
    on = 0;
    if (setsockopt(s_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on,
            sizeof(on)) != 0)
    {
        warning("unable to allow incoming IPv4 connections to configuration "
            "server");
    }
    if (bind(s_listen, (const void *)&listen_addr, sizeof(listen_addr)) != 0)
    {
        error("unable to create configuation server; failed to bind to "
            "address localhost:%u", port);
    }

    if (listen(s_listen, 1) != 0)
    {
        error("unable to create configuation server; failed to listen to "
            "address localhost:%u", port);
    }

    // Launch the UI:
    if (launch)
    {
        launch_ui(port);
    }

    // Main server loop:
    while (true)
    {
        struct sockaddr_in6 accept_addr;
        socklen_t accept_len = sizeof(accept_addr);
        socket_t s = accept(s_listen, (struct sockaddr *)&accept_addr,
            &accept_len);
        if (s == INVALID_SOCKET)
        {
            warning("unable to accept incoming connection to configuration "
                "server localhost:%u", port);
            close_socket(s);
            continue;
        }
        static const struct in6_addr in6addr_loopbackv4 =
            {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 127, 0, 0, 1}}};
        if (memcmp(&accept_addr.sin6_addr, &in6addr_loopback,
                sizeof(in6addr_loopback)) != 0 &&
            memcmp(&accept_addr.sin6_addr, &in6addr_loopbackv4,
                sizeof(in6addr_loopbackv4) - 3) != 0)
        {
            warning("unable to accept incoming connection to configuration "
                "server localhost:%u from non-local address", port);
            close_socket(s);
            continue;
        }
        char request[MAX_REQUEST_BUFF_SIZE];
        struct http_parser_s parser;
        http_parser_init(&parser);
        do
        {
            size_t n = recv(s, request, sizeof(request)-1, 0);
            if (n <= 0)
            {
                http_user_vars_free(&parser.request.vars);
                warning("unable to read request for configuration server "
                    "localhost:%u", port);
                close_socket(s);
                break;
            }
            request[n] = '\0';
            http_parse_request(request, n, &parser);
            switch (parser.state)
            {
                case HTTP_STATE_FINAL:
                    break;
                case HTTP_STATE_ERROR:
                    http_user_vars_free(&parser.request.vars);
                    warning("unable to parse request to configuration server "
                        "localhost:%u", port);
                    close_socket(s);
                    break;
                default:
                    continue;
            }
            http_callback_func_t generate;
            if (parser.request.method == HTTP_METHOD_GET &&
                (generate = http_lookup_callback(parser.request.name)) != NULL)
            {
                http_buffer_t content = http_buffer_open();
                if (generate(content))
                {
                    bool success = http_send_response(s, 200, content,
                        &parser.request);
                    if (!success)
                    {
                        http_error(s, 500, &parser.request);
                    }
                }
                else
                {
                    http_error(s, 404, &parser.request);
                }
                http_buffer_close(content);
            }
            else
            {
                callback(&parser.request.vars);
                http_handle_request(s, &parser.request);
            }
            shutdown(s, SHUT_RDWR);
            http_user_vars_free(&parser.request.vars);
            close_socket(s);
        } 
        while (false);
    }
}