Add primitive url handling system to skiaserve
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1644633002 Review URL: https://codereview.chromium.org/1644633002
This commit is contained in:
parent
8f5175842d
commit
ccfdaa5f2a
@ -129,6 +129,121 @@ static int process_upload_data(void* cls, enum MHD_ValueKind kind,
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
static int SendImage(MHD_Connection* connection, const SkData* data) {
|
||||
MHD_Response* response = MHD_create_response_from_buffer(data->size(),
|
||||
const_cast<void*>(data->data()),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
MHD_add_response_header(response, "Content-Type", "image/png");
|
||||
|
||||
int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int SendTemplate(MHD_Connection* connection) {
|
||||
SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org"));
|
||||
|
||||
MHD_Response* response = MHD_create_response_from_buffer(
|
||||
debuggerTemplate.size(),
|
||||
(void*) const_cast<char*>(debuggerTemplate.c_str()),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
|
||||
int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef int (*UrlHandler)(Request* request, MHD_Connection* connection,
|
||||
const char* upload_data, size_t* upload_data_size);
|
||||
|
||||
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->pp = MHD_create_post_processor(connection, kBufferSize, &process_upload_data, uc);
|
||||
SkASSERT(uc->pp);
|
||||
|
||||
request->fUploadContext = uc;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
// in process upload
|
||||
if (0 != *upload_data_size) {
|
||||
SkASSERT(uc->pp);
|
||||
MHD_post_process(uc->pp, upload_data, *upload_data_size);
|
||||
*upload_data_size = 0;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
// end of upload
|
||||
MHD_destroy_post_processor(uc->pp);
|
||||
uc->pp = nullptr;
|
||||
|
||||
// TODO response
|
||||
SkString error;
|
||||
SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error);
|
||||
if (!data) {
|
||||
// TODO send error
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
request->fPNG.reset(data);
|
||||
return SendTemplate(connection);
|
||||
}
|
||||
|
||||
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 SendImage(connection, data);
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
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});
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Url {
|
||||
const char* fMethod;
|
||||
const char* fPath;
|
||||
UrlHandler fHandler;
|
||||
};
|
||||
SkTArray<Url> fHandlers;
|
||||
};
|
||||
|
||||
const UrlManager kUrlManager;
|
||||
|
||||
int 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,
|
||||
@ -136,86 +251,7 @@ 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);
|
||||
|
||||
MHD_Response* response;
|
||||
int ret = MHD_NO;
|
||||
|
||||
// TODO url handlers
|
||||
// handle uploads
|
||||
if (0 == strcmp(method, MHD_HTTP_METHOD_POST) &&
|
||||
0 == strcmp(url, "/new")) {
|
||||
UploadContext* uc = request->fUploadContext;
|
||||
|
||||
// New connection
|
||||
if (!uc) {
|
||||
// TODO make this a method on request
|
||||
uc = new UploadContext;
|
||||
uc->connection = connection;
|
||||
uc->pp = MHD_create_post_processor(connection, kBufferSize, &process_upload_data, uc);
|
||||
SkASSERT(uc->pp);
|
||||
|
||||
request->fUploadContext = uc;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
// in process upload
|
||||
if (0 != *upload_data_size) {
|
||||
SkASSERT(uc->pp);
|
||||
MHD_post_process(uc->pp, upload_data, *upload_data_size);
|
||||
*upload_data_size = 0;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
// end of upload
|
||||
MHD_destroy_post_processor(uc->pp);
|
||||
uc->pp = nullptr;
|
||||
|
||||
// TODO response
|
||||
SkString error;
|
||||
SkData* data = setupAndDrawToCanvas(uc->stream.detachAsStream(), &error);
|
||||
if (!data) {
|
||||
// TODO send error
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
request->fPNG.reset(data);
|
||||
// TODO Hack
|
||||
SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org"));
|
||||
|
||||
response = MHD_create_response_from_buffer(debuggerTemplate.size(),
|
||||
(void*) const_cast<char*>(debuggerTemplate.c_str()),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
|
||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response(response);
|
||||
} else if (0 == strcmp(method, MHD_HTTP_METHOD_GET)) {
|
||||
if (0 == strcmp(url, "/")) {
|
||||
SkString debuggerTemplate = generateTemplate(SkString("http://debugger.skia.org"));
|
||||
|
||||
response = MHD_create_response_from_buffer(debuggerTemplate.size(),
|
||||
(void*) const_cast<char*>(debuggerTemplate.c_str()),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
|
||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response(response);
|
||||
} else if (0 == strcmp(url, "/img")) {
|
||||
if (request->fPNG.get()) {
|
||||
SkData* data = request->fPNG.get();
|
||||
response = MHD_create_response_from_buffer(data->size(),
|
||||
const_cast<void*>(data->data()),
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
MHD_add_response_header(response, "Content-Type", "image/png");
|
||||
|
||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response(response);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SkFAIL("whoops, need proper error handling");
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return kUrlManager.invoke(request, connection, url, method, upload_data, upload_data_size);
|
||||
}
|
||||
|
||||
int skiaserve_main() {
|
||||
|
Loading…
Reference in New Issue
Block a user