annotate Core/HttpServer/MongooseServer.cpp @ 43:9be852ad33d2

rename for c
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 04 Sep 2012 09:59:34 +0200
parents 96e57b863dd9
children a15e90e5d6fc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
1 /**
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
2 * Palantir - A Lightweight, RESTful DICOM Store
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
4 * Belgium
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
5 *
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
6 * This program is free software: you can redistribute it and/or
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
7 * modify it under the terms of the GNU General Public License as
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
8 * published by the Free Software Foundation, either version 3 of the
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
9 * License, or (at your option) any later version.
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
10 *
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
11 * This program is distributed in the hope that it will be useful, but
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
14 * General Public License for more details.
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
15 *
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
16 * You should have received a copy of the GNU General Public License
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
18 **/
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
19
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
20
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
21 // http://en.highscore.de/cpp/boost/stringhandling.html
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
22
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
23 #include "MongooseServer.h"
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
24
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
25 #include <algorithm>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
26 #include <string.h>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
27 #include <boost/lexical_cast.hpp>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
28 #include <boost/algorithm/string.hpp>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
29 #include <iostream>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
30 #include <string.h>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
31 #include <stdio.h>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
32 #include <boost/thread.hpp>
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
33
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
34 #include "../PalantirException.h"
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
35 #include "../ChunkedBuffer.h"
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
36 #include "mongoose.h"
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
37
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
38
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
39 #define PALANTIR_REALM "Palantir Secure Area"
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
40
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
41 static const long LOCALHOST = (127ll << 24) + 1ll;
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
42
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
43
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
44 namespace Palantir
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
45 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
46 static const char multipart[] = "multipart/form-data; boundary=";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
47 static unsigned int multipartLength = sizeof(multipart) / sizeof(char) - 1;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
48
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
49
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
50 namespace
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
51 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
52 // Anonymous namespace to avoid clashes between compilation modules
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
53 class MongooseOutput : public HttpOutput
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
54 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
55 private:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
56 struct mg_connection* connection_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
57
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
58 public:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
59 MongooseOutput(struct mg_connection* connection) : connection_(connection)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
60 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
61 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
62
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
63 virtual void Send(const void* buffer, size_t length)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
64 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
65 mg_write(connection_, buffer, length);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
66 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
67 };
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
68
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
69
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
70 enum PostDataStatus
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
71 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
72 PostDataStatus_Success,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
73 PostDataStatus_NoLength,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
74 PostDataStatus_Pending,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
75 PostDataStatus_Failure
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
76 };
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
77 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
78
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
79
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
80 // TODO Move this to external file
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
81
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
82
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
83 class ChunkedFile : public ChunkedBuffer
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
84 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
85 private:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
86 std::string filename_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
87
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
88 public:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
89 ChunkedFile(const std::string& filename) :
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
90 filename_(filename)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
91 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
92 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
93
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
94 const std::string& GetFilename() const
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
95 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
96 return filename_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
97 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
98 };
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
99
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
100
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
101
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
102 class ChunkStore
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
103 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
104 private:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
105 typedef std::list<ChunkedFile*> Content;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
106 Content content_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
107 unsigned int numPlaces_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
108
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
109 boost::mutex mutex_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
110 std::set<std::string> discardedFiles_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
111
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
112 void Clear()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
113 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
114 for (Content::iterator it = content_.begin();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
115 it != content_.end(); it++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
116 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
117 delete *it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
118 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
119 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
120
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
121 Content::iterator Find(const std::string& filename)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
122 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
123 for (Content::iterator it = content_.begin();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
124 it != content_.end(); it++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
125 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
126 if ((*it)->GetFilename() == filename)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
127 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
128 return it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
129 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
130 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
131
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
132 return content_.end();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
133 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
134
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
135 void Remove(const std::string& filename)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
136 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
137 Content::iterator it = Find(filename);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
138 if (it != content_.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
139 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
140 delete *it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
141 content_.erase(it);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
142 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
143 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
144
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
145 public:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
146 ChunkStore()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
147 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
148 numPlaces_ = 10;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
149 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
150
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
151 ~ChunkStore()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
152 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
153 Clear();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
154 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
155
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
156 PostDataStatus Store(std::string& completed,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
157 const char* chunkData,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
158 size_t chunkSize,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
159 const std::string& filename,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
160 size_t filesize)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
161 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
162 boost::mutex::scoped_lock lock(mutex_);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
163
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
164 std::set<std::string>::iterator wasDiscarded = discardedFiles_.find(filename);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
165 if (wasDiscarded != discardedFiles_.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
166 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
167 discardedFiles_.erase(wasDiscarded);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
168 return PostDataStatus_Failure;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
169 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
170
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
171 ChunkedFile* f;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
172 Content::iterator it = Find(filename);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
173 if (it == content_.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
174 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
175 f = new ChunkedFile(filename);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
176
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
177 // Make some room
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
178 if (content_.size() >= numPlaces_)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
179 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
180 discardedFiles_.insert(content_.front()->GetFilename());
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
181 delete content_.front();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
182 content_.pop_front();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
183 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
184
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
185 content_.push_back(f);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
186 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
187 else
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
188 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
189 f = *it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
190 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
191
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
192 f->AddChunk(chunkData, chunkSize);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
193
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
194 if (f->GetNumBytes() > filesize)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
195 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
196 Remove(filename);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
197 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
198 else if (f->GetNumBytes() == filesize)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
199 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
200 f->Flatten(completed);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
201 Remove(filename);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
202 return PostDataStatus_Success;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
203 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
204
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
205 return PostDataStatus_Pending;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
206 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
207
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
208 /*void Print()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
209 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
210 boost::mutex::scoped_lock lock(mutex_);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
211
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
212 printf("ChunkStore status:\n");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
213 for (Content::const_iterator i = content_.begin();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
214 i != content_.end(); i++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
215 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
216 printf(" [%s]: %d\n", (*i)->GetFilename().c_str(), (*i)->GetNumBytes());
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
217 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
218 printf("-----\n");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
219 }*/
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
220 };
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
221
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
222
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
223 struct MongooseServer::PImpl
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
224 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
225 struct mg_context *context_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
226 ChunkStore chunkStore_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
227 };
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
228
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
229
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
230 ChunkStore& MongooseServer::GetChunkStore()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
231 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
232 return pimpl_->chunkStore_;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
233 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
234
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
235
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
236
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
237 HttpHandler* MongooseServer::FindHandler(const UriComponents& forUri) const
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
238 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
239 for (Handlers::const_iterator it =
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
240 handlers_.begin(); it != handlers_.end(); it++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
241 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
242 if ((*it)->IsServedUri(forUri))
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
243 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
244 return *it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
245 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
246 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
247
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
248 return NULL;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
249 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
250
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
251
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
252
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
253
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
254 static PostDataStatus ReadPostData(std::string& postData,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
255 struct mg_connection *connection,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
256 const HttpHandler::Arguments& headers)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
257 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
258 HttpHandler::Arguments::const_iterator cs = headers.find("content-length");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
259 if (cs == headers.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
260 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
261 return PostDataStatus_NoLength;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
262 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
263
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
264 int length;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
265 try
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
266 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
267 length = boost::lexical_cast<int>(cs->second);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
268 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
269 catch (boost::bad_lexical_cast)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
270 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
271 return PostDataStatus_NoLength;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
272 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
273
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
274 if (length < 0)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
275 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
276 length = 0;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
277 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
278
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
279 postData.resize(length);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
280
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
281 size_t pos = 0;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
282 while (length > 0)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
283 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
284 int r = mg_read(connection, &postData[pos], length);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
285 if (r <= 0)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
286 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
287 return PostDataStatus_Failure;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
288 }
8
3a584803783e build with visual studio
jodogne
parents: 0
diff changeset
289 assert(r <= length);
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
290 length -= r;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
291 pos += r;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
292 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
293
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
294 return PostDataStatus_Success;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
295 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
296
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
297
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
298
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
299 static PostDataStatus ParseMultipartPost(std::string &completedFile,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
300 struct mg_connection *connection,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
301 const HttpHandler::Arguments& headers,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
302 const std::string& contentType,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
303 ChunkStore& chunkStore)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
304 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
305 std::string boundary = "--" + contentType.substr(multipartLength);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
306
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
307 std::string postData;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
308 PostDataStatus status = ReadPostData(postData, connection, headers);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
309
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
310 if (status != PostDataStatus_Success)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
311 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
312 return status;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
313 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
314
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
315 /*for (HttpHandler::Arguments::const_iterator i = headers.begin(); i != headers.end(); i++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
316 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
317 std::cout << "Header [" << i->first << "] = " << i->second << "\n";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
318 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
319 printf("CHUNK\n");*/
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
320
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
321 typedef HttpHandler::Arguments::const_iterator ArgumentIterator;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
322
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
323 ArgumentIterator requestedWith = headers.find("x-requested-with");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
324 ArgumentIterator fileName = headers.find("x-file-name");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
325 ArgumentIterator fileSizeStr = headers.find("x-file-size");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
326
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
327 if (requestedWith == headers.end() ||
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
328 requestedWith->second != "XMLHttpRequest")
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
329 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
330 return PostDataStatus_Failure;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
331 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
332
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
333 size_t fileSize = 0;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
334 if (fileSizeStr != headers.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
335 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
336 try
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
337 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
338 fileSize = boost::lexical_cast<size_t>(fileSizeStr->second);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
339 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
340 catch (boost::bad_lexical_cast)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
341 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
342 return PostDataStatus_Failure;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
343 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
344 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
345
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
346 typedef boost::find_iterator<std::string::iterator> FindIterator;
10
27e2bbc11200 Better signal handling
Administrator@jodogne-w01
parents: 8
diff changeset
347 typedef boost::iterator_range<char*> Range;
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
348
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
349 //chunkStore.Print();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
350
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
351 try
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
352 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
353 FindIterator last;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
354 for (FindIterator it =
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
355 make_find_iterator(postData, boost::first_finder(boundary));
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
356 it!=FindIterator();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
357 ++it)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
358 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
359 if (last != FindIterator())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
360 {
10
27e2bbc11200 Better signal handling
Administrator@jodogne-w01
parents: 8
diff changeset
361 Range part(&last->back(), &it->front());
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
362 Range content = boost::find_first(part, "\r\n\r\n");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
363 if (content != Range())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
364 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
365 Range c(&content.back() + 1, &it->front() - 2);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
366 size_t chunkSize = c.size();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
367
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
368 if (chunkSize > 0)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
369 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
370 const char* chunkData = &c.front();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
371
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
372 if (fileName == headers.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
373 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
374 // This file is stored in a single chunk
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
375 completedFile.resize(chunkSize);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
376 if (chunkSize > 0)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
377 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
378 memcpy(&completedFile[0], chunkData, chunkSize);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
379 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
380 return PostDataStatus_Success;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
381 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
382 else
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
383 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
384 return chunkStore.Store(completedFile, chunkData, chunkSize, fileName->second, fileSize);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
385 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
386 }
10
27e2bbc11200 Better signal handling
Administrator@jodogne-w01
parents: 8
diff changeset
387 }
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
388 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
389
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
390 last = it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
391 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
392 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
393 catch (std::length_error)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
394 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
395 return PostDataStatus_Failure;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
396 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
397
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
398 return PostDataStatus_Pending;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
399 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
400
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
401
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
402 static void SendUnauthorized(HttpOutput& output)
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
403 {
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
404 std::string s = "HTTP/1.1 401 Unauthorized\r\n"
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
405 "WWW-Authenticate: Basic realm=\"" PALANTIR_REALM "\""
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
406 "\r\n\r\n";
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
407 output.Send(&s[0], s.size());
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
408 }
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
409
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
410
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
411 static bool Authorize(const MongooseServer& that,
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
412 const HttpHandler::Arguments& headers,
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
413 HttpOutput& output)
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
414 {
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
415 bool granted = false;
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
416
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
417 HttpHandler::Arguments::const_iterator auth = headers.find("authorization");
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
418 if (auth != headers.end())
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
419 {
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
420 std::string s = auth->second;
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
421 if (s.substr(0, 6) == "Basic ")
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
422 {
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
423 std::string b64 = s.substr(6);
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
424 granted = that.IsValidBasicHttpAuthentication(b64);
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
425 }
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
426 }
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
427
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
428 if (!granted)
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
429 {
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
430 SendUnauthorized(output);
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
431 return false;
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
432 }
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
433 else
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
434 {
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
435 return true;
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
436 }
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
437 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
438
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
439
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
440
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
441 static void* Callback(enum mg_event event,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
442 struct mg_connection *connection,
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
443 const struct mg_request_info *request)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
444 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
445 if (event == MG_NEW_REQUEST)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
446 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
447 MongooseServer* that = (MongooseServer*) (request->user_data);
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
448 MongooseOutput output(connection);
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
449
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
450 if (!that->IsRemoteAccessAllowed() &&
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
451 request->remote_ip != LOCALHOST)
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
452 {
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
453 SendUnauthorized(output);
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
454 return (void*) "";
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
455 }
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
456
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
457 HttpHandler::Arguments arguments, headers;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
458
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
459 for (int i = 0; i < request->num_headers; i++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
460 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
461 std::string name = request->http_headers[i].name;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
462 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
463 headers.insert(std::make_pair(name, request->http_headers[i].value));
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
464 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
465
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
466 // Authenticate this connection
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
467 if (that->IsAuthenticationEnabled() &&
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
468 !Authorize(*that, headers, output))
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
469 {
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
470 return (void*) "";
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
471 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
472
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
473 std::string postData;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
474
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
475 if (!strcmp(request->request_method, "GET"))
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
476 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
477 HttpHandler::ParseGetQuery(arguments, request->query_string);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
478 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
479 else if (!strcmp(request->request_method, "POST"))
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
480 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
481 HttpHandler::Arguments::const_iterator ct = headers.find("content-type");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
482 if (ct == headers.end())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
483 {
43
9be852ad33d2 rename for c
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 34
diff changeset
484 output.SendHeader(Palantir_HttpStatus_400_BadRequest);
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
485 return (void*) "";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
486 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
487
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
488 PostDataStatus status;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
489
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
490 std::string contentType = ct->second;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
491 if (contentType.size() >= multipartLength &&
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
492 !memcmp(contentType.c_str(), multipart, multipartLength))
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
493 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
494 status = ParseMultipartPost(postData, connection, headers, contentType, that->GetChunkStore());
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
495 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
496 else
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
497 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
498 status = ReadPostData(postData, connection, headers);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
499 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
500
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
501 switch (status)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
502 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
503 case PostDataStatus_NoLength:
43
9be852ad33d2 rename for c
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 34
diff changeset
504 output.SendHeader(Palantir_HttpStatus_411_LengthRequired);
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
505 return (void*) "";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
506
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
507 case PostDataStatus_Failure:
43
9be852ad33d2 rename for c
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 34
diff changeset
508 output.SendHeader(Palantir_HttpStatus_400_BadRequest);
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
509 return (void*) "";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
510
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
511 case PostDataStatus_Pending:
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
512 output.AnswerBuffer("");
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
513 return (void*) "";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
514
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
515 default:
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
516 break;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
517 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
518 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
519
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
520 UriComponents uri;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
521 Toolbox::SplitUriComponents(uri, request->uri);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
522
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
523 HttpHandler* handler = that->FindHandler(uri);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
524 if (handler)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
525 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
526 try
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
527 {
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
528 handler->Handle(output, std::string(request->request_method),
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
529 uri, headers, arguments, postData);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
530 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
531 catch (PalantirException& e)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
532 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
533 std::cerr << "MongooseServer Exception [" << e.What() << "]" << std::endl;
43
9be852ad33d2 rename for c
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 34
diff changeset
534 output.SendHeader(Palantir_HttpStatus_500_InternalServerError);
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
535 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
536 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
537 else
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
538 {
43
9be852ad33d2 rename for c
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 34
diff changeset
539 output.SendHeader(Palantir_HttpStatus_404_NotFound);
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
540 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
541
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
542 // Mark as processed
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
543 return (void*) "";
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
544 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
545 else
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
546 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
547 return NULL;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
548 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
549 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
550
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
551
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
552 bool MongooseServer::IsRunning() const
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
553 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
554 return (pimpl_->context_ != NULL);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
555 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
556
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
557
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
558 MongooseServer::MongooseServer() : pimpl_(new PImpl)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
559 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
560 pimpl_->context_ = NULL;
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
561 remoteAllowed_ = false;
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
562 authentication_ = false;
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
563 ssl_ = false;
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
564 port_ = 8000;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
565 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
566
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
567
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
568 MongooseServer::~MongooseServer()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
569 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
570 Stop();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
571 ClearHandlers();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
572 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
573
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
574
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
575 void MongooseServer::SetPort(uint16_t port)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
576 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
577 Stop();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
578 port_ = port;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
579 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
580
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
581 void MongooseServer::Start()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
582 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
583 if (!IsRunning())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
584 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
585 std::string port = boost::lexical_cast<std::string>(port_);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
586
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
587 if (ssl_)
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
588 {
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
589 port += "s";
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
590 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
591
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
592 const char *options[] = {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
593 "listening_ports", port.c_str(),
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
594 ssl_ ? "ssl_certificate" : NULL,
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
595 certificate_.c_str(),
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
596 NULL
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
597 };
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
598
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
599 pimpl_->context_ = mg_start(&Callback, this, options);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
600 if (!pimpl_->context_)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
601 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
602 throw PalantirException("Unable to launch the Mongoose server");
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
603 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
604 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
605 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
606
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
607 void MongooseServer::Stop()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
608 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
609 if (IsRunning())
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
610 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
611 mg_stop(pimpl_->context_);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
612 pimpl_->context_ = NULL;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
613 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
614 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
615
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
616
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
617 void MongooseServer::RegisterHandler(HttpHandler* handler)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
618 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
619 Stop();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
620
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
621 handlers_.push_back(handler);
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
622 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
623
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
624
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
625 void MongooseServer::ClearHandlers()
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
626 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
627 Stop();
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
628
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
629 for (Handlers::iterator it =
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
630 handlers_.begin(); it != handlers_.end(); it++)
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
631 {
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
632 delete *it;
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
633 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
634 }
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
635
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
636
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
637 void MongooseServer::ClearUsers()
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
638 {
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
639 Stop();
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
640 registeredUsers_.clear();
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
641 }
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
642
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
643
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
644 void MongooseServer::RegisterUser(const char* username,
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
645 const char* password)
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
646 {
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
647 Stop();
24
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 23
diff changeset
648
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 23
diff changeset
649 std::string tag = std::string(username) + ":" + std::string(password);
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 23
diff changeset
650 registeredUsers_.insert(Toolbox::EncodeBase64(tag));
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
651 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
652
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
653 void MongooseServer::SetSslEnabled(bool enabled)
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
654 {
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
655 Stop();
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
656
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
657 #if PALANTIR_SSL_ENABLED == 0
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
658 if (enabled)
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
659 {
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
660 throw PalantirException("Palantir has been built without SSL support");
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
661 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
662 else
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
663 {
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
664 ssl_ = false;
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
665 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
666 #else
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
667 ssl_ = enabled;
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
668 #endif
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
669 }
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
670
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
671 void MongooseServer::SetAuthenticationEnabled(bool enabled)
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
672 {
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
673 Stop();
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
674 authentication_ = enabled;
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
675 }
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
676
23
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
677 void MongooseServer::SetSslCertificate(const char* path)
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
678 {
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
679 Stop();
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
680 certificate_ = path;
62bd05fe4b7c support for ssl
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 10
diff changeset
681 }
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
682
34
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
683 void MongooseServer::SetRemoteAccessAllowed(bool allowed)
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
684 {
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
685 Stop();
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
686 remoteAllowed_ = allowed;
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
687 }
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
688
96e57b863dd9 option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 25
diff changeset
689
25
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
690 bool MongooseServer::IsValidBasicHttpAuthentication(const std::string& basic) const
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
691 {
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
692 return registeredUsers_.find(basic) != registeredUsers_.end();
dd1489098265 basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 24
diff changeset
693 }
0
3959d33612cc initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
694 }