hrev46654 adds 1 changeset to branch 'master' old head: 5143323fb69e0c6e6adae3a2e67ce0720e01af56 new head: 090ba6d06bfc7232720da1acf07c7f82f6b1b501 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=090ba6d+%5E5143323 ---------------------------------------------------------------------------- 090ba6d: FileRequest: implement directory listings. Use the EPFL (Easily Parsed File Listing) format. This is one of the formats that WebKit allows for directory listings, and it's easily parsed and generated. [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev46654 Commit: 090ba6d06bfc7232720da1acf07c7f82f6b1b501 URL: http://cgit.haiku-os.org/haiku/commit/?id=090ba6d Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Fri Jan 10 14:27:49 2014 UTC ---------------------------------------------------------------------------- 1 file changed, 73 insertions(+), 20 deletions(-) src/kits/network/libnetapi/FileRequest.cpp | 93 ++++++++++++++++++++------ ---------------------------------------------------------------------------- diff --git a/src/kits/network/libnetapi/FileRequest.cpp b/src/kits/network/libnetapi/FileRequest.cpp index 21f087f..cad1502 100644 --- a/src/kits/network/libnetapi/FileRequest.cpp +++ b/src/kits/network/libnetapi/FileRequest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013 Haiku Inc. All rights reserved. + * Copyright 2013-2014 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -7,11 +7,14 @@ */ +#include <stdio.h> #include <stdlib.h> +#include <Directory.h> #include <File.h> #include <FileRequest.h> #include <NodeInfo.h> +#include <Path.h> BFileRequest::BFileRequest(const BUrl& url, BUrlProtocolListener* listener, @@ -38,30 +41,80 @@ BFileRequest::Result() const status_t BFileRequest::_ProtocolLoop() { - // FIXME error handling (file does not exists, etc.) - BFile file(fUrl.Path().String(), B_READ_ONLY); - - if (file.InitCheck() != B_OK || !file.IsFile()) + BNode node(fUrl.Path().String()); + node_ref ref; + if (node.GetNodeRef(&ref) != B_OK) return B_PROT_CONNECTION_FAILED; - // Send all notifications to listener, if any - if (fListener != NULL) { - fListener->ConnectionOpened(this); - off_t size = 0; - file.GetSize(&size); + if (node.IsFile()) { + BFile file(fUrl.Path().String(), B_READ_ONLY); + if (file.InitCheck() != B_OK) + return B_PROT_CONNECTION_FAILED; + + // Send all notifications to listener, if any + if (fListener != NULL) { + fListener->ConnectionOpened(this); + off_t size = 0; + file.GetSize(&size); + fListener->DownloadProgress(this, size, size); + fResult.SetLength(size); + + ssize_t chunkSize; + char chunk[4096]; + while ((chunkSize = file.Read(chunk, sizeof(chunk))) > 0) + fListener->DataReceived(this, chunk, chunkSize); + } + + BNodeInfo info(&file); + char mimeType[B_MIME_TYPE_LENGTH + 1]; + if (info.GetType(mimeType) == B_OK) + fResult.SetContentType(mimeType); + + return B_PROT_SUCCESS; + } else if (node.IsDirectory()) { + BDirectory directory(&ref); + + fResult.SetContentType("application/x-ftp-directory"); + // This tells WebKit to use its FTP directory rendering code. + + // Send all notifications to listener, if any + if (fListener != NULL) + fListener->ConnectionOpened(this); + + int size = 0; + char name[B_FILE_NAME_LENGTH]; + BEntry entry; + while(directory.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) + { + // We read directories using the EPFL (Easily Parsed List Format) + // This happens to be one of the formats that WebKit can understand, + // and it is not too hard to parse or generate. + // http://tools.ietf.org/html/draft-bernstein-eplf-02 + BString epfl("+"); + if(entry.IsFile() || entry.IsSymLink()) { + epfl += "r,"; + off_t fileSize; + if (entry.GetSize(&fileSize) == B_OK) + epfl << "s" << fileSize << ","; + + } else if(entry.IsDirectory()) + epfl += "/,"; + + time_t modification; + if (entry.GetModificationTime(&modification) == B_OK) + epfl << "m" << modification << ","; + + entry.GetName(name); + epfl << "\t" << name << "\r\n"; + fListener->DataReceived(this, epfl.String(), epfl.Length()); + size += epfl.Length(); + } + fListener->DownloadProgress(this, size, size); fResult.SetLength(size); - ssize_t chunkSize; - char chunk[4096]; - while ((chunkSize = file.Read(chunk, sizeof(chunk))) > 0) - fListener->DataReceived(this, chunk, chunkSize); + return B_PROT_SUCCESS; } - BNodeInfo info(&file); - char mimeType[B_MIME_TYPE_LENGTH + 1]; - if (info.GetType(mimeType) == B_OK) - fResult.SetContentType(mimeType); - - return B_PROT_SUCCESS; + return B_PROT_CONNECTION_FAILED; }