10
10
#include < boost/range/iterator_range.hpp>
11
11
#include < boost/logic/tribool.hpp>
12
12
#include < boost/fusion/tuple.hpp>
13
+ #include < boost/algorithm/string/classification.hpp>
13
14
14
15
namespace boost { namespace network { namespace http {
15
16
@@ -26,9 +27,11 @@ namespace boost { namespace network { namespace http {
26
27
, version_t1
27
28
, version_t2
28
29
, version_p
30
+ , version_slash
29
31
, version_d1
30
32
, version_dot
31
33
, version_d2
34
+ , version_cr
32
35
, version_done
33
36
, header_name
34
37
, header_colon
@@ -50,7 +53,7 @@ namespace boost { namespace network { namespace http {
50
53
template <class Range >
51
54
fusion::tuple<logic::tribool, iterator_range<typename Range::const_iterator> >
52
55
parse_until (state_t stop_state, Range & range) {
53
- logic::tribool parsed_ok;
56
+ logic::tribool parsed_ok = logic::indeterminate ;
54
57
typedef typename range_iterator<Range>::type iterator;
55
58
iterator start = boost::begin (range)
56
59
, end = boost::end (range)
@@ -60,12 +63,72 @@ namespace boost { namespace network { namespace http {
60
63
while (
61
64
!boost::empty (local_range)
62
65
&& stop_state != internal_state
63
- && parsed_ok == logic:: indeterminate
66
+ && indeterminate (parsed_ok)
64
67
) {
68
+ current_iterator = boost::begin (local_range);
65
69
switch (internal_state) {
70
+ case method_start:
71
+ if (algorithm::is_upper ()(*current_iterator)) internal_state = method_char;
72
+ else parsed_ok = false ;
73
+ break ;
74
+ case method_char:
75
+ if (algorithm::is_upper ()(*current_iterator)) break ;
76
+ else if (algorithm::is_space ()(*current_iterator)) internal_state = method_done;
77
+ else parsed_ok = false ;
78
+ break ;
79
+ case method_done:
80
+ if (algorithm::is_cntrl ()(*current_iterator)) parsed_ok = false ;
81
+ else if (algorithm::is_space ()(*current_iterator)) parsed_ok = false ;
82
+ else internal_state = uri_char;
83
+ break ;
84
+ case uri_char:
85
+ if (algorithm::is_cntrl ()(*current_iterator)) parsed_ok = false ;
86
+ else if (algorithm::is_space ()(*current_iterator)) internal_state = uri_done;
87
+ break ;
88
+ case uri_done:
89
+ if (*current_iterator == ' H' ) internal_state = version_h;
90
+ else parsed_ok = false ;
91
+ break ;
92
+ case version_h:
93
+ if (*current_iterator == ' T' ) internal_state = version_t1;
94
+ else parsed_ok = false ;
95
+ break ;
96
+ case version_t1:
97
+ if (*current_iterator == ' T' ) internal_state = version_t2;
98
+ else parsed_ok = false ;
99
+ break ;
100
+ case version_t2:
101
+ if (*current_iterator == ' P' ) internal_state = version_p;
102
+ else parsed_ok = false ;
103
+ break ;
104
+ case version_p:
105
+ if (*current_iterator == ' /' ) internal_state = version_slash;
106
+ else parsed_ok = false ;
107
+ break ;
108
+ case version_slash:
109
+ if (algorithm::is_digit ()(*current_iterator)) internal_state = version_d1;
110
+ else parsed_ok = false ;
111
+ break ;
112
+ case version_d1:
113
+ if (*current_iterator == ' .' ) internal_state = version_dot;
114
+ else parsed_ok = false ;
115
+ break ;
116
+ case version_dot:
117
+ if (algorithm::is_digit ()(*current_iterator)) internal_state = version_d2;
118
+ else parsed_ok = false ;
119
+ break ;
120
+ case version_d2:
121
+ if (*current_iterator == ' \r ' ) internal_state = version_cr;
122
+ else parsed_ok = false ;
123
+ break ;
124
+ case version_cr:
125
+ if (*current_iterator == ' \n ' ) internal_state = version_done;
126
+ else parsed_ok = false ;
127
+ break ;
66
128
default :
67
129
parsed_ok = false ;
68
130
};
131
+ if (internal_state == stop_state) parsed_ok = true ;
69
132
local_range = boost::make_iterator_range (
70
133
++current_iterator, end);
71
134
}
0 commit comments