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
1889e12b
Commit
1889e12b
authored
8 years ago
by
Marko Mikulicic
Committed by
Cesanta Bot
8 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support username:pass authority in HTTP/WS urls
PUBLISHED_FROM=39a1c2a271c5cd961670e11c830105c17ba0b2e4
parent
5e91d919
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
192 additions
and
20 deletions
+192
-20
intro.md
docs/c-api/http.h/intro.md
+1
-0
mg_send_websocket_handshake3.md
docs/c-api/http.h/mg_send_websocket_handshake3.md
+13
-0
intro.md
docs/c-api/http_server.h/intro.md
+2
-0
mg_get_http_basic_auth.md
docs/c-api/http_server.h/mg_get_http_basic_auth.md
+14
-0
mg_parse_http_basic_auth.md
docs/c-api/http_server.h/mg_parse_http_basic_auth.md
+13
-0
mongoose.c
mongoose.c
+127
-20
mongoose.h
mongoose.h
+22
-0
No files found.
docs/c-api/http.h/intro.md
View file @
1889e12b
...
...
@@ -10,6 +10,7 @@ items:
-
{
name
:
mg_send_websocket_framev.md
}
-
{
name
:
mg_send_websocket_handshake.md
}
-
{
name
:
mg_send_websocket_handshake2.md
}
-
{
name
:
mg_send_websocket_handshake3.md
}
-
{
name
:
mg_set_protocol_http_websocket.md
}
-
{
name
:
mg_url_decode.md
}
-
{
name
:
struct_http_message.md
}
...
...
This diff is collapsed.
Click to expand it.
docs/c-api/http.h/mg_send_websocket_handshake3.md
0 → 100644
View file @
1889e12b
---
title
:
"
mg_send_websocket_handshake3()"
decl_name
:
"
mg_send_websocket_handshake3"
symbol_kind
:
"
func"
signature
:
|
void mg_send_websocket_handshake3(struct mg_connection *nc, const char *path,
const char *host, const char *protocol,
const char *extra_headers, const char *user,
const char *pass);
---
Like mg_send_websocket_handshake2 but also passes basic auth header
This diff is collapsed.
Click to expand it.
docs/c-api/http_server.h/intro.md
View file @
1889e12b
...
...
@@ -4,6 +4,7 @@ symbol_kind: "intro"
decl_name
:
"
http_server.h"
items
:
-
{
name
:
mg_file_upload_handler.md
}
-
{
name
:
mg_get_http_basic_auth.md
}
-
{
name
:
mg_get_http_header.md
}
-
{
name
:
mg_get_http_var.md
}
-
{
name
:
mg_http_check_digest_auth.md
}
...
...
@@ -13,6 +14,7 @@ items:
-
{
name
:
mg_http_send_redirect.md
}
-
{
name
:
mg_http_serve_file.md
}
-
{
name
:
mg_parse_http.md
}
-
{
name
:
mg_parse_http_basic_auth.md
}
-
{
name
:
mg_parse_multipart.md
}
-
{
name
:
mg_printf_html_escape.md
}
-
{
name
:
mg_printf_http_chunk.md
}
...
...
This diff is collapsed.
Click to expand it.
docs/c-api/http_server.h/mg_get_http_basic_auth.md
0 → 100644
View file @
1889e12b
---
title
:
"
mg_get_http_basic_auth()"
decl_name
:
"
mg_get_http_basic_auth"
symbol_kind
:
"
func"
signature
:
|
int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,
char *pass, size_t pass_len);
---
Gets and parses the Authorization: Basic header
Returns -1 if no Authorization header is found, or if
mg_parse_http_basic_auth
fails parsing the resulting header.
This diff is collapsed.
Click to expand it.
docs/c-api/http_server.h/mg_parse_http_basic_auth.md
0 → 100644
View file @
1889e12b
---
title
:
"
mg_parse_http_basic_auth()"
decl_name
:
"
mg_parse_http_basic_auth"
symbol_kind
:
"
func"
signature
:
|
int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,
char *pass, size_t pass_len);
---
Parses the Authorization: Basic header
Returns -1 iif the authorization type is not "Basic" or any other error such
as incorrectly encoded base64 user password pair.
This diff is collapsed.
Click to expand it.
mongoose.c
View file @
1889e12b
...
...
@@ -110,6 +110,11 @@ MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,
struct
http_message
*
hm
,
char
*
buf
,
size_t
blen
);
MG_INTERNAL
int
mg_http_common_url_parse
(
const
char
*
url
,
const
char
*
schema
,
const
char
*
schema_tls
,
int
*
use_ssl
,
char
**
user
,
char
**
pass
,
char
**
addr
,
int
*
port_i
,
const
char
**
path
);
#if MG_ENABLE_FILESYSTEM
MG_INTERNAL
int
mg_uri_to_local_path
(
struct
http_message
*
hm
,
const
struct
mg_serve_http_opts
*
opts
,
...
...
@@ -4389,7 +4394,7 @@ static void mg_http_conn_destructor(void *proto_data);
struct
mg_connection
*
mg_connect_http_base
(
struct
mg_mgr
*
mgr
,
mg_event_handler_t
ev_handler
,
struct
mg_connect_opts
opts
,
const
char
*
schema
,
const
char
*
schema_ssl
,
const
char
*
url
,
const
char
**
path
,
char
**
addr
);
const
char
*
url
,
const
char
**
path
,
char
**
user
,
char
**
pass
,
char
**
addr
);
static
struct
mg_http_proto_data
*
mg_http_get_proto_data
(
struct
mg_connection
*
c
)
{
...
...
@@ -5872,6 +5877,35 @@ int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
return
len
;
}
int
mg_get_http_basic_auth
(
struct
http_message
*
hm
,
char
*
user
,
size_t
user_len
,
char
*
pass
,
size_t
pass_len
)
{
struct
mg_str
*
hdr
=
mg_get_http_header
(
hm
,
"Authorization"
);
if
(
hdr
==
NULL
)
return
-
1
;
return
mg_parse_http_basic_auth
(
hdr
,
user
,
user_len
,
pass
,
pass_len
);
}
int
mg_parse_http_basic_auth
(
struct
mg_str
*
hdr
,
char
*
user
,
size_t
user_len
,
char
*
pass
,
size_t
pass_len
)
{
char
*
buf
=
NULL
;
char
fmt
[
64
];
int
res
=
0
;
if
(
mg_strncmp
(
*
hdr
,
mg_mk_str
(
"Basic "
),
6
)
!=
0
)
return
-
1
;
buf
=
(
char
*
)
MG_MALLOC
(
hdr
->
len
);
cs_base64_decode
((
unsigned
char
*
)
hdr
->
p
+
6
,
hdr
->
len
,
buf
);
/* e.g. "%123[^:]:%321[^\n]" */
snprintf
(
fmt
,
sizeof
(
fmt
),
"%%%"
SIZE_T_FMT
"[^:]:%%%"
SIZE_T_FMT
"[^
\n
]"
,
user_len
-
1
,
pass_len
-
1
);
if
(
sscanf
(
buf
,
fmt
,
user
,
pass
)
==
0
)
{
res
=
-
1
;
}
MG_FREE
(
buf
);
return
res
;
}
#if MG_ENABLE_FILESYSTEM
static
int
mg_is_file_hidden
(
const
char
*
path
,
const
struct
mg_serve_http_opts
*
opts
,
...
...
@@ -6291,7 +6325,8 @@ void mg_http_reverse_proxy(struct mg_connection *nc,
(
int
)
(
hm
->
uri
.
len
-
mount
.
len
),
hm
->
uri
.
p
+
mount
.
len
);
be
=
mg_connect_http_base
(
nc
->
mgr
,
mg_reverse_proxy_handler
,
opts
,
"http://"
,
"https://"
,
purl
,
&
path
,
&
addr
);
"https://"
,
purl
,
&
path
,
NULL
/* user */
,
NULL
/* pass */
,
&
addr
);
DBG
((
"Proxying %.*s to %s (rule: %.*s)"
,
(
int
)
hm
->
uri
.
len
,
hm
->
uri
.
p
,
purl
,
(
int
)
mount
.
len
,
mount
.
p
));
...
...
@@ -6765,11 +6800,15 @@ void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
#endif
/* MG_ENABLE_FILESYSTEM */
/* returns 0 on success, -1 on error */
static
int
mg_http_common_url_parse
(
const
char
*
url
,
const
char
*
schema
,
const
char
*
schema_tls
,
int
*
use_ssl
,
char
**
addr
,
int
*
port_i
,
const
char
**
path
)
{
MG_INTERNAL
int
mg_http_common_url_parse
(
const
char
*
url
,
const
char
*
schema
,
const
char
*
schema_tls
,
int
*
use_ssl
,
char
**
user
,
char
**
pass
,
char
**
addr
,
int
*
port_i
,
const
char
**
path
)
{
int
addr_len
=
0
;
int
auth_sep_pos
=
-
1
;
int
user_sep_pos
=
-
1
;
(
void
)
user
;
(
void
)
pass
;
if
(
memcmp
(
url
,
schema
,
strlen
(
schema
))
==
0
)
{
url
+=
strlen
(
schema
);
...
...
@@ -6790,11 +6829,17 @@ static int mg_http_common_url_parse(const char *url, const char *schema,
if
(
*
url
==
'/'
)
{
break
;
}
if
(
*
url
==
'@'
)
{
auth_sep_pos
=
addr_len
;
user_sep_pos
=
*
port_i
;
*
port_i
=
-
1
;
}
if
(
*
url
==
':'
)
*
port_i
=
addr_len
;
(
*
addr
)[
addr_len
++
]
=
*
url
;
(
*
addr
)[
addr_len
]
=
'\0'
;
url
++
;
}
if
(
addr_len
==
0
)
goto
cleanup
;
if
(
*
port_i
<
0
)
{
*
port_i
=
addr_len
;
...
...
@@ -6807,6 +6852,25 @@ static int mg_http_common_url_parse(const char *url, const char *schema,
if
(
**
path
==
'\0'
)
*
path
=
"/"
;
if
(
user
!=
NULL
&&
pass
!=
NULL
)
{
if
(
auth_sep_pos
==
-
1
)
{
*
user
=
NULL
;
*
pass
=
NULL
;
}
else
{
/* user is from 0 to user_sep_pos */
*
user
=
(
char
*
)
MG_MALLOC
(
user_sep_pos
+
1
);
memcpy
(
*
user
,
*
addr
,
user_sep_pos
);
(
*
user
)[
user_sep_pos
]
=
'\0'
;
/* pass is from user_sep_pos + 1 to auth_sep_pos */
*
pass
=
(
char
*
)
MG_MALLOC
(
auth_sep_pos
-
user_sep_pos
-
1
+
1
);
memcpy
(
*
pass
,
*
addr
+
user_sep_pos
+
1
,
auth_sep_pos
-
user_sep_pos
-
1
);
(
*
pass
)[
auth_sep_pos
-
user_sep_pos
-
1
]
=
'\0'
;
/* move address proper to the front */
memmove
(
*
addr
,
*
addr
+
auth_sep_pos
+
1
,
addr_len
-
auth_sep_pos
);
}
}
DBG
((
"%s %s"
,
*
addr
,
*
path
));
return
0
;
...
...
@@ -6819,13 +6883,13 @@ cleanup:
struct
mg_connection
*
mg_connect_http_base
(
struct
mg_mgr
*
mgr
,
mg_event_handler_t
ev_handler
,
struct
mg_connect_opts
opts
,
const
char
*
schema
,
const
char
*
schema_ssl
,
const
char
*
url
,
const
char
**
path
,
char
**
addr
)
{
const
char
*
url
,
const
char
**
path
,
char
**
user
,
char
**
pass
,
char
**
addr
)
{
struct
mg_connection
*
nc
=
NULL
;
int
port_i
=
-
1
;
int
use_ssl
=
0
;
if
(
mg_http_common_url_parse
(
url
,
schema
,
schema_ssl
,
&
use_ssl
,
addr
,
&
port_i
,
path
)
<
0
)
{
if
(
mg_http_common_url_parse
(
url
,
schema
,
schema_ssl
,
&
use_ssl
,
user
,
pass
,
addr
,
&
port_i
,
path
)
<
0
)
{
MG_SET_PTRPTR
(
opts
.
error_string
,
"cannot parse url"
);
return
NULL
;
}
...
...
@@ -6843,7 +6907,9 @@ struct mg_connection *mg_connect_http_base(
}
#else
MG_SET_PTRPTR
(
opts
.
error_string
,
"ssl is disabled"
);
MG_FREE
(
addr
);
if
(
user
!=
NULL
)
MG_FREE
(
*
user
);
if
(
pass
!=
NULL
)
MG_FREE
(
*
pass
);
MG_FREE
(
*
addr
);
return
NULL
;
#endif
}
...
...
@@ -6863,22 +6929,32 @@ struct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr,
const
char
*
url
,
const
char
*
extra_headers
,
const
char
*
post_data
)
{
char
*
addr
=
NULL
;
char
*
user
=
NULL
,
*
pass
=
NULL
,
*
addr
=
NULL
;
const
char
*
path
=
NULL
;
struct
mg_connection
*
nc
=
mg_connect_http_base
(
mgr
,
ev_handler
,
opts
,
"http://"
,
"https://"
,
url
,
&
path
,
&
addr
);
struct
mbuf
auth
;
struct
mg_connection
*
nc
=
mg_connect_http_base
(
mgr
,
ev_handler
,
opts
,
"http://"
,
"https://"
,
url
,
&
path
,
&
user
,
&
pass
,
&
addr
);
if
(
nc
==
NULL
)
{
return
NULL
;
}
mbuf_init
(
&
auth
,
0
);
if
(
user
!=
NULL
)
{
mg_basic_auth_header
(
user
,
pass
,
&
auth
);
}
mg_printf
(
nc
,
"%s %s HTTP/1.1
\r\n
Host: %s
\r\n
Content-Length: %"
SIZE_T_FMT
"
\r\n
%s
\r\n
%s"
,
"
\r\n
%
.*s%
s
\r\n
%s"
,
post_data
==
NULL
?
"GET"
:
"POST"
,
path
,
addr
,
post_data
==
NULL
?
0
:
strlen
(
post_data
),
post_data
==
NULL
?
0
:
strlen
(
post_data
),
(
int
)
auth
.
len
,
auth
.
buf
,
extra_headers
==
NULL
?
""
:
extra_headers
,
post_data
==
NULL
?
""
:
post_data
);
mbuf_free
(
&
auth
);
MG_FREE
(
user
);
MG_FREE
(
pass
);
MG_FREE
(
addr
);
return
nc
;
}
...
...
@@ -8222,6 +8298,16 @@ MG_INTERNAL void mg_ws_handshake(struct mg_connection *nc,
void
mg_send_websocket_handshake2
(
struct
mg_connection
*
nc
,
const
char
*
path
,
const
char
*
host
,
const
char
*
protocol
,
const
char
*
extra_headers
)
{
mg_send_websocket_handshake3
(
nc
,
path
,
host
,
protocol
,
extra_headers
,
NULL
,
NULL
);
}
void
mg_send_websocket_handshake3
(
struct
mg_connection
*
nc
,
const
char
*
path
,
const
char
*
host
,
const
char
*
protocol
,
const
char
*
extra_headers
,
const
char
*
user
,
const
char
*
pass
)
{
struct
mbuf
auth
;
const
char
*
authstr
=
""
;
char
key
[
25
];
uint32_t
nonce
[
4
];
nonce
[
0
]
=
mg_ws_random_mask
();
...
...
@@ -8230,13 +8316,28 @@ void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
nonce
[
3
]
=
mg_ws_random_mask
();
mg_base64_encode
((
unsigned
char
*
)
&
nonce
,
sizeof
(
nonce
),
key
);
mbuf_init
(
&
auth
,
0
);
if
(
user
!=
NULL
)
{
mg_basic_auth_header
(
user
,
pass
,
&
auth
);
/*
* cc3200 libc is broken: it doesn't like zero length to be passed to %.*s
* i.e. sprintf("f%.*so", (int)0, ""), yields `f\0o`.
* Thus we ensure the header fragment is null terminated and use `%s` below.
*/
mbuf_append
(
&
auth
,
""
,
1
);
authstr
=
auth
.
buf
;
}
mg_printf
(
nc
,
"GET %s HTTP/1.1
\r\n
"
"Upgrade: websocket
\r\n
"
"Connection: Upgrade
\r\n
"
"%s"
"Sec-WebSocket-Version: 13
\r\n
"
"Sec-WebSocket-Key: %s
\r\n
"
,
path
,
key
);
path
,
authstr
,
key
);
/* TODO(mkm): take default hostname from http proto data if host == NULL */
if
(
host
!=
MG_WS_NO_HOST_HEADER_MAGIC
)
{
...
...
@@ -8249,6 +8350,8 @@ void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
mg_printf
(
nc
,
"%s"
,
extra_headers
);
}
mg_printf
(
nc
,
"
\r\n
"
);
mbuf_free
(
&
auth
);
}
void
mg_send_websocket_handshake
(
struct
mg_connection
*
nc
,
const
char
*
path
,
...
...
@@ -8262,16 +8365,20 @@ struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,
struct
mg_connect_opts
opts
,
const
char
*
url
,
const
char
*
protocol
,
const
char
*
extra_headers
)
{
char
*
addr
=
NULL
;
char
*
user
=
NULL
,
*
pass
=
NULL
,
*
addr
=
NULL
;
const
char
*
path
=
NULL
;
struct
mg_connection
*
nc
=
mg_connect_http_base
(
mgr
,
ev_handler
,
opts
,
"ws://"
,
"wss://"
,
url
,
&
path
,
&
addr
);
struct
mg_connection
*
nc
=
mg_connect_http_base
(
mgr
,
ev_handler
,
opts
,
"ws://"
,
"wss://"
,
url
,
&
path
,
&
user
,
&
pass
,
&
addr
);
if
(
nc
!=
NULL
)
{
mg_send_websocket_handshake2
(
nc
,
path
,
addr
,
protocol
,
extra_headers
);
mg_send_websocket_handshake3
(
nc
,
path
,
addr
,
protocol
,
extra_headers
,
user
,
pass
);
}
MG_FREE
(
addr
);
MG_FREE
(
user
);
MG_FREE
(
pass
);
return
nc
;
}
...
...
This diff is collapsed.
Click to expand it.
mongoose.h
View file @
1889e12b
...
...
@@ -4000,6 +4000,11 @@ void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
const
char
*
host
,
const
char
*
protocol
,
const
char
*
extra_headers
);
/* Like mg_send_websocket_handshake2 but also passes basic auth header */
void
mg_send_websocket_handshake3
(
struct
mg_connection
*
nc
,
const
char
*
path
,
const
char
*
host
,
const
char
*
protocol
,
const
char
*
extra_headers
,
const
char
*
user
,
const
char
*
pass
);
/*
* Helper function that creates an outbound WebSocket connection.
*
...
...
@@ -4171,6 +4176,23 @@ struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
int
mg_http_parse_header
(
struct
mg_str
*
hdr
,
const
char
*
var_name
,
char
*
buf
,
size_t
buf_size
);
/*
* Gets and parses the Authorization: Basic header
* Returns -1 if no Authorization header is found, or if
* mg_parse_http_basic_auth
* fails parsing the resulting header.
*/
int
mg_get_http_basic_auth
(
struct
http_message
*
hm
,
char
*
user
,
size_t
user_len
,
char
*
pass
,
size_t
pass_len
);
/*
* Parses the Authorization: Basic header
* Returns -1 iif the authorization type is not "Basic" or any other error such
* as incorrectly encoded base64 user password pair.
*/
int
mg_parse_http_basic_auth
(
struct
mg_str
*
hdr
,
char
*
user
,
size_t
user_len
,
char
*
pass
,
size_t
pass_len
);
/*
* Parses the buffer `buf`, `buf_len` that contains multipart form data chunks.
* Stores the chunk name in a `var_name`, `var_name_len` buffer.
...
...
This diff is collapsed.
Click to expand it.
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