GNU libmicrohttpd
0.9.29
Main Page
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
stream.c
Go to the documentation of this file.
1
/*
2
This file is part of libmicrospdy
3
Copyright (C) 2012 Andrey Uzunov
4
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
25
#include "
platform.h
"
26
#include "
structures.h
"
27
#include "
internal.h
"
28
#include "
session.h
"
29
30
31
int
32
SPDYF_stream_new
(
struct
SPDY_Session
*session)
33
{
34
uint32_t stream_id;
35
uint32_t assoc_stream_id;
36
uint8_t priority;
37
uint8_t slot;
38
size_t
buffer_pos = session->
read_buffer_beginning
;
39
struct
SPDYF_Stream
*stream;
40
struct
SPDYF_Control_Frame *frame;
41
42
if
((session->
read_buffer_offset
- session->
read_buffer_beginning
) < 10)
43
{
44
//not all fields are received to create new stream
45
return
SPDY_NO
;
46
}
47
48
frame = (
struct
SPDYF_Control_Frame *)session->
frame_handler_cls
;
49
50
//get stream id of the new stream
51
memcpy(&stream_id, session->
read_buffer
+ session->
read_buffer_beginning
, 4);
52
stream_id =
NTOH31
(stream_id);
53
session->
read_buffer_beginning
+= 4;
54
if
(stream_id <= session->last_in_stream_id || 0==(stream_id % 2))
55
{
56
//wrong stream id sent by client
57
//GOAWAY with PROTOCOL_ERROR MUST be sent
58
//TODO
59
60
//ignore frame
61
session->
frame_handler
= &
SPDYF_handler_ignore_frame
;
62
return
SPDY_NO
;
63
}
64
else
if
(session->
is_goaway_sent
)
65
{
66
//the client is not allowed to create new streams anymore
67
//we MUST ignore the frame
68
session->
frame_handler
= &
SPDYF_handler_ignore_frame
;
69
return
SPDY_NO
;
70
}
71
72
//set highest stream id for session
73
session->
last_in_stream_id
= stream_id;
74
75
//get assoc stream id of the new stream
76
//this value is used with SPDY PUSH, thus nothing to do with it here
77
memcpy(&assoc_stream_id, session->
read_buffer
+ session->
read_buffer_beginning
, 4);
78
assoc_stream_id =
NTOH31
(assoc_stream_id);
79
session->
read_buffer_beginning
+= 4;
80
81
//get stream priority (3 bits)
82
//after it there are 5 bits that are not used
83
priority = *(uint8_t *)(session->
read_buffer
+ session->
read_buffer_beginning
) >> 5;
84
session->
read_buffer_beginning
++;
85
86
//get slot (see SPDY draft)
87
slot = *(uint8_t *)(session->
read_buffer
+ session->
read_buffer_beginning
);
88
session->
read_buffer_beginning
++;
89
90
if
(
NULL
== (stream = malloc(
sizeof
(
struct
SPDYF_Stream
))))
91
{
92
SPDYF_DEBUG
(
"No memory"
);
93
//revert buffer state
94
session->
read_buffer_beginning
= buffer_pos;
95
return
SPDY_NO
;
96
}
97
memset(stream,0,
sizeof
(
struct
SPDYF_Stream
));
98
stream->
session
= session;
99
stream->
stream_id
= stream_id;
100
stream->
assoc_stream_id
= assoc_stream_id;
101
stream->
priority
= priority;
102
stream->
slot
= slot;
103
stream->
is_in_closed
= (frame->flags &
SPDY_SYN_STREAM_FLAG_FIN
) != 0;
104
stream->
flag_unidirectional
= (frame->flags &
SPDY_SYN_STREAM_FLAG_UNIDIRECTIONAL
) != 0;
105
stream->
is_out_closed
= stream->
flag_unidirectional
;
106
stream->
is_server_initiator
=
false
;
107
stream->
window_size
=
SPDYF_INITIAL_WINDOW_SIZE
;
108
109
//put the stream to the list of streams for the session
110
DLL_insert
(session->
streams_head
, session->
streams_tail
, stream);
111
112
return
SPDY_YES
;
113
}
114
115
116
void
117
SPDYF_stream_destroy
(
struct
SPDYF_Stream
*stream)
118
{
119
SPDY_name_value_destroy
(stream->
headers
);
120
free(stream);
121
stream =
NULL
;
122
}
123
124
125
void
126
SPDYF_stream_set_flags_on_write
(
struct
SPDYF_Response_Queue
*response_queue)
127
{
128
struct
SPDYF_Stream
* stream = response_queue->
stream
;
129
130
if
(
NULL
!= response_queue->
data_frame
)
131
{
132
stream->
is_out_closed
= (bool)(response_queue->
data_frame
->flags &
SPDY_DATA_FLAG_FIN
);
133
}
134
else
if
(
NULL
!= response_queue->
control_frame
)
135
{
136
switch
(response_queue->
control_frame
->type)
137
{
138
case
SPDY_CONTROL_FRAME_TYPES_SYN_REPLY
:
139
stream->
is_out_closed
= (bool)(response_queue->
control_frame
->flags &
SPDY_SYN_REPLY_FLAG_FIN
);
140
break
;
141
142
case
SPDY_CONTROL_FRAME_TYPES_RST_STREAM
:
143
if
(
NULL
!= stream)
144
{
145
stream->
is_out_closed
=
true
;
146
stream->
is_in_closed
=
true
;
147
}
148
break
;
149
150
}
151
}
152
}
153
154
155
//TODO add function *on_read
156
157
158
struct
SPDYF_Stream
*
159
SPDYF_stream_find
(uint32_t
stream_id
,
struct
SPDY_Session
*
session
)
160
{
161
struct
SPDYF_Stream
* stream = session->
streams_head
;
162
163
while
(
NULL
!= stream && stream_id != stream->
stream_id
)
164
{
165
stream = stream->
next
;
166
}
167
168
return
stream;
169
}
src
microspdy
stream.c
Generated by
1.8.3.1