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
|
#ifndef __httpd_h
#define __httpd_h
#include <asm/types.h>
#include <map>
#include <lib/base/eptrlist.h>
#include <lib/base/ebase.h>
#include <lib/base/estring.h>
#include <lib/base/eerror.h>
#include <lib/network/socket.h>
#include <lib/network/serversocket.h>
class eHTTPConnection;
class eHTTPDataSource;
class eHTTPD;
class eHTTPPathResolver
{
public:
virtual ~eHTTPPathResolver() {};
virtual eHTTPDataSource *getDataSource(eString request, eString path, eHTTPConnection *conn)=0;
};
class eHTTPDataSource
{
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"
};
class eHTTPError: public eHTTPDataSource
{
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(eString &line);
int processLocalState();
int processRemoteState();
void writeString(const char *data);
eHTTPDataSource *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
eString request, requestpath, httpversion;
int is09;
// stateResponse
int code;
eString 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;
ePtrList<eHTTPPathResolver> resolver;
eMainloop *ml;
public:
eHTTPD(int port, eMainloop *ml);
void newConnection(int socket);
void addResolver(eHTTPPathResolver *r) { resolver.push_back(r); }
void removeResolver(eHTTPPathResolver *r) { resolver.remove(r); }
};
#endif
|