void handleGET(TCPSocket* sock, TupleList& headers, const char* uri) { debug("GET request: %s", uri); if (isSpecialURI(uri)) { if (matchURL(uri, "/dune/time/set", true)) setTime(sock, headers, uri); else if (matchURL(uri, "/dune/version.js")) sendVersionJSON(sock, headers, uri); else if (matchURL(uri, "/dune/agent.js")) sendAgentJSON(sock, headers, uri); else if (matchURL(uri, "/dune/state/messages.js")) showMessages(sock, headers, uri); else if (matchURL(uri, "/dune/power/channel/", true)) handlePowerChannel(sock, headers, uri); else sendResponse404(sock); } else { Path path; if (std::strcmp("/", uri) == 0) path = m_ctx.dir_www / "index.html"; else path = m_ctx.dir_www / uri; sendStaticFile(sock, headers, path); } }
void RequestHandler::handlePUT(TCPSocket* sock, Utils::TupleList& headers, const char* uri) { (void)headers; (void)uri; sendResponse404(sock); }
void RequestHandler::sendFile(TCPSocket* sock, const std::string& file, HeaderFieldsMap& hdr_fields, int64_t off_beg, int64_t off_end) { int64_t size = FileSystem::Path(file).size(); // File doesn't exist or isn't accessible. if (size < 0) { sendResponse404(sock); return; } // Requested end offset is larger than file size. if (off_end > size) { sendResponse416(sock); return; } // Send full file. if ((off_beg < 0) && (off_end < 0)) { sendHeader(sock, STATUS_LINE_200, size, &hdr_fields); if (!sock->writeFile(file.c_str(), size - 1)) DUNE_ERR("HTTPHandle", "failed to send file: " << System::Error::getLastMessage()); return; } // Send partial content. if (off_end < 0) off_end = size - 1; if (off_beg < 0) off_beg = 0; std::ostringstream os; os << "bytes " << off_beg << "-" << off_end << "/" << size; hdr_fields.insert(std::make_pair("Content-Range", os.str())); sendHeader(sock, STATUS_LINE_206, off_end - off_beg + 1, &hdr_fields); if (!sock->writeFile(file.c_str(), off_end, off_beg)) DUNE_ERR("HTTPHandle", "failed to send file: " << System::Error::getLastMessage()); }
int staticFileCall(struct conn *c, void *arg) { wstr path = arg; struct staticFileData *static_data; off_t len; time_t m_time; int ret; struct stat stat; static_data = c->app_private_data; static_data->fd = open(path, O_RDONLY); if (static_data->fd == -1) { wheatLog(WHEAT_VERBOSE, "open file failed: %s", strerror(errno)); goto failed404; } ret = lstat(path, &stat); if (ret == -1) goto failed404; if (!S_ISREG(stat.st_mode)) { close(static_data->fd); static_data->fd = -1; if (S_ISDIR(stat.st_mode) && DirectoryIndex) { struct listNode *node; struct listIterator *iter; wstr last; char append_path[255]; iter = listGetIterator(DirectoryIndex, START_HEAD); while ((node = listNext(iter)) != NULL) { last = listNodeValue(node); snprintf(append_path, 255, "%s/%s", path, last); static_data->fd = open(append_path, O_RDONLY); if (static_data->fd != -1) { break; } } } if (static_data->fd == -1) { wheatLog(WHEAT_VERBOSE, "open file failed: %s", strerror(errno)); goto failed404; } } if (AllowExtensions && static_data->extension && !dictFetchValue(AllowExtensions, static_data->extension)) { goto failed404; } ret = getFileSizeAndMtime(static_data->fd , &len, &m_time); if (ret == WHEAT_WRONG) { wheatLog(WHEAT_VERBOSE, "open file failed: %s", strerror(errno)); goto failed404; } if (len > MaxFileSize) { wheatLog(WHEAT_NOTICE, "file exceed max limit %d", len); wheatLog(WHEAT_VERBOSE, "open file failed: %s", strerror(errno)); goto failed404; } wstr modified = dictFetchValue(httpGetReqHeaders(c), IfModifiedSince); if (modified != NULL) { char buf[wstrlen(modified)]; memcpy(buf, modified, wstrlen(modified)); time_t client_m_time = fromHttpDate(buf); if (m_time <= client_m_time) { fillResInfo(c, 304, "Not Modified"); ret = fillResHeaders(c, 0, 0); if (ret == -1) goto failed; ret = httpSendHeaders(c); if (ret == -1) goto failed; return WHEAT_OK; } } fillResInfo(c, 200, "OK"); ret = fillResHeaders(c, len, m_time); if (ret == -1) { wheatLog(WHEAT_WARNING, "fill Res Headers failes: %s", strerror(errno)); goto failed; } ret = httpSendHeaders(c); if (ret == -1) { wheatLog(WHEAT_WARNING, "static file send headers failed: %s", strerror(errno)); goto failed; } ret = sendClientFile(c, static_data->fd , len); if (ret == WHEAT_WRONG) { wheatLog(WHEAT_WARNING, "send static file failed: %s", strerror(errno)); goto failed; } return WHEAT_OK; failed404: sendResponse404(c); return WHEAT_OK; failed: setClientClose(c); return WHEAT_OK; }