OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrCaps.h" | 8 #include "GrCaps.h" |
9 #include "GrContextFactory.h" | 9 #include "GrContextFactory.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 const char* content_type, const char* transfer_en
coding, | 122 const char* content_type, const char* transfer_en
coding, |
123 const char* data, uint64_t off, size_t size) { | 123 const char* data, uint64_t off, size_t size) { |
124 struct UploadContext* uc = reinterpret_cast<UploadContext*>(cls); | 124 struct UploadContext* uc = reinterpret_cast<UploadContext*>(cls); |
125 | 125 |
126 if (0 != size) { | 126 if (0 != size) { |
127 uc->stream.write(data, size); | 127 uc->stream.write(data, size); |
128 } | 128 } |
129 return MHD_YES; | 129 return MHD_YES; |
130 } | 130 } |
131 | 131 |
| 132 static int SendImage(MHD_Connection* connection, const SkData* data) { |
| 133 MHD_Response* response = MHD_create_response_from_buffer(data->size(), |
| 134 const_cast<void*>(d
ata->data()), |
| 135 MHD_RESPMEM_MUST_CO
PY); |
| 136 MHD_add_response_header(response, "Content-Type", "image/png"); |
| 137 |
| 138 int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); |
| 139 MHD_destroy_response(response); |
| 140 return ret; |
| 141 } |
| 142 |
| 143 static int SendTemplate(MHD_Connection* connection) { |
| 144 SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.
org")); |
| 145 |
| 146 MHD_Response* response = MHD_create_response_from_buffer( |
| 147 debuggerTemplate.size(), |
| 148 (void*) const_cast<char*>(debuggerTemplate.c_str()), |
| 149 MHD_RESPMEM_MUST_COPY); |
| 150 |
| 151 int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); |
| 152 MHD_destroy_response(response); |
| 153 return ret; |
| 154 } |
| 155 |
| 156 typedef int (*UrlHandler)(Request* request, MHD_Connection* connection, |
| 157 const char* upload_data, size_t* upload_data_size); |
| 158 |
| 159 int rootHandler(Request* request, MHD_Connection* connection, |
| 160 const char* upload_data, size_t* upload_data_size) { |
| 161 return SendTemplate(connection); |
| 162 } |
| 163 |
| 164 int postHandler(Request* request, MHD_Connection* connection, |
| 165 const char* upload_data, size_t* upload_data_size) { |
| 166 UploadContext* uc = request->fUploadContext; |
| 167 |
| 168 // New connection |
| 169 if (!uc) { |
| 170 // TODO make this a method on request |
| 171 uc = new UploadContext; |
| 172 uc->connection = connection; |
| 173 uc->pp = MHD_create_post_processor(connection, kBufferSize, &process_upl
oad_data, uc); |
| 174 SkASSERT(uc->pp); |
| 175 |
| 176 request->fUploadContext = uc; |
| 177 return MHD_YES; |
| 178 } |
| 179 |
| 180 // in process upload |
| 181 if (0 != *upload_data_size) { |
| 182 SkASSERT(uc->pp); |
| 183 MHD_post_process(uc->pp, upload_data, *upload_data_size); |
| 184 *upload_data_size = 0; |
| 185 return MHD_YES; |
| 186 } |
| 187 |
| 188 // end of upload |
| 189 MHD_destroy_post_processor(uc->pp); |
| 190 uc->pp = nullptr; |
| 191 |
| 192 // TODO response |
| 193 SkString error; |
| 194 SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error); |
| 195 if (!data) { |
| 196 // TODO send error |
| 197 return MHD_YES; |
| 198 } |
| 199 |
| 200 request->fPNG.reset(data); |
| 201 return SendTemplate(connection); |
| 202 } |
| 203 |
| 204 int imgHandler(Request* request, MHD_Connection* connection, |
| 205 const char* upload_data, size_t* upload_data_size) { |
| 206 if (request->fPNG.get()) { |
| 207 SkData* data = request->fPNG.get(); |
| 208 return SendImage(connection, data); |
| 209 } |
| 210 return MHD_NO; |
| 211 } |
| 212 |
| 213 class UrlManager { |
| 214 public: |
| 215 UrlManager() { |
| 216 // Register handlers |
| 217 fHandlers.push_back({MHD_HTTP_METHOD_GET, "/", rootHandler}); |
| 218 fHandlers.push_back({MHD_HTTP_METHOD_POST, "/new", postHandler}); |
| 219 fHandlers.push_back({MHD_HTTP_METHOD_GET, "/img", imgHandler}); |
| 220 } |
| 221 |
| 222 // This is clearly not efficient for a large number of urls and handlers |
| 223 int invoke(Request* request, MHD_Connection* connection, const char* url, co
nst char* method, |
| 224 const char* upload_data, size_t* upload_data_size) const { |
| 225 for (int i = 0; i < fHandlers.count(); i++) { |
| 226 const Url& urlHandler = fHandlers[i]; |
| 227 if (0 == strcmp(method, urlHandler.fMethod) && |
| 228 0 == strcmp(url, urlHandler.fPath)) { |
| 229 return (*urlHandler.fHandler)(request, connection, upload_da
ta, |
| 230 upload_data_size); |
| 231 } |
| 232 } |
| 233 return MHD_NO; |
| 234 } |
| 235 |
| 236 private: |
| 237 struct Url { |
| 238 const char* fMethod; |
| 239 const char* fPath; |
| 240 UrlHandler fHandler; |
| 241 }; |
| 242 SkTArray<Url> fHandlers; |
| 243 }; |
| 244 |
| 245 const UrlManager kUrlManager; |
| 246 |
132 int answer_to_connection(void* cls, struct MHD_Connection* connection, | 247 int answer_to_connection(void* cls, struct MHD_Connection* connection, |
133 const char* url, const char* method, const char* versio
n, | 248 const char* url, const char* method, const char* versio
n, |
134 const char* upload_data, size_t* upload_data_size, | 249 const char* upload_data, size_t* upload_data_size, |
135 void** con_cls) { | 250 void** con_cls) { |
136 SkDebugf("New %s request for %s using version %s\n", method, url, version); | 251 SkDebugf("New %s request for %s using version %s\n", method, url, version); |
137 | 252 |
138 Request* request = reinterpret_cast<Request*>(cls); | 253 Request* request = reinterpret_cast<Request*>(cls); |
139 | 254 return kUrlManager.invoke(request, connection, url, method, upload_data, upl
oad_data_size); |
140 MHD_Response* response; | |
141 int ret = MHD_NO; | |
142 | |
143 // TODO url handlers | |
144 // handle uploads | |
145 if (0 == strcmp(method, MHD_HTTP_METHOD_POST) && | |
146 0 == strcmp(url, "/new")) { | |
147 UploadContext* uc = request->fUploadContext; | |
148 | |
149 // New connection | |
150 if (!uc) { | |
151 // TODO make this a method on request | |
152 uc = new UploadContext; | |
153 uc->connection = connection; | |
154 uc->pp = MHD_create_post_processor(connection, kBufferSize, &process
_upload_data, uc); | |
155 SkASSERT(uc->pp); | |
156 | |
157 request->fUploadContext = uc; | |
158 return MHD_YES; | |
159 } | |
160 | |
161 // in process upload | |
162 if (0 != *upload_data_size) { | |
163 SkASSERT(uc->pp); | |
164 MHD_post_process(uc->pp, upload_data, *upload_data_size); | |
165 *upload_data_size = 0; | |
166 return MHD_YES; | |
167 } | |
168 | |
169 // end of upload | |
170 MHD_destroy_post_processor(uc->pp); | |
171 uc->pp = nullptr; | |
172 | |
173 // TODO response | |
174 SkString error; | |
175 SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error)
; | |
176 if (!data) { | |
177 // TODO send error | |
178 return MHD_YES; | |
179 } | |
180 | |
181 request->fPNG.reset(data); | |
182 // TODO Hack | |
183 SkString debuggerTemplate = generateTemplate(SkString("http://debugger.s
kia.org")); | |
184 | |
185 response = MHD_create_response_from_buffer(debuggerTemplate.size(), | |
186 (void*) const_cast<char*>(deb
uggerTemplate.c_str()), | |
187 MHD_RESPMEM_MUST_COPY); | |
188 | |
189 ret = MHD_queue_response(connection, MHD_HTTP_OK, response); | |
190 MHD_destroy_response(response); | |
191 } else if (0 == strcmp(method, MHD_HTTP_METHOD_GET)) { | |
192 if (0 == strcmp(url, "/")) { | |
193 SkString debuggerTemplate = generateTemplate(SkString("http://debugg
er.skia.org")); | |
194 | |
195 response = MHD_create_response_from_buffer(debuggerTemplate.size(), | |
196 (void*) const_cast<char*>
(debuggerTemplate.c_str()), | |
197 MHD_RESPMEM_MUST_COPY); | |
198 | |
199 ret = MHD_queue_response(connection, MHD_HTTP_OK, response); | |
200 MHD_destroy_response(response); | |
201 } else if (0 == strcmp(url, "/img")) { | |
202 if (request->fPNG.get()) { | |
203 SkData* data = request->fPNG.get(); | |
204 response = MHD_create_response_from_buffer(data->size(), | |
205 const_cast<void*>(dat
a->data()), | |
206 MHD_RESPMEM_MUST_COPY
); | |
207 MHD_add_response_header(response, "Content-Type", "image/png"); | |
208 | |
209 ret = MHD_queue_response(connection, MHD_HTTP_OK, response); | |
210 MHD_destroy_response(response); | |
211 } | |
212 } | |
213 } else { | |
214 SkFAIL("whoops, need proper error handling"); | |
215 return MHD_NO; | |
216 } | |
217 | |
218 return ret; | |
219 } | 255 } |
220 | 256 |
221 int skiaserve_main() { | 257 int skiaserve_main() { |
222 Request request; // This simple server has one request | 258 Request request; // This simple server has one request |
223 struct MHD_Daemon* daemon; | 259 struct MHD_Daemon* daemon; |
224 daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, PORT, nullptr, nullptr, | 260 daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, PORT, nullptr, nullptr, |
225 &answer_to_connection, &request, | 261 &answer_to_connection, &request, |
226 MHD_OPTION_END); | 262 MHD_OPTION_END); |
227 if (NULL == daemon) { | 263 if (NULL == daemon) { |
228 return 1; | 264 return 1; |
229 } | 265 } |
230 | 266 |
231 getchar(); | 267 getchar(); |
232 MHD_stop_daemon(daemon); | 268 MHD_stop_daemon(daemon); |
233 return 0; | 269 return 0; |
234 } | 270 } |
235 | 271 |
236 #if !defined SK_BUILD_FOR_IOS | 272 #if !defined SK_BUILD_FOR_IOS |
237 int main(int argc, char** argv) { | 273 int main(int argc, char** argv) { |
238 SkCommandLineFlags::Parse(argc, argv); | 274 SkCommandLineFlags::Parse(argc, argv); |
239 return skiaserve_main(); | 275 return skiaserve_main(); |
240 } | 276 } |
241 #endif | 277 #endif |
OLD | NEW |