MHEG5  18.9.0
MHEG5 Documentation
http_header.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2012 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include <assert.h>
27 #include <string.h>
28 #include <stdio.h>
29 
30 #include <glue_memory.h>
31 
32 #include "http_header.h"
33 
34 /*---constant definitions for this file--------------------------------------*/
35 
36 #define MAX_FIELD_NAME (32)
37 #define MAX_CONTENT_LENGTH (24)
38 
39 #define DBG(x)
40 
41 
42 /*---local typedef structs for this file-------------------------------------*/
43 
44 typedef enum
45 {
46  TOKEN_NUMBER = '0',
47  TOKEN_BYTES = 'b',
48  TOKEN_SPACE = ' ',
49  TOKEN_HYPHEN = '-',
50  TOKEN_SLASH = '/',
52 } TokenType;
53 
54 typedef struct sToken
55 {
59 } Token;
60 
61 /*---local function definitions----------------------------------------------*/
62 
63 /*---global function definitions---------------------------------------------*/
64 
65 static BOOLEAN GetNextToken(U8BIT **data, Token *token);
66 
67 
68 /*---local (static) variable declarations for this file----------------------*/
69 
70 
79 {
80  U8BIT name[MAX_FIELD_NAME];
81  U16BIT nameLen;
82  char *sep = "()<>@,;:\\\"/[]?={} \t";
83 
84  *field = HTTP_FIELD_UNKNOWN;
85  nameLen = 0;
86  while ((*data > 32) && (*data < 127) && (strchr(sep, *data) == NULL) &&
87  (nameLen < MAX_FIELD_NAME))
88  {
89  if (*data >= 'A' && *data <= 'Z')
90  {
91  /* Convert to lower-case as we go */
92  name[nameLen] = *data - 'A' + 'a';
93  }
94  else
95  {
96  name[nameLen] = *data;
97  }
98  ++nameLen;
99  ++data;
100  }
101 
102  if (nameLen <= MAX_FIELD_NAME && *data == ':')
103  {
104  /* Content-Length */
105  if (nameLen == 14 && memcmp(name, "content-length", 14) == 0)
106  {
107  *field = HTTP_FIELD_CONTENT_LENGTH;
108  }
109  else if (nameLen == 13 && memcmp(name, "content-range", 13) == 0)
110  {
111  *field = HTTP_FIELD_CONTENT_RANGE;
112  }
113  else if (nameLen == 12 && memcmp(name, "content-type", 12) == 0)
114  {
115  *field = HTTP_FIELD_CONTENT_TYPE;
116  }
117  else if (nameLen == 6 && memcmp(name, "x-keys", 6) == 0)
118  {
119  *field = HTTP_FIELD_X_KEYS;
120  }
121  else if (nameLen == 13 && memcmp(name, "x-keylocation", 13) == 0)
122  {
123  *field = HTTP_FIELD_X_KEY_LOCATION;
124  }
125  else if (nameLen == 16 && memcmp(name, "x-bytespersecond", 16) == 0)
126  {
128  }
129  ++data;
130  /* Skip LWS (linear white spaces) */
131  while (*data == '\r' || *data == '\n' || *data == ' ' || *data == '\t')
132  {
133  ++data;
134  }
135  /* data should now point at data for the field */
136  }
137 
138  return data;
139 }
140 
148 {
149  U64BIT contentLength;
151  Token token;
152  BOOLEAN success;
153 
154  ULL_SetInvalid(contentLength);
155 
156  /* The field is 1*DIGIT (one or more digits) */
157  success = GetNextToken(&data, &token);
158  if (success)
159  {
160  if ((token.type == TOKEN_NUMBER) &&
161  (token.len < MAX_CONTENT_LENGTH))
162  {
163  memcpy(buffer, token.data, token.len);
164  buffer[token.len] = '\0';
165  contentLength = ULONG_Atoi(buffer);
166  }
167  }
168  return contentLength;
169 }
170 
178 {
179  U64BIT contentLength;
181  Token token;
182  BOOLEAN success;
183 
184  /* The field is 1*DIGIT "-" 1*DIGIT "/" (1*DIGIT | "*"), but
185  * we're only interested in the last field.
186  */
187  success = GetNextToken(&data, &token);
188  if (success && token.type == TOKEN_BYTES)
189  {
190  success = GetNextToken(&data, &token);
191  }
192  if (success && token.type == TOKEN_SPACE)
193  {
194  success = GetNextToken(&data, &token);
195  }
196  if (success && token.type == TOKEN_NUMBER)
197  {
198  success = GetNextToken(&data, &token);
199  }
200  if (success && token.type == TOKEN_HYPHEN)
201  {
202  success = GetNextToken(&data, &token);
203  }
204  if (success && token.type == TOKEN_NUMBER)
205  {
206  success = GetNextToken(&data, &token);
207  }
208  if (success && token.type == TOKEN_SLASH)
209  {
210  success = GetNextToken(&data, &token);
211  }
212  /* if (token.type == TOKEN_ASTERISK)
213  {
214  // Unknown length, nothing to do
215  }
216  */
217  if (success &&
218  (token.type == TOKEN_NUMBER) &&
219  (token.len < MAX_CONTENT_LENGTH))
220  {
221  memcpy(buffer, token.data, token.len);
222  buffer[token.len] = '\0';
223  contentLength = ULONG_Atoi(buffer);
224  }
225  else
226  {
227  ULL_SetInvalid(contentLength);
228  }
229  return contentLength;
230 }
231 
232 /*******************
233  * LOCAL FUNCTION *
234  ********************/
235 
243 static BOOLEAN GetNextToken(U8BIT **data, Token *token)
244 {
245  BOOLEAN success;
246  U8BIT *p = *data;
247 
248  token->data = p;
249  switch (*p)
250  {
251  case '0': case '1': case '2': case '3': case '4':
252  case '5': case '6': case '7': case '8': case '9':
253  token->type = TOKEN_NUMBER;
254  do
255  {
256  ++p;
257  }
258  while (*p >= '0' && *p <= '9');
259  token->len = p - *data;
260  success = TRUE;
261  break;
262  case 'b':
263  do
264  {
265  ++p;
266  }
267  while (*p >= 'a' && *p <= 'z');
268  if (p - *data == 5 && memcmp(*data, "bytes", 5) == 0)
269  {
270  token->type = TOKEN_BYTES;
271  token->len = 5;
272  success = TRUE;
273  }
274  else
275  {
276  success = FALSE;
277  }
278  break;
279  case ' ':
280  token->type = TOKEN_SPACE;
281  token->len = 1;
282  success = TRUE;
283  break;
284  case '-':
285  token->type = TOKEN_HYPHEN;
286  token->len = 1;
287  success = TRUE;
288  break;
289  case '/':
290  token->type = TOKEN_SLASH;
291  token->len = 1;
292  success = TRUE;
293  break;
294  case '*':
295  token->type = TOKEN_ASTERISK;
296  token->len = 1;
297  success = TRUE;
298  break;
299  default:
300  success = FALSE;
301  break;
302  }
303 
304  if (success)
305  {
306  *data += token->len;
307  }
308 
309  return success;
310 }
311 
struct sToken Token
E_HTTP_FIELD
Definition: http_header.h:39
#define MAX_CONTENT_LENGTH
Definition: http_header.c:37
uint8_t U8BIT
Definition: techtype.h:82
Memory functions.
U64BIT ULONG_Atoi(char *str)
Convert a string to unsigned 64 bit. Only the numeric part of the string is converted (up to the firs...
Definition: glue_ulong.c:398
#define ULL_SetInvalid(variable)
Definition: glue_ulong.h:89
U64BIT httpHdrParseContentRange(U8BIT *data, U32BIT len)
Parse "Content-Range" header and return the content length in bytes.
Definition: http_header.c:177
TokenType type
Definition: http_header.c:56
U64BIT httpHdrParseContentLength(U8BIT *data, U32BIT len)
Parse "Content-Length" header and return the content length in bytes.
Definition: http_header.c:147
uint16_t U16BIT
Definition: techtype.h:84
#define MAX_FIELD_NAME
Definition: http_header.c:36
U8BIT * data
Definition: http_header.c:57
Definition: mg_png.c:52
#define FALSE
Definition: techtype.h:68
TokenType
Definition: http_header.c:44
U8BIT BOOLEAN
Definition: techtype.h:99
#define TRUE
Definition: techtype.h:69
uint32_t U32BIT
Definition: techtype.h:86
U8BIT * httpHdrParseFieldName(U8BIT *data, U32BIT len, E_HTTP_FIELD *field)
Parse field for its name in an HTTP header.
Definition: http_header.c:78
U16BIT len
Definition: http_header.c:58