int Dispatch(HttpContextRef context) { int ret = 0; Route route; char* url = strdup(context->_request->_uri); if( _GetRoute(url, &route) ) { if ( CFDataGetLength(context->_rcvdBytes) == 0) rho_rhodesapp_keeplastvisitedurl(context->_request->_uri); ret = _ExecuteApp(context, &route); } free(url); return ret; }
int ServeIndex(HttpContextRef context, char* index_name) { RAWLOG_INFO("Calling ruby framework to serve index"); if ( CFDataGetLength(context->_rcvdBytes) == 0) rho_rhodesapp_keeplastvisitedurl(index_name); VALUE val = callServeIndex(index_name); char* res = getStringFromValue(val); if (res) { RAWTRACE("RESPONSE:"); RAWTRACE_DATA((UInt8*)res, strlen(res)); RAWTRACE("RESPONSE -- eof --"); RAWTRACE("Add response to the send buffer"); CFDataAppendBytes(context->_sendBytes, (UInt8*)res, (CFIndex)strlen(res)); releaseValue(val); return 1; } return 0; }
bool CHttpServer::decide(String const &method, String const &arg_uri, String const &query, HeaderList const &headers, String const &body/*, IResponseSender& respSender*/ ) { if (verbose) RAWTRACE1("Decide what to do with uri %s", arg_uri.c_str()); callback_t callback = registered(arg_uri); if (callback) { if (verbose) RAWTRACE1("Uri %s is registered callback, so handle it appropriately", arg_uri.c_str()); if ( callback == rho_http_ruby_proc_callback ) call_ruby_proc( query, body ); else callback(this, query.length() ? query : body); return false; } String uri = arg_uri; String fullPath = CFilePath::join(m_root, uri); #ifndef RHO_NO_RUBY_API if (rho_ruby_is_started()) { Route route; if (dispatch(uri, route)) { if (verbose) RAWTRACE1("Uri %s is correct route, so enable MVC logic", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callFramework(req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); bool isRedirect = String_startsWith(reply, "HTTP/1.1 301") || String_startsWith(reply, "HTTP/1.1 302"); if (!send_response(reply, isRedirect)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) { if (!route.id.empty()) { sync::RhoconnectClientManager::rho_sync_addobjectnotify_bysrcname(route.model.c_str(), route.id.c_str()); } } return true; } if (isdir(fullPath)) { if (verbose) RAWTRACE1("Uri %s is directory, redirecting to index", uri.c_str()); String q = query.empty() ? "" : "?" + query; HeaderList headers; headers.push_back(Header("Location", CFilePath::join( uri, "index" RHO_ERB_EXT) + q)); send_response(create_response("301 Moved Permanently", headers), true); return false; } if (isindex(uri)) { if (!isfile(fullPath)) { if (verbose) RAWLOG_ERROR1("The file %s was not found", fullPath.c_str()); String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + uri + " was not found.</font></html>"; send_response(create_response("404 Not Found",error)); return false; } if (verbose) RAWTRACE1("Uri %s is index file, call serveIndex", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callServeIndex((char *)fullPath.c_str(), req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); if (!send_response(reply)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); return true; } } #endif // Try to send requested file if (verbose) RAWTRACE1("Uri %s should be regular file, trying to send it", uri.c_str()); PROF_START("READ_FILE"); bool bRes = send_file(uri, headers); PROF_STOP("READ_FILE"); return bRes; }
bool CHttpServer::decide(String const &method, String const &arg_uri, String const &query, HeaderList const &headers, String const &body) { RAWTRACE1("Decide what to do with uri %s", arg_uri.c_str()); callback_t callback = registered(arg_uri); if (callback) { RAWTRACE1("Uri %s is registered callback, so handle it appropriately", arg_uri.c_str()); if ( callback == rho_http_ruby_proc_callback ) call_ruby_proc( query, body ); else callback(this, query.length() ? query : body); return false; } String uri = arg_uri; //#ifdef OS_ANDROID // //Work around malformed Android WebView URLs // if (!String_startsWith(uri, "/app") && // !String_startsWith(uri, "/public") && // !String_startsWith(uri, "/data")) // { // RAWTRACE1("Malformed URL: '%s', adding '/app' prefix.", uri.c_str()); // uri = CFilePath::join("/app", uri); // } //#endif String fullPath = CFilePath::join(m_root, uri); Route route; if (dispatch(uri, route)) { RAWTRACE1("Uri %s is correct route, so enable MVC logic", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callFramework(req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); bool isRedirect = String_startsWith(reply, "HTTP/1.1 301") || String_startsWith(reply, "HTTP/1.1 302"); if (!send_response(reply, isRedirect)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) { if (!route.id.empty()) { sync::RhoconnectClientManager::rho_sync_addobjectnotify_bysrcname(route.model.c_str(), route.id.c_str()); } } return true; } //#ifndef OS_ANDROID if (isdir(fullPath)) { RAWTRACE1("Uri %s is directory, redirecting to index", uri.c_str()); String q = query.empty() ? "" : "?" + query; HeaderList headers; headers.push_back(Header("Location", CFilePath::join( uri, "index"RHO_ERB_EXT) + q)); send_response(create_response("301 Moved Permanently", headers), true); return false; } //#else // //Work around this Android redirect bug: // //http://code.google.com/p/android/issues/detail?can=2&q=11583&id=11583 // if (isdir(fullPath)) { // RAWTRACE1("Uri %s is directory, override with index", uri.c_str()); // return decide(method, CFilePath::join( uri, "index"RHO_ERB_EXT), query, headers, body); // } //#endif if (isindex(uri)) { if (!isfile(fullPath)) { RAWLOG_ERROR1("The file %s was not found", fullPath.c_str()); String error = "<html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + uri + " was not found.</font></html>"; send_response(create_response("404 Not Found",error)); return false; } RAWTRACE1("Uri %s is index file, call serveIndex", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callServeIndex((char *)fullPath.c_str(), req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); if (!send_response(reply)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); return true; } // Try to send requested file RAWTRACE1("Uri %s should be regular file, trying to send it", uri.c_str()); return send_file(uri, headers); }