• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "GrCaps.h"
9 #include "GrContextFactory.h"
10 
11 #include "Request.h"
12 #include "Response.h"
13 
14 #include "SkCommandLineFlags.h"
15 
16 #include "microhttpd.h"
17 
18 #include "urlhandlers/UrlHandler.h"
19 #include <sys/socket.h>
20 
21 using namespace Response;
22 
23 // To get image decoders linked in we have to do the below magic
24 #include "SkForceLinking.h"
25 #include "SkImageDecoder.h"
26 __SK_FORCE_IMAGE_DECODER_LINKING;
27 
28 DEFINE_int32(port, 8888, "The port to listen on.");
29 
30 class UrlManager {
31 public:
UrlManager()32     UrlManager() {
33         // Register handlers
34         fHandlers.push_back(new RootHandler);
35         fHandlers.push_back(new PostHandler);
36         fHandlers.push_back(new ImgHandler);
37         fHandlers.push_back(new ClipAlphaHandler);
38         fHandlers.push_back(new EnableGPUHandler);
39         fHandlers.push_back(new CmdHandler);
40         fHandlers.push_back(new InfoHandler);
41         fHandlers.push_back(new DownloadHandler);
42         fHandlers.push_back(new DataHandler);
43         fHandlers.push_back(new BreakHandler);
44     }
45 
~UrlManager()46     ~UrlManager() {
47         for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; }
48     }
49 
50     // This is clearly not efficient for a large number of urls and handlers
invoke(Request * request,MHD_Connection * connection,const char * url,const char * method,const char * upload_data,size_t * upload_data_size) const51     int invoke(Request* request, MHD_Connection* connection, const char* url, const char* method,
52                const char* upload_data, size_t* upload_data_size) const {
53         for (int i = 0; i < fHandlers.count(); i++) {
54             if (fHandlers[i]->canHandle(method, url)) {
55                 return fHandlers[i]->handle(request, connection, url, method, upload_data,
56                                             upload_data_size);
57             }
58         }
59         return MHD_NO;
60     }
61 
62 private:
63     SkTArray<UrlHandler*> fHandlers;
64 };
65 
66 const UrlManager kUrlManager;
67 
answer_to_connection(void * cls,struct MHD_Connection * connection,const char * url,const char * method,const char * version,const char * upload_data,size_t * upload_data_size,void ** con_cls)68 int answer_to_connection(void* cls, struct MHD_Connection* connection,
69                          const char* url, const char* method, const char* version,
70                          const char* upload_data, size_t* upload_data_size,
71                          void** con_cls) {
72     SkDebugf("New %s request for %s using version %s\n", method, url, version);
73 
74     Request* request = reinterpret_cast<Request*>(cls);
75     int result = kUrlManager.invoke(request, connection, url, method, upload_data,
76                                     upload_data_size);
77     if (MHD_NO == result) {
78         fprintf(stderr, "Invalid method and / or url: %s %s\n", method, url);
79     }
80     return result;
81 }
82 
skiaserve_main()83 int skiaserve_main() {
84     Request request(SkString("/data")); // This simple server has one request
85 
86     // create surface
87     GrContextOptions grContextOpts;
88     request.fContextFactory.reset(new GrContextFactory(grContextOpts));
89     request.fSurface.reset(request.createCPUSurface());
90 
91     struct MHD_Daemon* daemon;
92     // TODO Add option to bind this strictly to an address, e.g. localhost, for security.
93     daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, FLAGS_port, nullptr, nullptr,
94                               &answer_to_connection, &request,
95                               MHD_OPTION_END);
96     if (NULL == daemon) {
97         return 1;
98     }
99 
100     getchar();
101     MHD_stop_daemon(daemon);
102     return 0;
103 }
104 
105 #if !defined SK_BUILD_FOR_IOS
main(int argc,char ** argv)106 int main(int argc, char** argv) {
107     SkCommandLineFlags::Parse(argc, argv);
108     return skiaserve_main();
109 }
110 #endif
111