Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-SMF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-SMF
Commits
9d95c753
Commit
9d95c753
authored
May 22, 2020
by
Tien-Thinh Nguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use a simple parser for Mime/related part
parent
502f5ade
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
187 additions
and
604 deletions
+187
-604
src/api-server/api/IndividualSMContextApi.cpp
src/api-server/api/IndividualSMContextApi.cpp
+17
-72
src/api-server/api/SMContextsCollectionApi.cpp
src/api-server/api/SMContextsCollectionApi.cpp
+18
-60
src/common/amf.h
src/common/amf.h
+29
-0
src/common/utils/CMakeLists.txt
src/common/utils/CMakeLists.txt
+1
-0
src/common/utils/simple_parser.cpp
src/common/utils/simple_parser.cpp
+69
-0
src/common/utils/simple_parser.hpp
src/common/utils/simple_parser.hpp
+48
-0
src/test/amf_client/amf-client.cpp
src/test/amf_client/amf-client.cpp
+5
-3
src/utils/multipartparser.c
src/utils/multipartparser.c
+0
-325
src/utils/multipartparser.h
src/utils/multipartparser.h
+0
-144
No files found.
src/api-server/api/IndividualSMContextApi.cpp
View file @
9d95c753
...
...
@@ -43,10 +43,7 @@
#include "logger.hpp"
#include "Helpers.h"
extern
"C"
{
#include "multipartparser.h"
#include "dynamic_memory_check.h"
}
#include "simple_parser.hpp"
namespace
oai
{
namespace
smf_server
{
...
...
@@ -141,91 +138,39 @@ void IndividualSMContextApi::update_sm_context_handler(
Logger
::
smf_api_server
().
info
(
"Received a SM context update request from AMF."
);
Logger
::
smf_api_server
().
debug
(
"Request body: %s
\n
"
,
request
.
body
().
c_str
());
//find boundary
std
::
size_t
found
=
request
.
body
().
find
(
"Content-Type"
);
std
::
string
boundary_str
=
request
.
body
().
substr
(
2
,
found
-
4
);
Logger
::
smf_api_server
().
debug
(
"Boundary: %s"
,
boundary_str
.
c_str
());
SmContextUpdateMessage
smContextUpdateMessage
=
{
};
//step 1. use multipartparser to decode the request
multipartparser_callbacks_init
(
&
g_callbacks
);
g_callbacks
.
on_body_begin
=
&
on_body_begin
;
g_callbacks
.
on_part_begin
=
&
on_part_begin
;
g_callbacks
.
on_header_field
=
&
on_header_field
;
g_callbacks
.
on_header_value
=
&
on_header_value
;
g_callbacks
.
on_headers_complete
=
&
on_headers_complete
;
g_callbacks
.
on_data
=
&
on_data
;
g_callbacks
.
on_part_end
=
&
on_part_end
;
g_callbacks
.
on_body_end
=
&
on_body_end
;
multipartparser
parser
=
{
};
init_globals
();
multipartparser_init
(
&
parser
,
reinterpret_cast
<
const
char
*>
(
boundary_str
.
c_str
()));
unsigned
int
str_len
=
request
.
body
().
length
();
unsigned
char
*
data
=
(
unsigned
char
*
)
malloc
(
str_len
+
1
);
memset
(
data
,
0
,
str_len
+
1
);
memcpy
((
void
*
)
data
,
(
void
*
)
request
.
body
().
c_str
(),
str_len
);
//if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){
if
((
multipartparser_execute
(
&
parser
,
&
g_callbacks
,
reinterpret_cast
<
const
char
*>
(
data
),
str_len
)
!=
strlen
(
request
.
body
().
c_str
()))
or
(
!
g_body_begin_called
))
{
Logger
::
smf_api_server
().
debug
(
"The received message can not be parsed properly!"
);
//TODO: fix this issue
//response.send(Pistache::Http::Code::Bad_Request, "");
//return;
}
//simple parser
simple_parser
sp
=
{
};
sp
.
parse
(
request
.
body
());
free_wrapper
((
void
**
)
&
data
);
uint8_t
size
=
g_parts
.
size
();
Logger
::
smf_api_server
().
debug
(
"Number of MIME parts %d"
,
g_parts
.
size
());
part
p0
=
{
};
part
p1
=
{
};
if
(
size
>
0
)
{
p0
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 1: %s"
,
p0
.
body
.
c_str
());
}
if
(
size
>
1
)
{
p1
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 2: %s (%d bytes)"
,
p1
.
body
.
c_str
(),
p1
.
body
.
length
());
//part p2 = g_parts.front(); g_parts.pop_front();
//Logger::smf_api_server().debug("Request body, part 3: \n %s",p2.body.c_str());
}
std
::
vector
<
mime_part
>
parts
=
{
};
sp
.
get_mime_parts
(
parts
);
uint8_t
size
=
parts
.
size
();
Logger
::
smf_api_server
().
debug
(
"Number of MIME parts %d"
,
size
);
// Getting the body param
SmContextUpdateData
smContextUpdateData
=
{
};
try
{
if
(
size
>
0
)
{
nlohmann
::
json
::
parse
(
p
0
.
body
.
c_str
()).
get_to
(
smContextUpdateData
);
nlohmann
::
json
::
parse
(
p
arts
[
0
]
.
body
.
c_str
()).
get_to
(
smContextUpdateData
);
}
else
{
nlohmann
::
json
::
parse
(
request
.
body
().
c_str
()).
get_to
(
smContextUpdateData
);
}
smContextUpdateMessage
.
setJsonData
(
smContextUpdateData
);
if
(
size
>
1
)
{
if
(
smContextUpdateData
.
n2SmInfoIsSet
())
{
//N2 SM (for Session establishment, or for session modification)
Logger
::
smf_api_server
().
debug
(
"N2 SM information is set"
);
smContextUpdateMessage
.
setBinaryDataN2SmInformation
(
p1
.
body
);
}
if
(
smContextUpdateData
.
n1SmMsgIsSet
())
{
//N1 SM (for session modification, UE-initiated)
for
(
int
i
=
1
;
i
<
size
;
i
++
)
{
if
(
parts
[
i
].
content_type
.
compare
(
"application/vnd.3gpp.5gnas"
)
==
0
)
{
smContextUpdateMessage
.
setBinaryDataN1SmMessage
(
parts
[
i
].
body
);
Logger
::
smf_api_server
().
debug
(
"N1 SM message is set"
);
smContextUpdateMessage
.
setBinaryDataN1SmMessage
(
p1
.
body
);
}
else
if
(
parts
[
i
].
content_type
.
compare
(
"application/vnd.3gpp.ngap"
)
==
0
)
{
smContextUpdateMessage
.
setBinaryDataN2SmInformation
(
parts
[
i
].
body
);
Logger
::
smf_api_server
().
debug
(
"N2 SM information is set"
);
}
}
// Getting the path params
auto
smContextRef
=
request
.
param
(
":smContextRef"
).
as
<
std
::
string
>
();
this
->
update_sm_context
(
smContextRef
,
smContextUpdateMessage
,
response
);
...
...
src/api-server/api/SMContextsCollectionApi.cpp
View file @
9d95c753
...
...
@@ -43,8 +43,9 @@
#include "logger.hpp"
#include "Helpers.h"
#include "simple_parser.hpp"
extern
"C"
{
#include "multipartparser.h"
#include "dynamic_memory_check.h"
}
...
...
@@ -85,77 +86,34 @@ void SMContextsCollectionApi::post_sm_contexts_handler(
Logger
::
smf_api_server
().
debug
(
""
);
Logger
::
smf_api_server
().
info
(
"Received a SM context create request from AMF."
);
Logger
::
smf_api_server
().
debug
(
"Request body: %s"
,
request
.
body
().
c_str
());
//find boundary
std
::
size_t
found
=
request
.
body
().
find
(
"Content-Type"
);
std
::
string
boundary_str
=
request
.
body
().
substr
(
2
,
found
-
4
);
Logger
::
smf_api_server
().
debug
(
"Boundary: %s"
,
boundary_str
.
c_str
());
SmContextMessage
smContextMessage
=
{
};
SmContextCreateData
smContextCreateData
=
{
};
//step 1. use multipartparser to decode the request
multipartparser_callbacks_init
(
&
g_callbacks
);
g_callbacks
.
on_body_begin
=
&
on_body_begin
;
g_callbacks
.
on_part_begin
=
&
on_part_begin
;
g_callbacks
.
on_header_field
=
&
on_header_field
;
g_callbacks
.
on_header_value
=
&
on_header_value
;
g_callbacks
.
on_headers_complete
=
&
on_headers_complete
;
g_callbacks
.
on_data
=
&
on_data
;
g_callbacks
.
on_part_end
=
&
on_part_end
;
g_callbacks
.
on_body_end
=
&
on_body_end
;
multipartparser
parser
=
{
};
init_globals
();
multipartparser_init
(
&
parser
,
reinterpret_cast
<
const
char
*>
(
boundary_str
.
c_str
()));
unsigned
int
str_len
=
request
.
body
().
length
();
unsigned
char
*
data
=
(
unsigned
char
*
)
malloc
(
str_len
+
1
);
memset
(
data
,
0
,
str_len
+
1
);
memcpy
((
void
*
)
data
,
(
void
*
)
request
.
body
().
c_str
(),
str_len
);
//if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){
if
((
multipartparser_execute
(
&
parser
,
&
g_callbacks
,
reinterpret_cast
<
const
char
*>
(
data
),
str_len
)
!=
strlen
(
request
.
body
().
c_str
()))
or
(
!
g_body_begin_called
))
{
Logger
::
smf_api_server
().
debug
(
"The received message can not be parsed properly!"
);
//TODO: fix this issue
//response.send(Pistache::Http::Code::Bad_Request, "");
//return;
}
free_wrapper
((
void
**
)
&
data
);
//simple parser
simple_parser
sp
=
{
};
sp
.
parse
(
request
.
body
());
uint8_t
size
=
g_parts
.
size
();
Logger
::
smf_api_server
().
debug
(
"Number of MIME parts %d"
,
g_parts
.
size
());
std
::
vector
<
mime_part
>
parts
=
{
};
sp
.
get_mime_parts
(
parts
);
uint8_t
size
=
parts
.
size
();
Logger
::
smf_api_server
().
debug
(
"Number of MIME parts %d"
,
size
);
//at least 2 parts for Json data and N1 (+ N2)
if
(
g_parts
.
size
()
<
2
)
{
if
(
size
<
2
)
{
response
.
send
(
Pistache
::
Http
::
Code
::
Bad_Request
,
""
);
return
;
}
part
p0
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 1:
\n
%s"
,
p0
.
body
.
c_str
());
part
p1
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 2:
\n
%s"
,
p1
.
body
.
c_str
());
if
(
g_parts
.
size
()
>
0
)
{
part
p2
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 3:
\n
%s"
,
p2
.
body
.
c_str
());
}
//step 2. process the request
try
{
nlohmann
::
json
::
parse
(
p
0
.
body
.
c_str
()).
get_to
(
smContextCreateData
);
nlohmann
::
json
::
parse
(
p
arts
[
0
]
.
body
.
c_str
()).
get_to
(
smContextCreateData
);
smContextMessage
.
setJsonData
(
smContextCreateData
);
smContextMessage
.
setBinaryDataN1SmMessage
(
p1
.
body
);
if
(
parts
[
1
].
content_type
.
compare
(
"application/vnd.3gpp.5gnas"
)
==
0
)
{
smContextMessage
.
setBinaryDataN1SmMessage
(
parts
[
1
].
body
);
}
else
if
(
parts
[
1
].
content_type
.
compare
(
"application/vnd.3gpp.ngap"
)
==
0
)
{
smContextMessage
.
setBinaryDataN2SmInformation
(
parts
[
1
].
body
);
}
this
->
post_sm_contexts
(
smContextMessage
,
response
);
}
catch
(
nlohmann
::
detail
::
exception
&
e
)
{
//send a 400 error
...
...
src/common/amf.h
0 → 100644
View file @
9d95c753
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef FILE_AMF_SEEN
#define FILE_AMF_SEEN
#endif
src/common/utils/CMakeLists.txt
View file @
9d95c753
...
...
@@ -36,6 +36,7 @@ set(CN_UTILS_SRC STATIC
${
CMAKE_CURRENT_SOURCE_DIR
}
/pid_file.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/string.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/thread_sched.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/simple_parser.cpp
)
...
...
src/common/utils/simple_parser.cpp
0 → 100644
View file @
9d95c753
/* From https://gist.github.com/javiermon/6272065#file-gateway_netlink-c */
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "simple_parser.hpp"
#include "logger.hpp"
bool
simple_parser
::
parse
(
const
std
::
string
&
str
)
{
std
::
string
CRLF
=
"
\r\n
"
;
Logger
::
smf_app
().
debug
(
""
);
Logger
::
smf_app
().
debug
(
"Simple parser, parsing a string:"
);
Logger
::
smf_app
().
debug
(
"%s"
,
str
.
c_str
());
//find boundary
std
::
size_t
content_type_pos
=
str
.
find
(
"Content-Type"
);
//first part
if
((
content_type_pos
<=
4
)
or
(
content_type_pos
==
std
::
string
::
npos
))
return
false
;
std
::
string
boundary_str
=
str
.
substr
(
2
,
content_type_pos
-
4
);
// 2 for -- and 2 for CRLF
Logger
::
smf_app
().
debug
(
"Boundary: %s"
,
boundary_str
.
c_str
());
std
::
string
boundary_full
=
"--"
+
boundary_str
+
CRLF
;
std
::
string
last_boundary
=
"--"
+
boundary_str
+
"--"
+
CRLF
;
std
::
size_t
crlf_pos
=
str
.
find
(
CRLF
,
content_type_pos
);
std
::
size_t
boundary_pos
=
str
.
find
(
boundary_full
);
std
::
size_t
boundary_last_post
=
str
.
find
(
last_boundary
);
while
(
boundary_pos
<
boundary_last_post
)
{
mime_part
p
=
{
};
content_type_pos
=
str
.
find
(
"Content-Type"
,
boundary_pos
);
crlf_pos
=
str
.
find
(
CRLF
,
content_type_pos
);
if
((
content_type_pos
==
std
::
string
::
npos
)
or
(
crlf_pos
==
std
::
string
::
npos
))
break
;
p
.
content_type
=
str
.
substr
(
content_type_pos
+
14
,
crlf_pos
-
(
content_type_pos
+
14
));
Logger
::
smf_app
().
debug
(
"Content Type: %s"
,
p
.
content_type
.
c_str
());
crlf_pos
=
str
.
find
(
CRLF
+
CRLF
,
content_type_pos
);
//beginning of content
boundary_pos
=
str
.
find
(
boundary_full
,
crlf_pos
);
if
(
boundary_pos
==
std
::
string
::
npos
)
{
boundary_pos
=
str
.
find
(
last_boundary
,
crlf_pos
);
}
if
(
boundary_pos
>
0
)
{
p
.
body
=
str
.
substr
(
crlf_pos
+
4
,
boundary_pos
-
2
-
(
crlf_pos
+
4
));
Logger
::
smf_app
().
debug
(
"Body: %s"
,
p
.
body
.
c_str
());
mime_parts
.
push_back
(
p
);
}
}
return
true
;
}
void
simple_parser
::
get_mime_parts
(
std
::
vector
<
mime_part
>
&
parts
)
const
{
for
(
auto
it
:
mime_parts
)
{
parts
.
push_back
(
it
);
}
}
src/common/utils/simple_parser.hpp
0 → 100644
View file @
9d95c753
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file simple_parser.hpp
\brief
\author
\company Eurecom
\email:
*/
#ifndef FILE_SIMPLE_PARSER_HPP_SEEN
#define FILE_SIMPLE_PARSER_HPP_SEEN
# include <string>
#include <map>
#include <vector>
typedef
struct
mime_part
{
std
::
string
content_type
;
std
::
string
body
;
}
mime_part
;
class
simple_parser
{
public:
bool
parse
(
const
std
::
string
&
str
);
void
get_mime_parts
(
std
::
vector
<
mime_part
>
&
parts
)
const
;
private:
std
::
vector
<
mime_part
>
mime_parts
;
};
#endif
/* FILE_SIMPLE_PARSER_HPP_SEEN */
src/test/amf_client/amf-client.cpp
View file @
9d95c753
...
...
@@ -419,7 +419,6 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x06
,
size
);
//QoS Rules
std
::
cout
<<
"Buffer: "
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
printf
(
"%02x "
,
buffer
[
i
]);
...
...
@@ -1241,11 +1240,14 @@ int main(int argc, char *argv[]) {
usleep
(
200000
);
send_pdu_session_update_sm_context_ue_service_request_step2
(
smf_ip_address
);
usleep
(
200000
);
/*
//PDU Session Modification
send_pdu_session_modification_request_step1(smf_ip_address);
usleep(200000);
send_pdu_session_modification_request_step2(smf_ip_address);
usleep(200000);
send_pdu_session_modification_complete(smf_ip_address);
usleep(200000);
//PDU Session Release procedure
send_pdu_session_release_request(smf_ip_address);
usleep(200000);
...
...
@@ -1253,7 +1255,7 @@ int main(int argc, char *argv[]) {
usleep(200000);
send_pdu_session_release_complete(smf_ip_address);
usleep(200000);
//Release SM context
*/
//Release SM context
//send_release_sm_context_request(smf_ip_address);
return
0
;
}
...
...
src/utils/multipartparser.c
deleted
100644 → 0
View file @
502f5ade
This diff is collapsed.
Click to expand it.
src/utils/multipartparser.h
deleted
100644 → 0
View file @
502f5ade
/*
* https://github.com/iafonov/multipart-parser-c
*/
#ifndef MULTIPARTPARSER_H
#define MULTIPARTPARSER_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
typedef
struct
multipartparser
multipartparser
;
typedef
struct
multipartparser_callbacks
multipartparser_callbacks
;
typedef
int
(
*
multipart_cb
)
(
multipartparser
*
);
typedef
int
(
*
multipart_data_cb
)
(
multipartparser
*
,
const
char
*
data
,
size_t
size
);
struct
multipartparser
{
/** PRIVATE **/
char
boundary
[
70
];
int
boundary_length
;
int
index
;
uint16_t
state
;
/** PUBLIC **/
void
*
data
;
};
struct
multipartparser_callbacks
{
multipart_cb
on_body_begin
;
multipart_cb
on_part_begin
;
multipart_data_cb
on_header_field
;
multipart_data_cb
on_header_value
;
multipart_cb
on_headers_complete
;
multipart_data_cb
on_data
;
multipart_cb
on_part_end
;
multipart_cb
on_body_end
;
};
void
multipartparser_init
(
multipartparser
*
parser
,
const
char
*
boundary
);
void
multipartparser_callbacks_init
(
multipartparser_callbacks
*
callbacks
);
size_t
multipartparser_execute
(
multipartparser
*
parser
,
multipartparser_callbacks
*
callbacks
,
const
char
*
data
,
size_t
size
);
#ifdef __cplusplus
}
#define BOUNDARY "----Boundary"
typedef
struct
part
{
std
::
map
<
std
::
string
,
std
::
string
>
headers
;
std
::
string
body
;
}
part
;
static
multipartparser_callbacks
g_callbacks
;
static
bool
g_body_begin_called
;
static
std
::
string
g_header_name
;
static
std
::
string
g_header_value
;
static
std
::
list
<
part
>
g_parts
;
static
bool
g_body_end_called
;
static
void
init_globals
()
{
g_body_begin_called
=
false
;
g_header_name
.
clear
();
g_header_value
.
clear
();
g_parts
.
clear
();
g_body_end_called
=
false
;
}
static
int
on_body_begin
(
multipartparser
*
/*parser*/
)
{
g_body_begin_called
=
true
;
return
0
;
}
static
int
on_part_begin
(
multipartparser
*
/*parser*/
)
{
g_parts
.
push_back
(
part
());
return
0
;
}
static
void
on_header_done
()
{
g_parts
.
back
().
headers
[
g_header_name
]
=
g_header_value
;
g_header_name
.
clear
();
g_header_value
.
clear
();
}
static
int
on_header_field
(
multipartparser
*
/*parser*/
,
const
char
*
data
,
size_t
size
)
{
if
(
g_header_value
.
size
()
>
0
)
on_header_done
();
g_header_name
.
append
(
data
,
size
);
return
0
;
}
static
int
on_header_value
(
multipartparser
*
/*parser*/
,
const
char
*
data
,
size_t
size
)
{
g_header_value
.
append
(
data
,
size
);
return
0
;
}
static
int
on_headers_complete
(
multipartparser
*
/*parser*/
)
{
if
(
g_header_value
.
size
()
>
0
)
on_header_done
();
return
0
;
}
static
int
on_data
(
multipartparser
*
/*parser*/
,
const
char
*
data
,
size_t
size
)
{
std
::
string
str
;
//g_parts.back().body.append(data, size);
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
//printf("%02x ",data[i]);
str
.
push_back
(
data
[
i
]);
}
g_parts
.
back
().
body
.
append
(
str
);
return
0
;
}
static
int
on_part_end
(
multipartparser
*
/*parser*/
)
{
return
0
;
}
static
int
on_body_end
(
multipartparser
*
/*parser*/
)
{
g_body_end_called
=
true
;
return
0
;
}
#endif
#endif // MULTIPARTPARSER_H
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