1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
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 //
9 #include <anna/http/parser/WaitMessage.hpp>
11 #include <anna/http/internal/Token.hpp>
12 #include <anna/http/Transport.hpp>
13 #include <anna/http/Method.hpp>
14 #include <anna/http/Request.hpp>
15 #include <anna/http/Response.hpp>
20 //----------------------------------------------------------------------------------------------------
21 // Todavia no se ha identificado el comienzo del mensaje HTTP. Comprueba el primer token de la
22 // linea para comprobar si se puede identificar una mensaje HTTP de tipo 'Response' o 'Request'.
24 // La expresion del mensaje HTTP sera:
26 // Mensahe HTTP := Request | Response
28 // Resquest := Method <sp> URI <sp> version <crlf> *(Header)<crlf><crlf> [Body]
29 // Response := version <sp> status_code <sp> phrase <crlf> *(Header)
31 // (1) Si recibimos una linea vacia o con solo CRLF's
32 // (2) Separa el contenido de la linea en los tokens. El separador seran espacios en blanco, tabs, etc.
33 // (3) Si estamos recibiendo un Request.
34 // (4) Si estamos recibiendo un Response
35 //----------------------------------------------------------------------------------------------------
36 int http::parser::WaitMessage::processLine(http::Transport& transport, const DataBlock&, const http::Token& line) const
37 throw(RuntimeException) {
38 if(line.getSize() == 0) // (1)
41 const Tokenizer& tokenizer = transport.split(line); // (2)
42 const Token* token = tokenizer [tokenizer.begin()];
47 if(Method::asType(token) != Method::Type::None) // (3)
48 if(setupRequest(transport, tokenizer) == true)
52 if(token->match("http/1.1") || token->match("http/1.0")) // (4)
53 setupResponse(transport, tokenizer);
59 //----------------------------------------------------------------------------------------------------
60 // (1) Verifica que en la linea solo esten los tres elementos esperados
61 //----------------------------------------------------------------------------------------------------
63 bool http::parser::WaitMessage::setupRequest(http::Transport& transport, const http::Tokenizer& tokenizer)
67 Tokenizer::const_iterator ii = tokenizer.begin();
70 if((token = tokenizer [ii ++]) == NULL)
73 const Method::Type::_v method = Method::asType(token);
75 if((token = tokenizer [ii ++]) == NULL)
78 const string& uri(token->getStringValue());
80 if((token = tokenizer [ii ++]) == NULL)
83 if(tokenizer [ii] != NULL) // (1)
86 const string& version(token->getStringValue());
87 http::Request* request = static_cast <http::Request*>(transport.allocateInputMessage(Message::Type::Request));
88 request->setMethod(method);
90 request->setVersion(version);
91 setState(transport, ClassType::ReadHeader);
92 } catch(RuntimeException&) {
99 //----------------------------------------------------------------------------------------------------
100 // (1) IN_NEMRD_01.00.00_http_001
101 //----------------------------------------------------------------------------------------------------
103 void http::parser::WaitMessage::setupResponse(http::Transport& transport, const http::Tokenizer& tokenizer)
106 Tokenizer::const_iterator ii = tokenizer.begin();
109 if((token = tokenizer [ii ++]) == NULL)
112 const string& version(token->getStringValue());
114 if((token = tokenizer [ii ++]) == NULL)
117 const int statusCode(token->getIntegerValue());
120 if((token = tokenizer [ii ++]) != NULL) { // (1)
121 reasonPhrase = token->getStringValue();
123 while((token = tokenizer [ii ++]) != NULL) {
125 reasonPhrase += token->getStringValue();
129 http::Response* response = static_cast <http::Response*>(transport.allocateInputMessage(Message::Type::Response));
130 response->setVersion(version);
131 response->setStatusCode(statusCode);
132 response->setReasonPhrase(reasonPhrase);
133 setState(transport, ClassType::ReadHeader);
134 } catch(RuntimeException&) {