Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F3075984
http_parser.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
http_parser.c
View Options
#include
<compat.h>
// IWYU pragma: keep
#include
<stdbool.h>
#include
<stdint.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
"ant.h"
#include
"errors.h"
#include
"internal.h"
#include
"http/http1_parser.h"
#include
"modules/buffer.h"
#include
"modules/http_parser.h"
static
ant_value_t
http_parser_make_buffer
(
ant_t
*
js
,
const
uint8_t
*
data
,
size_t
len
)
{
ArrayBufferData
*
ab
=
create_array_buffer_data
(
len
);
if
(
!
ab
)
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"Out of memory"
);
if
(
len
>
0
&&
data
)
memcpy
(
ab
->
data
,
data
,
len
);
return
create_typed_array
(
js
,
TYPED_ARRAY_UINT8
,
ab
,
0
,
len
,
"Buffer"
);
}
static
ant_value_t
http_parser_make_error
(
ant_t
*
js
,
const
char
*
message
,
const
char
*
code
,
size_t
bytes_parsed
)
{
ant_value_t
err
=
js_mkerr_typed
(
js
,
JS_ERR_SYNTAX
,
"%s"
,
message
?
message
:
"Invalid HTTP request"
);
if
(
!
is_err
(
err
))
return
err
;
if
(
code
)
js_set
(
js
,
err
,
"code"
,
js_mkstr
(
js
,
code
,
strlen
(
code
)));
js_set
(
js
,
err
,
"bytesParsed"
,
js_mknum
((
double
)
bytes_parsed
));
return
err
;
}
static
ant_value_t
http_parser_raw_headers_array
(
ant_t
*
js
,
const
ant_http1_parsed_request_t
*
parsed
)
{
ant_value_t
raw_headers
=
js_mkarr
(
js
);
const
ant_http_header_t
*
hdr
=
NULL
;
for
(
hdr
=
parsed
->
headers
;
hdr
;
hdr
=
hdr
->
next
)
{
js_arr_push
(
js
,
raw_headers
,
js_mkstr
(
js
,
hdr
->
name
,
strlen
(
hdr
->
name
)));
js_arr_push
(
js
,
raw_headers
,
js_mkstr
(
js
,
hdr
->
value
,
strlen
(
hdr
->
value
)));
}
return
raw_headers
;
}
static
ant_value_t
js_http_parser_parse_request
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
ant_http1_parsed_request_t
parsed
=
{
0
};
ant_http1_parse_result_t
result
=
ANT_HTTP1_PARSE_INCOMPLETE
;
ant_value_t
input
=
0
;
ant_value_t
out
=
0
;
ant_value_t
body
=
0
;
ant_value_t
version
=
0
;
const
uint8_t
*
bytes
=
NULL
;
size_t
len
=
0
;
const
char
*
error_reason
=
NULL
;
const
char
*
error_code
=
NULL
;
char
version_buf
[
8
]
=
{
0
};
if
(
nargs
<
1
)
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"parseRequest requires 1 argument"
);
input
=
args
[
0
];
if
(
!
buffer_source_get_bytes
(
js
,
input
,
&
bytes
,
&
len
))
{
ant_value_t
str_value
=
js_tostring_val
(
js
,
input
);
const
char
*
str
=
NULL
;
if
(
is_err
(
str_value
))
return
str_value
;
str
=
js_getstr
(
js
,
str_value
,
&
len
);
if
(
!
str
)
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"parseRequest input must be string or buffer-like"
);
bytes
=
(
const
uint8_t
*
)
str
;
}
result
=
ant_http1_parse_request
((
const
char
*
)
bytes
,
len
,
&
parsed
,
&
error_reason
,
&
error_code
);
if
(
result
==
ANT_HTTP1_PARSE_INCOMPLETE
)
return
js_mknull
();
if
(
result
==
ANT_HTTP1_PARSE_ERROR
)
return
http_parser_make_error
(
js
,
error_reason
,
error_code
,
parsed
.
consumed_len
);
out
=
js_mkobj
(
js
);
body
=
http_parser_make_buffer
(
js
,
parsed
.
body
,
parsed
.
body_len
);
if
(
is_err
(
body
))
{
ant_http1_free_parsed_request
(
&
parsed
);
return
body
;
}
snprintf
(
version_buf
,
sizeof
(
version_buf
),
"%u.%u"
,
parsed
.
http_major
,
parsed
.
http_minor
);
version
=
js_mkstr
(
js
,
version_buf
,
strlen
(
version_buf
));
js_set
(
js
,
out
,
"method"
,
js_mkstr
(
js
,
parsed
.
method
,
strlen
(
parsed
.
method
)));
js_set
(
js
,
out
,
"target"
,
js_mkstr
(
js
,
parsed
.
target
,
strlen
(
parsed
.
target
)));
js_set
(
js
,
out
,
"host"
,
parsed
.
host
?
js_mkstr
(
js
,
parsed
.
host
,
strlen
(
parsed
.
host
))
:
js_mknull
());
js_set
(
js
,
out
,
"contentType"
,
parsed
.
content_type
?
js_mkstr
(
js
,
parsed
.
content_type
,
strlen
(
parsed
.
content_type
))
:
js_mknull
());
js_set
(
js
,
out
,
"rawHeaders"
,
http_parser_raw_headers_array
(
js
,
&
parsed
));
js_set
(
js
,
out
,
"body"
,
body
);
js_set
(
js
,
out
,
"bodyLength"
,
js_mknum
((
double
)
parsed
.
body_len
));
js_set
(
js
,
out
,
"contentLength"
,
js_mknum
((
double
)
parsed
.
content_length
));
js_set
(
js
,
out
,
"absoluteTarget"
,
js_bool
(
parsed
.
absolute_target
));
js_set
(
js
,
out
,
"keepAlive"
,
js_bool
(
parsed
.
keep_alive
));
js_set
(
js
,
out
,
"httpVersionMajor"
,
js_mknum
((
double
)
parsed
.
http_major
));
js_set
(
js
,
out
,
"httpVersionMinor"
,
js_mknum
((
double
)
parsed
.
http_minor
));
js_set
(
js
,
out
,
"httpVersion"
,
version
);
js_set
(
js
,
out
,
"consumed"
,
js_mknum
((
double
)
parsed
.
consumed_len
));
ant_http1_free_parsed_request
(
&
parsed
);
return
out
;
}
ant_value_t
internal_http_parser_library
(
ant_t
*
js
)
{
ant_value_t
lib
=
js_mkobj
(
js
);
js_set
(
js
,
lib
,
"parseRequest"
,
js_mkfun
(
js_http_parser_parse_request
));
return
lib
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Apr 4, 3:06 AM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
521268
Default Alt Text
http_parser.c (4 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment