1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#ifndef __httpd_h
#define __httpd_h
#include <asm/types.h>
#include <map>
#include <lib/base/object.h>
#include <lib/base/eptrlist.h>
#include <lib/base/ebase.h>
#include <string>
#include <lib/base/eerror.h>
#include <lib/network/socket.h>
#include <lib/network/serversocket.h>
class eHTTPConnection;
class eHTTPDataSource;
class eHTTPD;
class eHTTPDataSource;
typedef ePtr<eHTTPDataSource> eHTTPDataSourcePtr;
class iHTTPPathResolver: public iObject
{
public:
virtual ~iHTTPPathResolver() {};
virtual RESULT getDataSource(eHTTPDataSourcePtr &source, std::string request, std::string path, eHTTPConnection *conn)=0;
};
class eHTTPDataSource: public iObject
{
protected:
eHTTPConnection *connection;
public:
eHTTPDataSource(eHTTPConnection *c);
virtual ~eHTTPDataSource();
virtual void haveData(void *data, int len);
virtual int doWrite(int bytes); // number of written bytes, -1 for "no more"
};
typedef ePtr<eHTTPDataSource> eHTTPDataSourcePtr;
class eHTTPError: public eHTTPDataSource
{
DECLARE_REF(eHTTPError);
private:
int errcode;
public:
eHTTPError(eHTTPConnection *c, int errcode);
~eHTTPError() { }
void haveData();
int doWrite(int bytes);
};
class eHTTPConnection: public eSocket
{
void doError(int error);
int getLine(std::string &line);
int processLocalState();
int processRemoteState();
void writeString(const char *data);
eHTTPDataSourcePtr data;
eHTTPD *parent;
int buffersize;
private:
void readData();
void gotError(int);
void bytesWritten(int);
void hostConnected();
void destruct();
public:
Signal1<void,int> transferDone;
Signal1<eHTTPDataSource*,eHTTPConnection*> createDataSource;
enum
{
/*
< GET / HTTP/1.0
< If-modified-since: bla
<
< Data
> 200 OK HTTP/1.0
> Content-Type: text/html
>
> Data
*/
stateWait, stateRequest, stateResponse, stateHeader, stateData, stateDone, stateClose
};
int localstate, remotestate;
int persistent;
eHTTPConnection(int socket, int issocket, eHTTPD *parent, int persistent=0);
eHTTPConnection(eMainloop *ml); // ready to do "connectToHost"
static eHTTPConnection *doRequest(const char *uri, eMainloop *ml, int *error=0);
void start();
void gotHangup();
~eHTTPConnection();
// stateRequest
std::string request, requestpath, httpversion;
int is09;
// stateResponse
int code;
std::string code_descr;
std::map<std::string,std::string> remote_header, local_header;
// stateData
int content_length, content_length_remaining;
};
class eHTTPD: public eServerSocket
{
friend class eHTTPConnection;
eSmartPtrList<iHTTPPathResolver> resolver;
eMainloop *ml;
public:
eHTTPD(int port, eMainloop *ml);
void newConnection(int socket);
void addResolver(iHTTPPathResolver *r) { resolver.push_back(r); }
void removeResolver(iHTTPPathResolver *r) { resolver.remove(r); }
};
#endif
|