cleanup of skia serve url handling
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1653203002 Review URL: https://codereview.chromium.org/1653203002
This commit is contained in:
parent
0735de67c8
commit
483b90140a
@ -172,101 +172,135 @@ static int SendTemplate(MHD_Connection* connection, bool redirect = false,
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef int (*UrlHandler)(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size);
|
||||
class UrlHandler {
|
||||
public:
|
||||
virtual ~UrlHandler() {}
|
||||
virtual bool canHandle(const char* method, const char* url) = 0;
|
||||
virtual int handle(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) = 0;
|
||||
};
|
||||
|
||||
int rootHandler(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) {
|
||||
return SendTemplate(connection);
|
||||
}
|
||||
|
||||
int postHandler(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) {
|
||||
UploadContext* uc = request->fUploadContext;
|
||||
|
||||
// New connection
|
||||
if (!uc) {
|
||||
// TODO make this a method on request
|
||||
uc = new UploadContext;
|
||||
uc->connection = connection;
|
||||
uc->fPostProcessor = MHD_create_post_processor(connection, kBufferSize,
|
||||
&process_upload_data, uc);
|
||||
SkASSERT(uc->fPostProcessor);
|
||||
|
||||
request->fUploadContext = uc;
|
||||
return MHD_YES;
|
||||
class InfoHandler : public UrlHandler {
|
||||
public:
|
||||
bool canHandle(const char* method, const char* url) override {
|
||||
return 0 == strcmp(method, MHD_HTTP_METHOD_GET) &&
|
||||
0 == strcmp(url, "/cmd");
|
||||
}
|
||||
|
||||
// in process upload
|
||||
if (0 != *upload_data_size) {
|
||||
SkASSERT(uc->fPostProcessor);
|
||||
MHD_post_process(uc->fPostProcessor, upload_data, *upload_data_size);
|
||||
*upload_data_size = 0;
|
||||
return MHD_YES;
|
||||
int handle(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) override {
|
||||
if (request->fPicture.get()) {
|
||||
return SendJSON(connection, request->fPicture);
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
};
|
||||
|
||||
class ImgHandler : public UrlHandler {
|
||||
public:
|
||||
bool canHandle(const char* method, const char* url) override {
|
||||
static const char* kBasePath = "/img";
|
||||
return 0 == strcmp(method, MHD_HTTP_METHOD_GET) &&
|
||||
0 == strncmp(url, kBasePath, strlen(kBasePath));
|
||||
}
|
||||
|
||||
// end of upload
|
||||
MHD_destroy_post_processor(uc->fPostProcessor);
|
||||
uc->fPostProcessor = nullptr;
|
||||
int handle(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) override {
|
||||
if (request->fPNG.get()) {
|
||||
SkData* data = request->fPNG.get();
|
||||
return SendData(connection, data, "image/png");
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO response
|
||||
SkString error;
|
||||
if (!setupAndDrawToCanvas(request, &error)) {
|
||||
// TODO send error
|
||||
return MHD_YES;
|
||||
class PostHandler : public UrlHandler {
|
||||
public:
|
||||
bool canHandle(const char* method, const char* url) override {
|
||||
return 0 == strcmp(method, MHD_HTTP_METHOD_POST) &&
|
||||
0 == strcmp(url, "/new");
|
||||
}
|
||||
|
||||
return SendTemplate(connection, true, "/");
|
||||
}
|
||||
int handle(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) override {
|
||||
UploadContext* uc = request->fUploadContext;
|
||||
|
||||
int imgHandler(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) {
|
||||
if (request->fPNG.get()) {
|
||||
SkData* data = request->fPNG.get();
|
||||
return SendData(connection, data, "image/png");
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
// New connection
|
||||
if (!uc) {
|
||||
// TODO make this a method on request
|
||||
uc = new UploadContext;
|
||||
uc->connection = connection;
|
||||
uc->fPostProcessor = MHD_create_post_processor(connection, kBufferSize,
|
||||
&process_upload_data, uc);
|
||||
SkASSERT(uc->fPostProcessor);
|
||||
|
||||
int infoHandler(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) {
|
||||
if (request->fPicture.get()) {
|
||||
return SendJSON(connection, request->fPicture);
|
||||
request->fUploadContext = uc;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
// in process upload
|
||||
if (0 != *upload_data_size) {
|
||||
SkASSERT(uc->fPostProcessor);
|
||||
MHD_post_process(uc->fPostProcessor, upload_data, *upload_data_size);
|
||||
*upload_data_size = 0;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
// end of upload
|
||||
MHD_destroy_post_processor(uc->fPostProcessor);
|
||||
uc->fPostProcessor = nullptr;
|
||||
|
||||
// TODO response
|
||||
SkString error;
|
||||
if (!setupAndDrawToCanvas(request, &error)) {
|
||||
// TODO send error
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
return SendTemplate(connection, true, "/");
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
};
|
||||
|
||||
class RootHandler : public UrlHandler {
|
||||
public:
|
||||
bool canHandle(const char* method, const char* url) override {
|
||||
return 0 == strcmp(method, MHD_HTTP_METHOD_GET) &&
|
||||
0 == strcmp(url, "/");
|
||||
}
|
||||
|
||||
int handle(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size) override {
|
||||
return SendTemplate(connection);
|
||||
}
|
||||
};
|
||||
|
||||
class UrlManager {
|
||||
public:
|
||||
UrlManager() {
|
||||
// Register handlers
|
||||
fHandlers.push_back({MHD_HTTP_METHOD_GET, "/", rootHandler});
|
||||
fHandlers.push_back({MHD_HTTP_METHOD_POST, "/new", postHandler});
|
||||
fHandlers.push_back({MHD_HTTP_METHOD_GET, "/img", imgHandler});
|
||||
fHandlers.push_back({MHD_HTTP_METHOD_GET, "/cmd", infoHandler});
|
||||
fHandlers.push_back(new RootHandler);
|
||||
fHandlers.push_back(new PostHandler);
|
||||
fHandlers.push_back(new ImgHandler);
|
||||
fHandlers.push_back(new InfoHandler);
|
||||
}
|
||||
|
||||
~UrlManager() {
|
||||
for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; }
|
||||
}
|
||||
|
||||
// This is clearly not efficient for a large number of urls and handlers
|
||||
int invoke(Request* request, MHD_Connection* connection, const char* url, const char* method,
|
||||
const char* upload_data, size_t* upload_data_size) const {
|
||||
for (int i = 0; i < fHandlers.count(); i++) {
|
||||
const Url& urlHandler = fHandlers[i];
|
||||
if (0 == strcmp(method, urlHandler.fMethod) &&
|
||||
0 == strcmp(url, urlHandler.fPath)) {
|
||||
return (*urlHandler.fHandler)(request, connection, upload_data,
|
||||
upload_data_size);
|
||||
if (fHandlers[i]->canHandle(method, url)) {
|
||||
return fHandlers[i]->handle(request, connection, upload_data, upload_data_size);
|
||||
}
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Url {
|
||||
const char* fMethod;
|
||||
const char* fPath;
|
||||
UrlHandler fHandler;
|
||||
};
|
||||
SkTArray<Url> fHandlers;
|
||||
SkTArray<UrlHandler*> fHandlers;
|
||||
};
|
||||
|
||||
const UrlManager kUrlManager;
|
||||
@ -278,7 +312,12 @@ int answer_to_connection(void* cls, struct MHD_Connection* connection,
|
||||
SkDebugf("New %s request for %s using version %s\n", method, url, version);
|
||||
|
||||
Request* request = reinterpret_cast<Request*>(cls);
|
||||
return kUrlManager.invoke(request, connection, url, method, upload_data, upload_data_size);
|
||||
int result = kUrlManager.invoke(request, connection, url, method, upload_data,
|
||||
upload_data_size);
|
||||
if (MHD_NO == result) {
|
||||
fprintf(stderr, "Invalid method and / or url: %s %s)\n", method, url);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int skiaserve_main() {
|
||||
|
Loading…
Reference in New Issue
Block a user