| 121 | |
| 122 | |
| 123 | bool HttpProxy::process(const Future<Response>& future, const Request& request) |
| 124 | { |
| 125 | if (!future.isReady()) { |
| 126 | // TODO(benh): Consider handling other "states" of future |
| 127 | // (discarded, failed, etc) with different HTTP statuses. |
| 128 | Response response = future.isFailed() |
| 129 | ? InternalServerError(future.failure()) |
| 130 | : InternalServerError("discarded future"); |
| 131 | |
| 132 | VLOG(1) << "Returning '" << response.status << "'" |
| 133 | << " for '" << request.url.path << "'" |
| 134 | << " (" |
| 135 | << (future.isFailed() |
| 136 | ? future.failure() |
| 137 | : "discarded") << ")"; |
| 138 | |
| 139 | socket_manager->send(response, request, socket); |
| 140 | |
| 141 | return true; // All done, can process next response. |
| 142 | } |
| 143 | |
| 144 | Response response = future.get(); |
| 145 | |
| 146 | // If the response specifies a path, try and perform a sendfile. |
| 147 | if (response.type == Response::PATH) { |
| 148 | // Make sure no body is sent (this is really an error and |
| 149 | // should be reported and no response sent. |
| 150 | response.body.clear(); |
| 151 | |
| 152 | const string& path = response.path; |
| 153 | Try<int_fd> fd = os::open(path, O_RDONLY); |
| 154 | if (fd.isError()) { |
| 155 | #ifdef __WINDOWS__ |
| 156 | const int error = ::GetLastError(); |
| 157 | if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND) { |
| 158 | #else |
| 159 | const int error = errno; |
| 160 | if (error == ENOENT || error == ENOTDIR) { |
| 161 | #endif // __WINDOWS__ |
| 162 | VLOG(1) << "Returning '404 Not Found' for path '" << path << "'"; |
| 163 | socket_manager->send(NotFound(), request, socket); |
| 164 | } else { |
| 165 | VLOG(1) << "Failed to send file at '" << path << "': " << fd.error(); |
| 166 | socket_manager->send(InternalServerError(), request, socket); |
| 167 | } |
| 168 | } else { |
| 169 | const Try<Bytes> size = os::stat::size(fd.get()); |
| 170 | if (size.isError()) { |
| 171 | VLOG(1) << "Failed to send file at '" << path << "': " << size.error(); |
| 172 | socket_manager->send(InternalServerError(), request, socket); |
| 173 | } else if (os::stat::isdir(fd.get())) { |
| 174 | VLOG(1) << "Returning '404 Not Found' for directory '" << path << "'"; |
| 175 | socket_manager->send(NotFound(), request, socket); |
| 176 | } else { |
| 177 | // While the user is expected to properly set a 'Content-Type' |
| 178 | // header, we fill in (or overwrite) 'Content-Length' header. |
| 179 | response.headers["Content-Length"] = stringify(size->bytes()); |
| 180 |
nothing calls this directly
no test coverage detected