Commit 1e7da874 authored by Sergey Lyubka's avatar Sergey Lyubka

Merge branch 'master' of ssh://github.com/valenok/mongoose

parents 7875a8c2 b0355d45
...@@ -1342,7 +1342,7 @@ static const struct { ...@@ -1342,7 +1342,7 @@ static const struct {
{".ogg", 4, "application/ogg"}, {".ogg", 4, "application/ogg"},
{".ram", 4, "audio/x-pn-realaudio"}, {".ram", 4, "audio/x-pn-realaudio"},
{".xml", 4, "text/xml"}, {".xml", 4, "text/xml"},
{".json", 5, "text/json"}, {".json", 5, "application/json"},
{".xslt", 5, "application/xml"}, {".xslt", 5, "application/xml"},
{".xsl", 4, "application/xml"}, {".xsl", 4, "application/xml"},
{".ra", 3, "audio/x-pn-realaudio"}, {".ra", 3, "audio/x-pn-realaudio"},
...@@ -2544,7 +2544,7 @@ static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) { ...@@ -2544,7 +2544,7 @@ static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) {
(void) a; (void) b; (void) c; (void) d; (void) e; (void) a; (void) b; (void) c; (void) d; (void) e;
} }
static void SHA1Init(SHA1_CTX* context) { static void SHA1Init(SHA1_CTX *context) {
context->state[0] = 0x67452301; context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89; context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE; context->state[2] = 0x98BADCFE;
...@@ -2553,7 +2553,7 @@ static void SHA1Init(SHA1_CTX* context) { ...@@ -2553,7 +2553,7 @@ static void SHA1Init(SHA1_CTX* context) {
context->count[0] = context->count[1] = 0; context->count[0] = context->count[1] = 0;
} }
static void SHA1Update(SHA1_CTX* context, const unsigned char* data, static void SHA1Update(SHA1_CTX *context, const unsigned char *data,
uint32_t len) { uint32_t len) {
uint32_t i, j; uint32_t i, j;
...@@ -2574,7 +2574,7 @@ static void SHA1Update(SHA1_CTX* context, const unsigned char* data, ...@@ -2574,7 +2574,7 @@ static void SHA1Update(SHA1_CTX* context, const unsigned char* data,
memcpy(&context->buffer[j], &data[i], len - i); memcpy(&context->buffer[j], &data[i], len - i);
} }
static void SHA1Final(unsigned char digest[20], SHA1_CTX* context) { static void SHA1Final(unsigned char digest[20], SHA1_CTX *context) {
unsigned i; unsigned i;
unsigned char finalcount[8], c; unsigned char finalcount[8], c;
...@@ -2690,7 +2690,7 @@ static int deliver_websocket_frame(struct connection *conn) { ...@@ -2690,7 +2690,7 @@ static int deliver_websocket_frame(struct connection *conn) {
return buffered; return buffered;
} }
size_t mg_websocket_write(struct mg_connection* conn, int opcode, size_t mg_websocket_write(struct mg_connection *conn, int opcode,
const char *data, size_t data_len) { const char *data, size_t data_len) {
unsigned char mem[4192], *copy = mem; unsigned char mem[4192], *copy = mem;
size_t copy_len = 0; size_t copy_len = 0;
...@@ -2740,7 +2740,7 @@ size_t mg_websocket_write(struct mg_connection* conn, int opcode, ...@@ -2740,7 +2740,7 @@ size_t mg_websocket_write(struct mg_connection* conn, int opcode,
return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len; return MG_CONN_2_CONN(conn)->ns_conn->send_iobuf.len;
} }
size_t mg_websocket_printf(struct mg_connection* conn, int opcode, size_t mg_websocket_printf(struct mg_connection *conn, int opcode,
const char *fmt, ...) { const char *fmt, ...) {
char mem[4192], *buf = mem; char mem[4192], *buf = mem;
va_list ap; va_list ap;
...@@ -3501,16 +3501,16 @@ void mg_send_digest_auth_request(struct mg_connection *c) { ...@@ -3501,16 +3501,16 @@ void mg_send_digest_auth_request(struct mg_connection *c) {
// Use the global passwords file, if specified by auth_gpass option, // Use the global passwords file, if specified by auth_gpass option,
// or search for .htpasswd in the requested directory. // or search for .htpasswd in the requested directory.
static FILE *open_auth_file(struct connection *conn, const char *path) { static FILE *open_auth_file(struct connection *conn, const char *path,
int is_directory) {
char name[MAX_PATH_SIZE]; char name[MAX_PATH_SIZE];
const char *p, *gpass = conn->server->config_options[GLOBAL_AUTH_FILE]; const char *p, *gpass = conn->server->config_options[GLOBAL_AUTH_FILE];
file_stat_t st;
FILE *fp = NULL; FILE *fp = NULL;
if (gpass != NULL) { if (gpass != NULL) {
// Use global passwords file // Use global passwords file
fp = fopen(gpass, "r"); fp = fopen(gpass, "r");
} else if (!stat(path, &st) && S_ISDIR(st.st_mode)) { } else if (is_directory) {
mg_snprintf(name, sizeof(name), "%s%c%s", path, '/', PASSWORDS_FILE_NAME); mg_snprintf(name, sizeof(name), "%s%c%s", path, '/', PASSWORDS_FILE_NAME);
fp = fopen(name, "r"); fp = fopen(name, "r");
} else { } else {
...@@ -3800,11 +3800,12 @@ int mg_authorize_digest(struct mg_connection *c, FILE *fp) { ...@@ -3800,11 +3800,12 @@ int mg_authorize_digest(struct mg_connection *c, FILE *fp) {
// Return 1 if request is authorised, 0 otherwise. // Return 1 if request is authorised, 0 otherwise.
static int is_authorized(struct connection *conn, const char *path) { static int is_authorized(struct connection *conn, const char *path,
int is_directory) {
FILE *fp; FILE *fp;
int authorized = MG_TRUE; int authorized = MG_TRUE;
if ((fp = open_auth_file(conn, path)) != NULL) { if ((fp = open_auth_file(conn, path, is_directory)) != NULL) {
authorized = mg_authorize_digest(&conn->mg_conn, fp); authorized = mg_authorize_digest(&conn->mg_conn, fp);
fclose(fp); fclose(fp);
} }
...@@ -4143,11 +4144,11 @@ static void proxify_connection(struct connection *conn) { ...@@ -4143,11 +4144,11 @@ static void proxify_connection(struct connection *conn) {
} }
#ifndef MONGOOSE_NO_FILESYSTEM #ifndef MONGOOSE_NO_FILESYSTEM
void mg_send_file(struct mg_connection *c, const char *file_name) { void mg_send_file_internal(struct mg_connection *c, const char *file_name,
file_stat_t *st, int exists) {
struct connection *conn = MG_CONN_2_CONN(c); struct connection *conn = MG_CONN_2_CONN(c);
file_stat_t st;
char path[MAX_PATH_SIZE]; char path[MAX_PATH_SIZE];
int exists = 0, is_directory = 0; const int is_directory = S_ISDIR(st->st_mode);
#ifndef MONGOOSE_NO_CGI #ifndef MONGOOSE_NO_CGI
const char *cgi_pat = conn->server->config_options[CGI_PATTERN]; const char *cgi_pat = conn->server->config_options[CGI_PATTERN];
#else #else
...@@ -4160,8 +4161,6 @@ void mg_send_file(struct mg_connection *c, const char *file_name) { ...@@ -4160,8 +4161,6 @@ void mg_send_file(struct mg_connection *c, const char *file_name) {
#endif #endif
mg_snprintf(path, sizeof(path), "%s", file_name); mg_snprintf(path, sizeof(path), "%s", file_name);
exists = stat(path, &st) == 0;
is_directory = S_ISDIR(st.st_mode);
if (!exists || must_hide_file(conn, path)) { if (!exists || must_hide_file(conn, path)) {
send_http_error(conn, 404, NULL); send_http_error(conn, 404, NULL);
...@@ -4171,7 +4170,7 @@ void mg_send_file(struct mg_connection *c, const char *file_name) { ...@@ -4171,7 +4170,7 @@ void mg_send_file(struct mg_connection *c, const char *file_name) {
mg_printf(&conn->mg_conn, "HTTP/1.1 301 Moved Permanently\r\n" mg_printf(&conn->mg_conn, "HTTP/1.1 301 Moved Permanently\r\n"
"Location: %s/\r\n\r\n", conn->mg_conn.uri); "Location: %s/\r\n\r\n", conn->mg_conn.uri);
close_local_endpoint(conn); close_local_endpoint(conn);
} else if (is_directory && !find_index_file(conn, path, sizeof(path), &st)) { } else if (is_directory && !find_index_file(conn, path, sizeof(path), st)) {
if (!mg_strcasecmp(dir_lst, "yes")) { if (!mg_strcasecmp(dir_lst, "yes")) {
#ifndef MONGOOSE_NO_DIRECTORY_LISTING #ifndef MONGOOSE_NO_DIRECTORY_LISTING
send_directory_listing(conn, path); send_directory_listing(conn, path);
...@@ -4193,16 +4192,21 @@ void mg_send_file(struct mg_connection *c, const char *file_name) { ...@@ -4193,16 +4192,21 @@ void mg_send_file(struct mg_connection *c, const char *file_name) {
path) > 0) { path) > 0) {
handle_ssi_request(conn, path); handle_ssi_request(conn, path);
#endif #endif
} else if (is_not_modified(conn, &st)) { } else if (is_not_modified(conn, st)) {
send_http_error(conn, 304, NULL); send_http_error(conn, 304, NULL);
} else if ((conn->endpoint.fd = open(path, O_RDONLY | O_BINARY)) != -1) { } else if ((conn->endpoint.fd = open(path, O_RDONLY | O_BINARY)) != -1) {
// O_BINARY is required for Windows, otherwise in default text mode // O_BINARY is required for Windows, otherwise in default text mode
// two bytes \r\n will be read as one. // two bytes \r\n will be read as one.
open_file_endpoint(conn, path, &st); open_file_endpoint(conn, path, st);
} else { } else {
send_http_error(conn, 404, NULL); send_http_error(conn, 404, NULL);
} }
} }
void mg_send_file(struct mg_connection *c, const char *file_name) {
file_stat_t st;
const int exists = stat(file_name, &st) == 0;
mg_send_file_internal(c, file_name, &st, exists);
}
#endif // !MONGOOSE_NO_FILESYSTEM #endif // !MONGOOSE_NO_FILESYSTEM
static void open_local_endpoint(struct connection *conn, int skip_user) { static void open_local_endpoint(struct connection *conn, int skip_user) {
...@@ -4265,7 +4269,8 @@ static void open_local_endpoint(struct connection *conn, int skip_user) { ...@@ -4265,7 +4269,8 @@ static void open_local_endpoint(struct connection *conn, int skip_user) {
} else if (conn->server->config_options[DOCUMENT_ROOT] == NULL) { } else if (conn->server->config_options[DOCUMENT_ROOT] == NULL) {
send_http_error(conn, 404, NULL); send_http_error(conn, 404, NULL);
#ifndef MONGOOSE_NO_AUTH #ifndef MONGOOSE_NO_AUTH
} else if ((!is_dav_request(conn) && !is_authorized(conn, path)) || } else if ((!is_dav_request(conn) && !is_authorized(conn, path,
exists && S_ISDIR(st.st_mode))) ||
(is_dav_request(conn) && !is_authorized_for_dav(conn))) { (is_dav_request(conn) && !is_authorized_for_dav(conn))) {
mg_send_digest_auth_request(&conn->mg_conn); mg_send_digest_auth_request(&conn->mg_conn);
close_local_endpoint(conn); close_local_endpoint(conn);
...@@ -4283,7 +4288,7 @@ static void open_local_endpoint(struct connection *conn, int skip_user) { ...@@ -4283,7 +4288,7 @@ static void open_local_endpoint(struct connection *conn, int skip_user) {
handle_put(conn, path); handle_put(conn, path);
#endif #endif
} else { } else {
mg_send_file(&conn->mg_conn, path); mg_send_file_internal(&conn->mg_conn, path, &st, exists);
} }
#endif // MONGOOSE_NO_FILESYSTEM #endif // MONGOOSE_NO_FILESYSTEM
} }
...@@ -4352,7 +4357,8 @@ static void on_recv_data(struct connection *conn) { ...@@ -4352,7 +4357,8 @@ static void on_recv_data(struct connection *conn) {
} }
try_parse(conn); try_parse(conn);
DBG(("%p %d %lu %d", conn, conn->request_len, (unsigned long)io->len, conn->ns_conn->flags)); DBG(("%p %d %lu %d", conn, conn->request_len, (unsigned long)io->len,
conn->ns_conn->flags));
if (conn->request_len < 0 || if (conn->request_len < 0 ||
(conn->request_len > 0 && !is_valid_uri(conn->mg_conn.uri))) { (conn->request_len > 0 && !is_valid_uri(conn->mg_conn.uri))) {
send_http_error(conn, 400, NULL); send_http_error(conn, 400, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment