147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_HTTPSERVER_H__
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_HTTPSERVER_H__
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <map>
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpbase.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass AsyncSocket;
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass HttpServer;
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SocketAddress;
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//////////////////////////////////////////////////////////////////////
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// HttpServer
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//////////////////////////////////////////////////////////////////////
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst int HTTP_INVALID_CONNECTION_ID = 0;
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct HttpServerTransaction : public HttpTransaction {
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgpublic:
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HttpServerTransaction(int id) : connection_id_(id) { }
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int connection_id() const { return connection_id_; }
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgprivate:
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int connection_id_;
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass HttpServer {
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgpublic:
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HttpServer();
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~HttpServer();
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int HandleConnection(StreamInterface* stream);
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Due to sigslot issues, we can't destroy some streams at an arbitrary time.
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal3<HttpServer*, int, StreamInterface*> SignalConnectionClosed;
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // This signal occurs when the HTTP request headers have been received, but
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // before the request body is written to the request document.  By default,
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // the request document is a MemoryStream.  By handling this signal, the
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // document can be overridden, in which case the third signal argument should
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // be set to true.  In the case where the request body should be ignored,
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // the document can be set to NULL.  Note that the transaction object is still
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // owened by the HttpServer at this point.
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal3<HttpServer*, HttpServerTransaction*, bool*>
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalHttpRequestHeader;
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // An HTTP request has been made, and is available in the transaction object.
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Populate the transaction's response, and then return the object via the
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Respond method.  Note that during this time, ownership of the transaction
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // object is transferred, so it may be passed between threads, although
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // respond must be called on the server's active thread.
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal2<HttpServer*, HttpServerTransaction*> SignalHttpRequest;
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Respond(HttpServerTransaction* transaction);
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // If you want to know when a request completes, listen to this event.
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal3<HttpServer*, HttpServerTransaction*, int>
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalHttpRequestComplete;
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Stop processing the connection indicated by connection_id.
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Unless force is true, the server will complete sending a response that is
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // in progress.
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Close(int connection_id, bool force);
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void CloseAll(bool force);
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // After calling CloseAll, this event is signalled to indicate that all
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // outstanding connections have closed.
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal1<HttpServer*> SignalCloseAllComplete;
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgprivate:
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  class Connection : private IHttpNotify {
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  public:
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Connection(int connection_id, HttpServer* server);
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    virtual ~Connection();
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    void BeginProcess(StreamInterface* stream);
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    StreamInterface* EndProcess();
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    void Respond(HttpServerTransaction* transaction);
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    void InitiateClose(bool force);
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // IHttpNotify Interface
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size);
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    virtual void onHttpComplete(HttpMode mode, HttpError err);
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    virtual void onHttpClosed(HttpError err);
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    int connection_id_;
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HttpServer* server_;
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HttpBase base_;
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HttpServerTransaction* current_;
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    bool signalling_, close_;
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  };
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Connection* Find(int connection_id);
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Remove(int connection_id);
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  friend class Connection;
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::map<int,Connection*> ConnectionMap;
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectionMap connections_;
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int next_connection_id_;
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool closing_;
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//////////////////////////////////////////////////////////////////////
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass HttpListenServer : public HttpServer, public sigslot::has_slots<> {
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgpublic:
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HttpListenServer();
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~HttpListenServer();
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int Listen(const SocketAddress& address);
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool GetAddress(SocketAddress* address) const;
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void StopListening();
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgprivate:
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnReadEvent(AsyncSocket* socket);
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnConnectionClosed(HttpServer* server, int connection_id,
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                          StreamInterface* stream);
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> listener_;
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//////////////////////////////////////////////////////////////////////
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_BASE_HTTPSERVER_H__
138