Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
a0e54945
Commit
a0e54945
authored
May 30, 2013
by
Sergey Lyubka
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #177 from arvidn/master
support serving pre-gzipped files
parents
f62c7339
d283e316
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
62 additions
and
23 deletions
+62
-23
mongoose.c
mongoose.c
+62
-23
No files found.
mongoose.c
View file @
a0e54945
...
@@ -420,8 +420,11 @@ struct file {
...
@@ -420,8 +420,11 @@ struct file {
int64_t
size
;
int64_t
size
;
FILE
*
fp
;
FILE
*
fp
;
const
char
*
membuf
;
// Non-NULL if file data is in memory
const
char
*
membuf
;
// Non-NULL if file data is in memory
// set to 1 if the content is gzipped
// in which case we need a content-encoding: gzip header
int
gzipped
;
};
};
#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL}
#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL
, 0
}
// Describes listening socket, or socket which was accept()-ed by the master
// Describes listening socket, or socket which was accept()-ed by the master
// thread and queued for future handling by the worker thread.
// thread and queued for future handling by the worker thread.
...
@@ -1772,6 +1775,8 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
...
@@ -1772,6 +1775,8 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
const
char
*
rewrite
,
*
uri
=
conn
->
request_info
.
uri
;
const
char
*
rewrite
,
*
uri
=
conn
->
request_info
.
uri
;
char
*
p
;
char
*
p
;
int
match_len
;
int
match_len
;
char
gz_path
[
PATH_MAX
];
char
const
*
accept_encoding
;
// Using buf_len - 1 because memmove() for PATH_INFO may shift part
// Using buf_len - 1 because memmove() for PATH_INFO may shift part
// of the path one byte on the right.
// of the path one byte on the right.
...
@@ -1787,26 +1792,42 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
...
@@ -1787,26 +1792,42 @@ static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
}
}
}
}
if
(
!
mg_stat
(
conn
,
buf
,
filep
))
{
if
(
mg_stat
(
conn
,
buf
,
filep
))
return
;
// Support PATH_INFO for CGI scripts.
for
(
p
=
buf
+
strlen
(
buf
);
p
>
buf
+
1
;
p
--
)
{
// if we can't find the actual file, look for the file
if
(
*
p
==
'/'
)
{
// with the same name but a .gz extension. If we find it,
*
p
=
'\0'
;
// use that and set the gzipped flag in the file struct
if
(
match_prefix
(
conn
->
ctx
->
config
[
CGI_EXTENSIONS
],
// to indicate that the response need to have the content-
strlen
(
conn
->
ctx
->
config
[
CGI_EXTENSIONS
]),
buf
)
>
0
&&
// encoding: gzip header
mg_stat
(
conn
,
buf
,
filep
))
{
// we can only do this if the browser declares support
// Shift PATH_INFO block one character right, e.g.
if
((
accept_encoding
=
mg_get_header
(
conn
,
"Accept-Encoding"
))
!=
NULL
)
{
// "/x.cgi/foo/bar\x00" => "/x.cgi\x00/foo/bar\x00"
if
(
strstr
(
accept_encoding
,
"gzip"
)
!=
NULL
)
{
// conn->path_info is pointing to the local variable "path" declared
snprintf
(
gz_path
,
sizeof
(
gz_path
),
"%s.gz"
,
buf
);
// in handle_request(), so PATH_INFO is not valid after
if
(
mg_stat
(
conn
,
gz_path
,
filep
))
{
// handle_request returns.
filep
->
gzipped
=
1
;
conn
->
path_info
=
p
+
1
;
return
;
memmove
(
p
+
2
,
p
+
1
,
strlen
(
p
+
1
)
+
1
);
// +1 is for trailing \0
}
p
[
1
]
=
'/'
;
}
break
;
}
}
else
{
*
p
=
'/'
;
// Support PATH_INFO for CGI scripts.
}
for
(
p
=
buf
+
strlen
(
buf
);
p
>
buf
+
1
;
p
--
)
{
if
(
*
p
==
'/'
)
{
*
p
=
'\0'
;
if
(
match_prefix
(
conn
->
ctx
->
config
[
CGI_EXTENSIONS
],
strlen
(
conn
->
ctx
->
config
[
CGI_EXTENSIONS
]),
buf
)
>
0
&&
mg_stat
(
conn
,
buf
,
filep
))
{
// Shift PATH_INFO block one character right, e.g.
// "/x.cgi/foo/bar\x00" => "/x.cgi\x00/foo/bar\x00"
// conn->path_info is pointing to the local variable "path" declared
// in handle_request(), so PATH_INFO is not valid after
// handle_request returns.
conn
->
path_info
=
p
+
1
;
memmove
(
p
+
2
,
p
+
1
,
strlen
(
p
+
1
)
+
1
);
// +1 is for trailing \0
p
[
1
]
=
'/'
;
break
;
}
else
{
*
p
=
'/'
;
}
}
}
}
}
}
...
@@ -2828,17 +2849,29 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
...
@@ -2828,17 +2849,29 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
int64_t
cl
,
r1
,
r2
;
int64_t
cl
,
r1
,
r2
;
struct
vec
mime_vec
;
struct
vec
mime_vec
;
int
n
;
int
n
;
char
gz_path
[
PATH_MAX
];
char
const
*
encoding
=
""
;
get_mime_type
(
conn
->
ctx
,
path
,
&
mime_vec
);
get_mime_type
(
conn
->
ctx
,
path
,
&
mime_vec
);
cl
=
filep
->
size
;
cl
=
filep
->
size
;
conn
->
status_code
=
200
;
conn
->
status_code
=
200
;
range
[
0
]
=
'\0'
;
range
[
0
]
=
'\0'
;
// if this file is in fact a pre-gzipped file, rewrite its filename
// it's important to rewrite the filename after resolving
// the mime type from it, to preserve the actual file's type
if
(
filep
->
gzipped
)
{
snprintf
(
gz_path
,
sizeof
(
gz_path
),
"%s.gz"
,
path
);
path
=
gz_path
;
encoding
=
"Content-Encoding: gzip
\r\n
"
;
}
if
(
!
mg_fopen
(
conn
,
path
,
"rb"
,
filep
))
{
if
(
!
mg_fopen
(
conn
,
path
,
"rb"
,
filep
))
{
send_http_error
(
conn
,
500
,
http_500_error
,
send_http_error
(
conn
,
500
,
http_500_error
,
"fopen(%s): %s"
,
path
,
strerror
(
ERRNO
));
"fopen(%s): %s"
,
path
,
strerror
(
ERRNO
));
return
;
return
;
}
}
fclose_on_exec
(
filep
);
fclose_on_exec
(
filep
);
// If Range: header specified, act accordingly
// If Range: header specified, act accordingly
...
@@ -2846,6 +2879,12 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
...
@@ -2846,6 +2879,12 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
hdr
=
mg_get_header
(
conn
,
"Range"
);
hdr
=
mg_get_header
(
conn
,
"Range"
);
if
(
hdr
!=
NULL
&&
(
n
=
parse_range_header
(
hdr
,
&
r1
,
&
r2
))
>
0
&&
if
(
hdr
!=
NULL
&&
(
n
=
parse_range_header
(
hdr
,
&
r1
,
&
r2
))
>
0
&&
r1
>=
0
&&
r2
>=
0
)
{
r1
>=
0
&&
r2
>=
0
)
{
// actually, range requests don't play well with a pre-gzipped
// file (since the range is specified in the uncmpressed space)
if
(
filep
->
gzipped
)
{
send_http_error
(
conn
,
501
,
"Not Implemented"
,
"range requests in gzipped files are not supported"
);
return
;
}
conn
->
status_code
=
206
;
conn
->
status_code
=
206
;
cl
=
n
==
2
?
(
r2
>
cl
?
cl
:
r2
)
-
r1
+
1
:
cl
-
r1
;
cl
=
n
==
2
?
(
r2
>
cl
?
cl
:
r2
)
-
r1
+
1
:
cl
-
r1
;
mg_snprintf
(
conn
,
range
,
sizeof
(
range
),
mg_snprintf
(
conn
,
range
,
sizeof
(
range
),
...
@@ -2871,9 +2910,9 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
...
@@ -2871,9 +2910,9 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
"Content-Length: %"
INT64_FMT
"
\r\n
"
"Content-Length: %"
INT64_FMT
"
\r\n
"
"Connection: %s
\r\n
"
"Connection: %s
\r\n
"
"Accept-Ranges: bytes
\r\n
"
"Accept-Ranges: bytes
\r\n
"
"%s
\r\n
"
,
"%s
%s
\r\n
"
,
conn
->
status_code
,
msg
,
date
,
lm
,
etag
,
(
int
)
mime_vec
.
len
,
conn
->
status_code
,
msg
,
date
,
lm
,
etag
,
(
int
)
mime_vec
.
len
,
mime_vec
.
ptr
,
cl
,
suggest_connection_header
(
conn
),
range
);
mime_vec
.
ptr
,
cl
,
suggest_connection_header
(
conn
),
range
,
encoding
);
if
(
strcmp
(
conn
->
request_info
.
request_method
,
"HEAD"
)
!=
0
)
{
if
(
strcmp
(
conn
->
request_info
.
request_method
,
"HEAD"
)
!=
0
)
{
send_file_data
(
conn
,
filep
,
r1
,
cl
);
send_file_data
(
conn
,
filep
,
r1
,
cl
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment