/* * Returns the host associated with the request. If a client sends an absolute * URI, the host part of that is preferred. Otherwise, the input headers are * searched for a Host: header. NULL is returned if no absolute URI or Host: * header is provided. * @return [String] host */ static VALUE t_get_host(VALUE self) { Libevent_HttpRequest *http_request; Data_Get_Struct(self, Libevent_HttpRequest, http_request); return rb_str_new2(evhttp_request_get_host(http_request->ev_request)); }
/* Thread: httpd */ static void serve_file(struct evhttp_request *req, char *uri) { const char *host; char *ext; char path[PATH_MAX]; char *deref; char *ctype; char *passwd; struct evbuffer *evbuf; struct evkeyvalq *headers; struct stat sb; int fd; int i; int ret; /* Check authentication */ passwd = cfg_getstr(cfg_getsec(cfg, "general"), "admin_password"); if (passwd) { DPRINTF(E_DBG, L_HTTPD, "Checking web interface authentication\n"); ret = httpd_basic_auth(req, "admin", passwd, PACKAGE " web interface"); if (ret != 0) return; DPRINTF(E_DBG, L_HTTPD, "Authentication successful\n"); } else { host = evhttp_request_get_host(req); if ((strcmp(host, "::1") != 0) && (strcmp(host, "127.0.0.1") != 0)) { DPRINTF(E_LOG, L_HTTPD, "Remote web interface request denied; no password set\n"); evhttp_send_error(req, 403, "Forbidden"); return; } } ret = snprintf(path, sizeof(path), "%s%s", WEBFACE_ROOT, uri + 1); /* skip starting '/' */ if ((ret < 0) || (ret >= sizeof(path))) { DPRINTF(E_LOG, L_HTTPD, "Request exceeds PATH_MAX: %s\n", uri); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } ret = lstat(path, &sb); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not lstat() %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } if (S_ISDIR(sb.st_mode)) { redirect_to_index(req, uri); return; } else if (S_ISLNK(sb.st_mode)) { deref = m_realpath(path); if (!deref) { DPRINTF(E_LOG, L_HTTPD, "Could not dereference %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } if (strlen(deref) + 1 > PATH_MAX) { DPRINTF(E_LOG, L_HTTPD, "Dereferenced path exceeds PATH_MAX: %s\n", path); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); free(deref); return; } strcpy(path, deref); free(deref); ret = stat(path, &sb); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not stat() %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } if (S_ISDIR(sb.st_mode)) { redirect_to_index(req, uri); return; } } if (path_is_legal(path) != 0) { evhttp_send_error(req, 403, "Forbidden"); return; } evbuf = evbuffer_new(); if (!evbuf) { DPRINTF(E_LOG, L_HTTPD, "Could not create evbuffer\n"); evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal error"); return; } fd = open(path, O_RDONLY); if (fd < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not open %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } /* FIXME: this is broken, if we ever need to serve files here, * this must be fixed. */ ret = evbuffer_read(evbuf, fd, sb.st_size); close(fd); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not read file into evbuffer\n"); evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal error"); return; } ctype = "application/octet-stream"; ext = strrchr(path, '.'); if (ext) { for (i = 0; ext2ctype[i].ext; i++) { if (strcmp(ext, ext2ctype[i].ext) == 0) { ctype = ext2ctype[i].ctype; break; } } } headers = evhttp_request_get_output_headers(req); evhttp_add_header(headers, "Content-Type", ctype); evhttp_send_reply(req, HTTP_OK, "OK", evbuf); evbuffer_free(evbuf); }
static String HHVM_METHOD(EventHttpRequest, getHost) { EventHttpRequestResourceData *event_http_request_resource_data = FETCH_RESOURCE(this_, EventHttpRequestResourceData, s_event_http_request); return StringData::Make(evhttp_request_get_host((evhttp_request_t *) event_http_request_resource_data->getInternalResourceData()), CopyString); }