Remove dynamic exceptions
[anna.git] / source / http / parser / ReadChunkSize.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <stdio.h>
10
11 #include <anna/core/tracing/Logger.hpp>
12
13 #include <anna/http/parser/ReadChunkSize.hpp>
14
15 #include <anna/http/Transport.hpp>
16 #include <anna/http/functions.hpp>
17 #include <anna/http/internal/defines.hpp>
18 #include <anna/http/internal/EncodedBlock.hpp>
19
20 using namespace std;
21 using namespace anna;
22
23 /*
24    Se ha comprobado que una vez que parace el Transfer-encoding puede haber un
25    número indeterminado de header antes del chunk (propiemente dicho), pero
26    siempre hay una línea en blanco, que indica que la siguiente línea es la que
27    contiene el tamaño del primer chunk, etc, etc
28
29    160: 6e 65 63 74 69 6f 6e 3a 20 4b 65 65 70 2d 41 6c   nection: Keep-Al
30    176: 69 76 65 0d 0a 54 72 61 6e 73 66 65 72 2d 45 6e   ive..Transfer-En
31    192: 63 6f 64 69 6e 67 3a 20 63 68 75 6e 6b 65 64 0d   coding: chunked.
32    208: 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74   .Content-Type: t
33    224: 65 78 74 2f 70 6c 61 69 6e 0d 0a 0d 0a 31 66 66   ext/plain....1ff     <================= ojo
34    240: 38 0d 0a 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e   8..<?xml version
35    256: 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d   ="1.0" encoding=
36
37    464: 4a 61 6e 20 31 39 39 35 20 32 32 3a 30 30 3a 30   Jan 1995 22:00:0
38    480: 30 20 47 4d 54 0d 0a 43 6f 6e 74 65 6e 74 2d 54   0 GMT..Content-T
39    496: 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c 0d 0a   ype: text/html..
40    512: 54 72 61 6e 73 66 65 72 2d 65 6e 63 6f 64 69 6e   Transfer-encodin
41    528: 67 3a 20 63 68 75 6e 6b 65 64 0d 0a 43 6f 6e 6e   g: chunked..Conn
42    544: 65 63 74 69 6f 6e 3a 20 4b 65 65 70 2d 41 6c 69   ection: Keep-Ali
43    560: 76 65 0d 0a 0d 0a 35 34 20 20 20 20 20 0d 0a 3c   ve....54     ..<     <================= ojo
44    576: 21 2d 2d 20 6c 30 37 2e 6d 65 6d 62 65 72 2e 75   !-- l07.member.u
45    592: 6b 6c 2e 79 61 68 6f 6f 2e 63 6f 6d 20 75 6e 63   kl.yahoo.com unc
46    608: 6f 6d 70 72 65 73 73 65 64 2f 63 68 75 6e 6b 65   ompressed/chunke
47    624: 64 20 57 65 64 20 53 65 70 20 20 33 20 31 30 3a   d Wed Sep  3 10:
48    640: 31 34 3a 31 31 20 47 4d 54 20 32 30 30 38 20 2d   14:11 GMT 2008 -
49    656: 2d 3e 0a 0d 0a 30 0d 0a 0d 0a                     ->...0....
50
51    HTTP/1.1 200 OK
52    Date: Fri, 31 Dec 1999 23:59:59 GMT
53    Content-Type: text/plain
54    Transfer-Encoding: chunked
55
56    1a; ignore-stuff-here
57    abcdefghijklmnopqrstuvwxyz
58    10
59    1234567890abcdef
60    0
61    some-footer: some-value
62    another-footer: another-value
63
64    Después del tamamño del chunk puede venir un "; y parámetros extras".
65 */
66 int http::parser::ReadChunkSize::processLine(http::Transport& transport, const DataBlock& dataBlock, const http::Token& line) const
67 noexcept(false) {
68   int chunkSize = 0;
69   EncodedBlock* encodedBlock = transport.getEncodedBlock();
70
71   if(line.contains(';') == false) {
72     const std::string& hexstr = line.getStringValue();
73     sscanf(hexstr.c_str(), "%x", &chunkSize);
74     encodedBlock->setExpectedSize(chunkSize);
75   } else {
76     const Tokenizer& tokenizer = transport.split(line, ';');
77     const Token* token = tokenizer [0];
78     const std::string& hexstr = token->getStringValue();
79     sscanf(hexstr.c_str(), "%x", &chunkSize);
80     encodedBlock->setExpectedSize(chunkSize);
81
82     /*
83      * Los parámetros extras se adjunta al http::Message para que estén accesibles
84      * al programador cuando se termine de recibir el mensaje.
85      * La clase EncodedBlock no es pública.
86      */
87     if((token = tokenizer [1]) != NULL) {
88       http::Message* message = transport.getInputMessage();
89       appendExtraParameter(message, token->getStringValue());
90     }
91   }
92
93   LOGDEBUG(
94     string msg("ExpectedChunkSize: ");
95     msg += anna::functions::asString(chunkSize);
96     Logger::debug(msg, ANNA_FILE_LOCATION);
97   );
98   setState(transport, (chunkSize == 0) ? ClassType::ReadChunkTrailers : ClassType::ReadChunkData);
99   return -1;
100 }
101