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.
This commit is contained in:
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -7,11 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <FileRequest.h>
|
#include <FileRequest.h>
|
||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
|
||||||
BFileRequest::BFileRequest(const BUrl& url, BUrlProtocolListener* listener,
|
BFileRequest::BFileRequest(const BUrl& url, BUrlProtocolListener* listener,
|
||||||
@@ -38,10 +41,14 @@ BFileRequest::Result() const
|
|||||||
status_t
|
status_t
|
||||||
BFileRequest::_ProtocolLoop()
|
BFileRequest::_ProtocolLoop()
|
||||||
{
|
{
|
||||||
// FIXME error handling (file does not exists, etc.)
|
BNode node(fUrl.Path().String());
|
||||||
BFile file(fUrl.Path().String(), B_READ_ONLY);
|
node_ref ref;
|
||||||
|
if (node.GetNodeRef(&ref) != B_OK)
|
||||||
|
return B_PROT_CONNECTION_FAILED;
|
||||||
|
|
||||||
if (file.InitCheck() != B_OK || !file.IsFile())
|
if (node.IsFile()) {
|
||||||
|
BFile file(fUrl.Path().String(), B_READ_ONLY);
|
||||||
|
if (file.InitCheck() != B_OK)
|
||||||
return B_PROT_CONNECTION_FAILED;
|
return B_PROT_CONNECTION_FAILED;
|
||||||
|
|
||||||
// Send all notifications to listener, if any
|
// Send all notifications to listener, if any
|
||||||
@@ -64,4 +71,50 @@ BFileRequest::_ProtocolLoop()
|
|||||||
fResult.SetContentType(mimeType);
|
fResult.SetContentType(mimeType);
|
||||||
|
|
||||||
return B_PROT_SUCCESS;
|
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);
|
||||||
|
|
||||||
|
return B_PROT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_PROT_CONNECTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user