Exemplo n.º 1
0
/* Dispatch a GET request REQ, writing the response body to FD fd.  If
 * RANGE is non-NULL, then it is the value of the Range request
 * header, e.g. "bytes=1-5".  Returns an NE_* error code. */
static int dispatch_to_fd(ne_request *req, int fd, const char *range)
{
    ne_session *const sess = ne_get_session(req);
    const ne_status *const st = ne_get_status(req);
    int ret;

    do {
        const char *value;
        
        ret = ne_begin_request(req);
        if (ret != NE_OK) break;

        value = ne_get_response_header(req, "Content-Range");

        /* For a 206 response, check that a Content-Range header is
         * given which matches the Range request header. */
        if (range && st->code == 206 
            && (value == NULL || strncmp(value, "bytes ", 6) != 0
                || strcmp(range + 6, value + 6))) {
            ne_set_error(sess, _("Response did not include requested range"));
            return NE_ERROR;
        }

        if ((range && st->code == 206) || (!range && st->klass == 2)) {
            ret = ne_read_response_to_fd(req, fd);
        } else {
            ret = ne_discard_response(req);
        }

        if (ret == NE_OK) ret = ne_end_request(req);
    } while (ret == NE_RETRY);

    return ret;
}
Exemplo n.º 2
0
/* A slightly ugly hack: the pre_send hook is scoped per-session, so
 * must check that the invoking request is this one, before doing
 * anything, and must be unregistered when the context is
 * destroyed. */
ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt,
				    ne_block_reader rdr, void *userdata)
{
    ne_decompress *ctx = ne_calloc(sizeof *ctx);

    ne_add_request_header(req, "Accept-Encoding", "gzip");

    ne_add_response_body_reader(req, gz_acceptor, gz_reader, ctx);

    ctx->reader = rdr;
    ctx->userdata = userdata;
    ctx->session = ne_get_session(req);
    ctx->request = req;
    ctx->acceptor = acpt;

    ne_hook_pre_send(ne_get_session(req), gz_pre_send, ctx);

    return ctx;    
}
MateVFSResult
ne_matevfs_last_error (ne_request *req)
{
	ne_session *sess;
	
	sess = ne_get_session (req);

	if (sess && sess->socket)
		return sess->socket->last_error;
	
	return MATE_VFS_OK;
}
Exemplo n.º 4
0
int ne_xml_parse_response(ne_request *req, ne_xml_parser *parser)
{
    char buf[8000];
    ssize_t bytes;
    int ret = 0;

    while ((bytes = ne_read_response_block(req, buf, sizeof buf)) > 0) {
        ret = ne_xml_parse(parser, buf, bytes);
        if (ret)
            return parse_error(ne_get_session(req), parser);
    }

    if (bytes == 0) {
        /* Tell the parser that end of document was reached: */
        if (ne_xml_parse(parser, NULL, 0) == 0)
            return NE_OK;
        else
            return parse_error(ne_get_session(req), parser);
    } else {
        return NE_ERROR;
    }    
}
Exemplo n.º 5
0
void ne_lock_using_parent(ne_request *req, const char *path)
{
    NE_DEBUG_WINSCP_CONTEXT(ne_get_session(req));
    struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID);
    ne_uri u = {0};
    struct lock_list *item;
    char *parent;

    if (lrc == NULL)
	return;
    
    parent = ne_path_parent(path);
    if (parent == NULL)
	return;
    
    ne_fill_server_uri(ne_get_session(req), &u);

    for (item = lrc->store->locks; item != NULL; item = item->next) {

	/* Only care about locks which are on this server. */
	u.path = item->lock->uri.path;
	if (ne_uri_cmp(&u, &item->lock->uri))
	    continue;
	
	/* This lock is needed if it is an infinite depth lock which
	 * covers the parent, or a lock on the parent itself. */
	if ((item->lock->depth == NE_DEPTH_INFINITE && 
	     ne_path_childof(item->lock->uri.path, parent)) ||
	    ne_path_compare(item->lock->uri.path, parent) == 0) {
	    NE_DEBUG(NE_DBG_LOCKS, "Locked parent, %s on %s\n",
		     item->lock->token, item->lock->uri.path);
	    submit_lock(lrc, item->lock);
	}
    }

    u.path = parent; /* handy: makes u.path valid and ne_free(parent). */
    ne_uri_free(&u);
}
Exemplo n.º 6
0
/* Dispatch a GET request REQ, writing the response body to FD fd.  If
 * RANGE is non-NULL, then it is the value of the Range request
 * header, e.g. "bytes=1-5".  Returns an NE_* error code. */
static int dispatch_to_fd(ne_request *req, int fd, const char *range)
{
    ne_session *const sess = ne_get_session(req);
    const ne_status *const st = ne_get_status(req);
    int ret;

    do {
        const char *value;
        
        ret = ne_begin_request(req);
        if (ret != NE_OK) break;

        value = ne_get_response_header(req, "Content-Range");

        /* For a 206 response, check that a Content-Range header is
         * given which matches the Range request header. */
        if (range && st->code == 206) {
            int err = 0;
            if (value == NULL || strncmp(value, "bytes ", 6) != 0) {
                err++;
            } else {
                /* If the response gives a range begin-end/total, limit
                 * the comparison to the range itself. */
                int len = strlen(value);
                char *cp = strchr(value, '/');
                if (cp != NULL)
                    len = (int)(cp - value);
                len -= 6;
                if (strncmp(range + 6, value + 6, len))
                    err++;
            }
            if (err) {
                ne_set_error(sess, _("Response did not include requested range"));
                return NE_ERROR;
            }
        }

        if ((range && st->code == 206) || (!range && st->klass == 2)) {
            ret = ne_read_response_to_fd(req, fd);
        } else {
            ret = ne_discard_response(req);
        }

        if (ret == NE_OK) ret = ne_end_request(req);
    } while (ret == NE_RETRY);

    return ret;
}
Exemplo n.º 7
0
static int lk_startelm(void *userdata, int parent,
                       const char *nspace, const char *name,
		       const char **atts)
{
    struct lock_ctx *ctx = userdata;
    int id;
    NE_DEBUG_WINSCP_CONTEXT(ne_get_session(ctx->req));

    id = ne_xml_mapid(element_map, NE_XML_MAPLEN(element_map), nspace, name);

    NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: %s => %d\n", name, id);
    
    if (id == 0)
        return NE_XML_DECLINE;    

    if (parent == 0 && ctx->token == NULL) {
        const char *token = ne_get_response_header(ctx->req, "Lock-Token");
        /* at the root element; retrieve the Lock-Token header,
         * and bail if it wasn't given. */
        if (token == NULL) {
            ne_xml_set_error(ctx->parser, 
                             _("LOCK response missing Lock-Token header"));
            return NE_XML_ABORT;
        }

        if (token[0] == '<') token++;
        ctx->token = ne_strdup(token);
        ne_shave(ctx->token, ">");
        NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: Finding token %s\n",
                 ctx->token);
    }

    /* TODO: only accept 'prop' as root for LOCK response */
    if (!can_accept(parent, id))
        return NE_XML_DECLINE;

    if (id == ELM_activelock && !ctx->found) {
	/* a new activelock */
	ne_lock_free(&ctx->active);
	memset(&ctx->active, 0, sizeof ctx->active);
        ctx->active.timeout = NE_TIMEOUT_INVALID;
    }

    ne_buffer_clear(ctx->cdata);

    return id;
}
int
ne__negotiate_ssl (ne_request *req)
{
	MateVFSSSL *ssl;
	MateVFSCancellation *cancellation;
	ne_session *sess;
	ne_socket  *sock;
	int fd;

	sess = ne_get_session (req);
	sock = sess->socket;
	
	if (!mate_vfs_ssl_enabled ()) {
		sock->last_error = MATE_VFS_ERROR_NOT_SUPPORTED;
		return NE_SOCK_ERROR;
	}
	
	peek_cancellation (cancellation);

	
	fd = mate_vfs_inet_connection_get_fd (sock->connection);

	sock->last_error = mate_vfs_ssl_create_from_fd (&ssl,
							 fd,
							 cancellation);

	if (sock->last_error != MATE_VFS_OK) {
		return NE_SOCK_ERROR;
	}

	mate_vfs_socket_free (sock->socket);
	sock->socket = mate_vfs_ssl_to_socket (ssl);

	mate_vfs_socket_buffer_flush (sock->socket_buffer,
				       cancellation);
	
	sock->last_error = mate_vfs_socket_buffer_destroy (sock->socket_buffer,
							    FALSE,
							    cancellation);

	mate_vfs_inet_connection_free (sock->connection, cancellation);
	
	sock->socket_buffer = mate_vfs_socket_buffer_new (sock->socket);

	return 0;
}
Exemplo n.º 9
0
void ne_lock_using_resource(ne_request *req, const char *uri, int depth)
{
    NE_DEBUG_WINSCP_CONTEXT(ne_get_session(req));
    struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID);
    struct lock_list *item;
    int match;

    if (lrc == NULL)
	return;	

    /* Iterate over the list of stored locks to see if any of them
     * apply to this resource */
    for (item = lrc->store->locks; item != NULL; item = item->next) {
	
	match = 0;
	
	if (depth == NE_DEPTH_INFINITE &&
	    ne_path_childof(uri, item->lock->uri.path)) {
	    /* Case 1: this is a depth-infinity request which will 
	     * modify a lock somewhere inside the collection. */
	    NE_DEBUG(NE_DBG_LOCKS, "Has child: %s\n", item->lock->token);
	    match = 1;
	} 
	else if (ne_path_compare(uri, item->lock->uri.path) == 0) {
	    /* Case 2: this request is directly on a locked resource */
	    NE_DEBUG(NE_DBG_LOCKS, "Has direct lock: %s\n", item->lock->token);
	    match = 1;
	}
	else if (item->lock->depth == NE_DEPTH_INFINITE && 
		 ne_path_childof(item->lock->uri.path, uri)) {
	    /* Case 3: there is a higher-up infinite-depth lock which
	     * covers the resource that this request will modify. */
	    NE_DEBUG(NE_DBG_LOCKS, "Is child of: %s\n", item->lock->token);
	    match = 1;
	}
	
	if (match) {
	    submit_lock(lrc, item->lock);
	}
    }

}