// Use the global passwords file, if specified by auth_gpass option, // or search for .htpasswd in the requested directory. static FILE *open_auth_file(struct mg_connection *conn, const char *path) { char name[PATH_MAX]; const char *p, *e, *gpass = conn->ctx->config[GLOBAL_PASSWORDS_FILE]; struct file file = STRUCT_FILE_INITIALIZER; FILE *fp = NULL; if (gpass != NULL) { // Use global passwords file fp = mg_fopen(gpass, "r"); // Important: using local struct file to test path for is_directory flag. // If filep is used, mg_stat() makes it appear as if auth file was opened. } else if (mg_stat(path, &file) && file.is_directory) { mg_snprintf(name, sizeof(name), "%s%c%s", path, '/', PASSWORDS_FILE_NAME); fp = mg_fopen(name, "r"); } else { // Try to find .htpasswd in requested directory. for (p = path, e = p + strlen(p) - 1; e > p; e--) if (e[0] == '/') break; mg_snprintf(name, sizeof(name), "%.*s%c%s", (int) (e - p), p, '/', PASSWORDS_FILE_NAME); fp = mg_fopen(name, "r"); } return fp; }
// Return 1 if request is authorised, 0 otherwise. static int check_authorization(struct mg_connection *conn, const char *path) { char fname[PATH_MAX]; struct vec uri_vec, filename_vec; const char *list; FILE *fp = NULL; int authorized = 1; list = conn->ctx->config[PROTECT_URI]; while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) { if (!memcmp(conn->request_info.uri, uri_vec.ptr, uri_vec.len)) { mg_snprintf(fname, sizeof(fname), "%.*s", (int) filename_vec.len, filename_vec.ptr); fp = mg_fopen(fname, "r"); break; } } if (fp == NULL) { fp = open_auth_file(conn, path); } if (fp != NULL) { authorized = authorize(conn, fp); fclose(fp); } return authorized; }
void mg_send_http_error(struct mg_connection *conn, int status, const char *reason, const char *fmt, ...) { char buf[BUFSIZ]; va_list ap; int len; conn->request_info.status_code = status; buf[0] = '\0'; len = 0; /* Errors 1xx, 204 and 304 MUST NOT send a body */ if (status > 199 && status != 204 && status != 304) { len = mg_snprintf(conn, buf, sizeof(buf), "Error %d: %s", status, reason); cry(conn, "%s", buf); buf[len++] = '\n'; va_start(ap, fmt); len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap); va_end(ap); } DEBUG_TRACE(("[%s]", buf)); mg_printf(conn, "HTTP/1.1 %d %s\r\n" "Content-Type: text/plain\r\n" "Content-Length: %d\r\n" "Connection: %s\r\n\r\n", status, reason, len, suggest_connection_header(conn)); conn->num_bytes_sent += mg_printf(conn, "%s", buf); }
static void print_dav_dir_entry(struct de *de, void *data) { char href[PATH_MAX]; char href_encoded[PATH_MAX]; struct mg_connection *conn = (struct mg_connection *) data; mg_snprintf(href, sizeof(href), "%s%s", conn->request_info.uri, de->file_name); mg_url_encode(href, href_encoded, PATH_MAX-1); print_props(conn, href_encoded, &de->file); }
END_TEST START_TEST(test_mg_vsnprintf) { char buf[16]; int is_trunc; memset(buf, 0, sizeof(buf)); is_trunc = 777; mg_snprintf(NULL, &is_trunc, buf, 10, "%8i", 123); ck_assert_str_eq(buf, " 123"); ck_assert_int_eq(is_trunc, 0); is_trunc = 777; mg_snprintf(NULL, &is_trunc, buf, 10, "%9i", 123); ck_assert_str_eq(buf, " 123"); ck_assert_int_eq(is_trunc, 0); is_trunc = 777; mg_snprintf(NULL, &is_trunc, buf, 9, "%9i", 123); ck_assert_str_eq(buf, " 12"); ck_assert_int_eq(is_trunc, 1); is_trunc = 777; mg_snprintf(NULL, &is_trunc, buf, 8, "%9i", 123); ck_assert_str_eq(buf, " 1"); ck_assert_int_eq(is_trunc, 1); is_trunc = 777; mg_snprintf(NULL, &is_trunc, buf, 7, "%9i", 123); ck_assert_str_eq(buf, " "); ck_assert_int_eq(is_trunc, 1); strcpy(buf, "1234567890"); mg_snprintf(NULL, &is_trunc, buf, 0, "%i", 543); ck_assert_str_eq(buf, "1234567890"); }