TFCweb  1.0.4 $Rev: 483 $
TFC Primavera 2012: Nucli d'un servidor web
Servidor.h
Veure la documentació d'aquest fitxer.
1 #ifndef _SERVIDOR_H_
2 #define _SERVIDOR_H_
3 
11 /*
12  * Copyright (c) 2012 Toni Corvera
13  *
14  * This file is part of TFCWeb.
15  *
16  * TFCWeb is free software: you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation, either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * TFCWeb is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with TFCWeb. If not, see <http://www.gnu.org/licenses/>.
28  */
29 
30 #include "Excepcions.h"
31 #include "PeticioHTTP.h"
32 #include "portabilitat.h"
33 #include "Uri.h"
34 
35 #include <memory>
36 #include <sstream>
37 #include <boost/array.hpp>
38 #include <boost/asio.hpp>
39 #include <boost/enable_shared_from_this.hpp>
40 #include <boost/thread/xtime.hpp>
41 
45 namespace tfc {
46 
47 // Forward declarations
48 class Configuracio;
49 class RespostaHTTP;
50 class RecursDinamic;
51 class Ruta;
52 class UrlHTTP;
53 
57 class ErrorRebentDades : public ErrorTFC {
58 public:
59  explicit ErrorRebentDades(const std::string & w = "Error rebent dades")
60  : ErrorTFC(w)
61  {
62  // buit
63  }
64 };
65 
71 class Servidor
72 {
73 public:
75  typedef boost::asio::ip::tcp::socket socket_t;
77  typedef std::shared_ptr<socket_t> socket_ptr;
78 
79  Servidor(const Configuracio & c, socket_ptr & s) throw ();
80  Servidor(const Servidor & s) throw ()
81  : cfg(s.cfg), socket_(s.socket_), buffer_(s.buffer_.str())
82  {
83  assert( socket_->is_open() );
84  }
85  ~Servidor();
86 
87  // Factoria de sockets
88  static socket_ptr crea_socket(boost::asio::io_service & iosrv) {
89  return socket_ptr(new socket_t(iosrv));
90  }
91 
92  void aten() throw (ErrorHTTP);
93 
95  //void analitzar_peticio(const PeticioHTTP &); // <- Prototip
96  void interpretar_ruta(const Ruta &) const;
97 // void enviar_error(const FraseEstat &); // <- Unificat amb envia_resposta
98  void tancar_sessio();
99  //void carregar_configuracio(const Configuracio &);
101 
105  static const std::string& signatura();
106 private:
107  void envia_resposta(TipusPeticioHTTP, tfc::RespostaHTTP &) const
108  throw (ErrorEscrivintEnSocket);
109 
110  PeticioHTTP analitza_peticio() throw (ErrorHTTP);
111  void extreu_capsaleres(PeticioHTTP &) throw (ErrorHTTP, ErrorRebentDades);
112  void extreu_cos(PeticioHTTP &) throw (ErrorHTTP, ErrorRebentDades);
114  typedef std::unique_ptr<RespostaHTTP> resposta_uptr;
115 
116  //TODO: TRACE!
125  resposta_uptr aten_peticio_lectura(const Uri & u, PeticioHTTP & p) throw (ErrorHTTP);
134  resposta_uptr aten_peticio_escriptura(const Uri & u, PeticioHTTP & p) throw (ErrorHTTP);
143  resposta_uptr aten_peticio_informacio(const Uri & u, PeticioHTTP & p) throw (ErrorHTTP);
144 
145  const Configuracio & cfg;
147 
149  enum {
151  // Apache
152  // <http://httpd.apache.org/docs/2.0/mod/core.html#timeout>
153  // <http://httpd.apache.org/docs/2.0/mod/core.html#keepalivetimeout>
154  // Fa servir 300s per peticions i 15s per keep-alive.
155  // TFCWeb no fa aquesta distinció, i el timeout és el mateix. Més d'uns
156  // pocs segons sembla excessiu per la gran majoria de casos
157  TIMEOUT_RECEPCIO = 20*1000 // ms
158  };
159 
160  // TODO:
161  // Possibles implementacions de buffer
162  //boost::circular_buffer<char> buffer_real_;
163  //boost::asio::mutable_buffers_1 buffer_;
164 
165  // Lectura de socket
173  size_t llegeix_socket(std::stringstream & buffer,
174  unsigned int timeout_ms = TIMEOUT_RECEPCIO) throw (ErrorRebentDades);
178  size_t llegeix_socket(unsigned int timeout_ms = TIMEOUT_RECEPCIO)
179  throw (ErrorRebentDades) {
180  return llegeix_socket(this->buffer_, timeout_ms);
181  }
182 
187  size_t omple_buffer(unsigned int timeout_ms = TIMEOUT_RECEPCIO) throw (ErrorRebentDades);
188  std::stringstream buffer_;
189 };
190 
191 #if 0
192 class ControladorServei {
193 public:
194  ControladorServei(boost::asio::io_service & iosrv)
195  // FIXME: Port
196  : acceptador_(iosrv, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8000))
197  {
198  using boost::asio::ip::tcp;
199 
200  }
201 private:
202  boost::asio::ip::tcp::acceptor acceptador_;
203 };
204 #endif
205 
206 } // ns tfc
207 
208 #endif // _SERVIDOR_H_
209 
210 // vim:set ts=4 et ai: //