cmogstored.git  about / heads / tags
alternative mogstored implementation for MogileFS
blob 43b6c7af968f14be26007b0298a4927f1ce6b4cc 2056 bytes (raw)
$ git show HEAD:http_dav.c	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
/*
 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 *
 * TODO: ensure compliance with relevant RFCs.
 *       This is only enough to work with MogileFS.
 */
#include "cmogstored.h"
#include "http.h"

void mog_http_delete(struct mog_fd *mfd, char *buf)
{
	struct mog_http *http = &mfd->as.http;
	int rc;
	char *path;

	if (mfd->fd_type == MOG_FD_TYPE_HTTPGET) {
		mog_http_resp(mfd, "405 Method Not Allowed", true);
		return;
	}

	path = mog_http_path(http, buf);
	if (!path) goto forbidden; /* path traversal attack */
	assert(path[0] == '/' && "bad path");
	if (path[1] == '\0') goto forbidden;

	TRACE(CMOGSTORED_HTTP_REQ_START(mfd->fd, "DELETE", path));

	rc = mog_unlink(http->svc, path);
	if (rc == 0) {
		mog_http_resp(mfd, "204 No Content", true);
		mog_notify(MOG_NOTIFY_DEVICE_REFRESH);

		return;
	}

	switch (errno) {
	case EPERM:
	case EISDIR:
	case EACCES:
forbidden:
		mog_http_resp(mfd, "403 Forbidden", true);
		return;
	case ENOENT:
		mog_http_resp(mfd, "404 Not Found", true);
		return;
	}
	PRESERVE_ERRNO(do {
		mog_http_resp(mfd, "500 Internal Server Error", true);
	} while(0));
	syslog(LOG_ERR, "Failed to unlink %s (in %s): %m",
		path, http->svc->docroot);
}

void mog_http_mkcol(struct mog_fd *mfd, char *buf)
{
	struct mog_http *http = &mfd->as.http;
	char *path;

	if (mfd->fd_type == MOG_FD_TYPE_HTTPGET) {
		mog_http_resp(mfd, "405 Method Not Allowed", true);
		return;
	}
	path = mog_http_path(http, buf);

	/*
	 * This can be useful for making sure the skip_mkcol server setting
	 * is enabled in the tracker/database to avoid latency
	 */
	TRACE(CMOGSTORED_HTTP_REQ_START(mfd->fd, "MKCOL", path));

	/*
	 * Do not do anything on MKCOL and rely on PUT to create
	 * directories.  This stops MogileFS trackers from trying
	 * (expensive) MKCOL requests.  Perlbal/mogstored also does
	 * this.
	 */
	if (path)
		mog_http_resp(mfd, "400 Bad Request", true);
	else /* path traversal attack */
		mog_http_resp(mfd, "403 Forbidden", true);
}

git clone https://yhbt.net/cmogstored.git