HttpUpload is a collection of classes that makes it easy to implement a remote file manager.
HttpUpload which is internally using MultipartUpload, HttpAsynchReq, and HttpAsynchResp enables you to easily design code for uploading files using HTTP PUT and multipart POST.
The HttpResMgr in the example directory is a full file manager implementation that is internally using HttpUpload when the client requests a file upload. The following HttpDir C++ example shows how to use HttpUpload:
!#include <HttpUpload.h>
#include <HttpResRdr.h>
/* MyUploadDir is a specialized HttpDir that can upload and download
any file from a IoIntf implemenation such as a DiskIo.
We use multiple inheritance for implementing the HttpDir and HttpUpload
(HttpUploadCbIntf) callback interface.
*/
class MyUploadDir :
public HttpDir, public HttpUploadCbIntf
{
HttpUpload upload; //The upload worker class.
//HttpUploadCbIntf callback
static void onFile(HttpUploadCbIntf* super,
HttpUploadNode* node,
BaBool completed);
//HttpUploadCbIntf callback
static void onError(HttpUploadCbIntf* super,
HttpUploadNode* node,
int ecode,
const char* extraEcode);
//HttpDir callback
static int doService(HttpDir* super,
const char* relPath,
HttpCommand* cmd);
public:
MyUploadDir(const char* dirName, IoIntfPtr io);
};
//Called at start of multipart POST and at end of successful upload.
void
MyUploadDir::onFile(HttpUploadCbIntf* super,
HttpUploadNode* node,
BaBool completed)
{
MyUploadDir* o = (MyUploadDir*)super; // Upcast from base
if(completed) //A PUT or multipart POST completed.
{
HttpAsynchResp* resp = node->getResponse();
//Send a simple text response message to client.
BufPrint* out = resp->getWriter();
if(out) //If socket OK
out->printf("Upload of %s completed\n", node->getName());
}
else //If start of a multipart file. Not used for HTTP PUT.
{
// This is where one can authorize the upload.
// See the HttpResMgr class for how to deny access, if needed.
}
}
//Called if upload failed.
void
MyUploadDir::onError(HttpUploadCbIntf* super,
HttpUploadNode* node,
int ecode,
const char* extraEcode)
{
MyUploadDir* o = (MyUploadDir*)super; /* Upcast from base */
HttpAsynchResp* resp = node->getResponse();
//Send a simple text response message to client.
BufPrint* out = resp->getWriter();
if(out) //If socket OK
out->printf("Upload of %s failed\n", node->getName());
}
//The overloaded HttpDir service funtion. See HttpDir for more info.
int
MyUploadDir::doService(HttpDir* super,const char* relPath,HttpCommand* cmd)
{
MyUploadDir* o = (MyUploadDir*)super; // Upcast from base class
//Check that the HTTP method type is one of GET, POST, PUT, OPTION, or
// HEAD.
if(cmd->request.checkMethods(
&cmd->response, HttpMethod_Get | HttpMethod_Post | HttpMethod_Put))
{
// Condition failed or method type is OPTION.
// Response sent by checkMethods.
return 0;
}
//If a download request.
if(cmd->request.getMethodType() == HttpMethod_Get)
{
IoStat st;
IoIntfPtr io = o->upload.getIoIntf();
if( ! io->statFp(io,relPath, &st) && ! st.isDir )
{ //Send to client if file found and not a directory.
HttpResRdr::sendFile(io, relPath, &st, cmd);
return 0; //Signal found
}
}
else //Assume upload request.
{
if(o->upload.service(relPath, cmd) < 0)
cmd->response.sendError(415); //Request not supported.
return 0; //Signal found .i.e. stop searching.
}
return -1; //Let the virtual file system send "not found".
}
//Initiate HttpDir, HttpUploadCbIntf and HttpUpload.
MyUploadDir::MyUploadDir(const char* dirName, IoIntfPtr io) :
HttpDir(dirName),
HttpUploadCbIntf(onFile, onError),
upload(io, 0, this, 5)
{
setService(service); //Overload and ignore default HttpDir::service
}
|
| BA_API const char * | HttpUploadNode_getName (struct HttpUploadNode *o) |
| |
| BA_API const char * | HttpUploadNode_getUrl (struct HttpUploadNode *o) |
| |
| BA_API HttpAsynchResp * | HttpUploadNode_getResponse (struct HttpUploadNode *o) |
| | Switch from receiving the upload to producing its response. More...
|
| |
| BA_API struct HttpConnection * | HttpUploadNode_getConnection (struct HttpUploadNode *o) |
| |
| BA_API IoIntfPtr | HttpUploadNode_getIoIntf (struct HttpUploadNode *o) |
| |
| BA_API void * | HttpUploadNode_getdata (struct HttpUploadNode *o) |
| |
| BA_API HttpSession * | HttpUploadNode_getSession (struct HttpUploadNode *o) |
| |
| BA_API BaBool | HttpUploadNode_isMultipartUpload (struct HttpUploadNode *o) |
| |
| BA_API BaBool | HttpUploadNode_isResponseMode (struct HttpUploadNode *o) |
| |
| BA_API BaBool | HttpUploadNode_initial (struct HttpUploadNode *o) |
| |
| BA_API int | HttpUploadNode_decrRef (struct HttpUploadNode *o) |
| | Release one retained reference. More...
|
| |
| BA_API void | HttpUploadNode_incRef (struct HttpUploadNode *o) |
| | Retain a node beyond the current callback. More...
|
| |
| BA_API void | set_inflategzip (IoIntf_InflateGzip ptr) |
| | Install the process-wide gzip upload adapter in builds with zlib support. More...
|
| |
| BA_API IoIntf_InflateGzip | get_inflategzip (void) |
| |
| BA_API void | HttpUpload_constructor (HttpUpload *o, IoIntfPtr io, AllocatorIntf *alloc, HttpUploadCbIntf *uploadCb, int maxUploads) |
| | Initialize an HttpUpload instance. More...
|
| |
| BA_API void | HttpUpload_destructor (HttpUpload *o) |
| | Abort active uploads and release their storage. More...
|
| |
| BA_API int | HttpUpload_service (HttpUpload *o, const char *name, HttpCommand *cmd, void *userdata) |
| | Start an upload for a PUT or multipart POST request. More...
|
| |
| const char * | HttpUploadNode::getName () |
| |
| const char * | HttpUploadNode::getUrl () |
| |
| HttpAsynchResp * | HttpUploadNode::getResponse () |
| | Switch from receiving the upload to producing its response. More...
|
| |
| struct HttpConnection * | HttpUploadNode::getConnection () |
| |
| IoIntfPtr | HttpUploadNode::getIoIntf () |
| |
| HttpSession * | HttpUploadNode::getSession () |
| |
| bool | HttpUploadNode::isMultipartUpload () |
| |
| | HttpUploadCbIntf::HttpUploadCbIntf (HttpUploadCbIntf_OnFile of, HttpUploadCbIntf_OnError oe) |
| | Initialize a HttpUploadCbIntf interface. More...
|
| |
| | HttpUpload::HttpUpload (IoIntfPtr io, AllocatorIntf *alloc, HttpUploadCbIntf *uploadCb, int maxUploads) |
| | Initialize an HttpUpload instance. More...
|
| |
| | HttpUpload::~HttpUpload () |
| | Terminate the HttpUpload instance and all active HttpUploadNode instances. More...
|
| |
| int | HttpUpload::service (const char *name, HttpCommand *cmd, void *userdata=0) |
| | The HttpUpload service method. More...
|
| |
| IoIntfPtr | HttpUpload::getIoIntf () |
| |
◆ HttpUpload_getIoIntf
| #define HttpUpload_getIoIntf |
( |
|
o | ) |
(o)->io |
- Parameters
-
| [in] | o | Initialized uploader. |
- Returns
- Borrowed destination I/O interface.
◆ HttpUploadCbIntf_constructor
| #define HttpUploadCbIntf_constructor |
( |
|
o, |
|
|
|
onFile, |
|
|
|
onError |
|
) |
| |
Value: do { \
(o)->onFileFp=onFile; \
(o)->onErrorFp=onError; \
} while(0)
Install upload callbacks without allocating memory.
- Parameters
-
| [out] | o | Caller-owned callback interface, valid throughout upload use. |
| [in] | onFile | Required file/completion callback. |
| [in] | onError | Required failure callback. |
◆ HttpUpload
The HttpUpload node is responsible for creating and starting HttpUploadNode instances.
The class can create N concurrent HttpUploadNodes, where N is controlled by the 'maxUploads' attribute.
◆ HttpUploadCbIntf
◆ HttpUploadCbIntf_OnError
Report upload failure or parent shutdown.
- Parameters
-
| [in,out] | o | Borrowed installed callback interface. |
| [in,out] | node | Borrowed upload node, valid during the callback. |
| [in] | ecode | I/O error code, or FE_SOCKET for receive/parser failures. Parent shutdown reports IOINTF_IOERROR. |
| [in] | extraEcode | Borrowed optional error text, valid during the callback; copy it if retaining it. Do not interpret it as a stable machine-readable code. Send any desired error response using HttpUploadNode_getResponse. The socket may already be unusable. Files can be partially written; cleanup is the application's responsibility. The library does not free userdata. |
◆ HttpUploadCbIntf_OnFile
Notify the application about a file or completed request.
- Parameters
-
| [in,out] | o | Borrowed callback interface installed in HttpUpload. |
| [in,out] | node | Borrowed upload node, valid during the callback. |
| [in] | completed | FALSE before opening each multipart file; TRUE when the complete upload request finishes and its last file closes successfully. PUT has a completion callback but no FALSE start notification. A multipart request can contain several files; TRUE is not a per-file event. Call HttpUploadNode_getResponse to reject a file before opening it or to send the final response. Callbacks can run synchronously during service, or later. Do not destroy the parent HttpUpload from a callback. |
◆ get_inflategzip()
- Returns
- Installed process-wide gzip upload adapter, or NULL. Available in builds with zlib support. No ownership is transferred.
◆ getConnection()
- Returns
- Borrowed receive connection only after reception has reached a state that needs no lingering close and before response mode. Returns NULL while an incomplete upload needs closing or after response mode starts. The pointer is not an ownership transfer.
◆ getIoIntf() [1/2]
| IoIntfPtr HttpUploadNode::getIoIntf |
( |
| ) |
|
- Returns
- Borrowed destination I/O interface owned by the application.
◆ getIoIntf() [2/2]
| IoIntfPtr HttpUpload::getIoIntf |
( |
| ) |
|
- Returns
- Borrowed destination I/O interface passed to construction.
-
Borrowed destination I/O interface owned by the application.
◆ getName()
| const char * HttpUploadNode::getName |
( |
| ) |
|
- Returns
- Borrowed NUL-terminated path within the I/O interface. PUT returns the destination path; multipart POST returns the current file path, or the destination directory before a file is selected. Copy it before the next file callback or node destruction.
◆ getResponse()
Switch from receiving the upload to producing its response.
Calling before completion aborts reception. Send the desired response from the callback, including on success; obtaining the object alone does not establish that any response was delivered.
- Returns
- Borrowed embedded response object, never NULL for a valid node. Its connection can be unusable; check the response operation results. Do not destroy or free this object separately from the upload node.
◆ getSession()
- Returns
- Borrowed session found by its saved ID, or NULL if no session exists or it has expired.
The session object may expire at any time. See the explanation in the HttpSession for more information.
- See also
- HttpSession::incrRefCntr
◆ getUrl()
| const char * HttpUploadNode::getUrl |
( |
| ) |
|
- Returns
- Borrowed URL generated from the request's current directory using HttpResponse::encodeRedirectURL with an empty relative path. It can include session encoding; it is not necessarily the original request URI or a URL identifying the current multipart file. Valid until node destruction.
◆ HttpUpload()
Initialize an HttpUpload instance.
- Parameters
-
| io | Required borrowed writable I/O interface, valid until all uploads are destroyed. |
| alloc | Required borrowed allocator, valid until all uploads are destroyed. Pass AllocatorIntf_getDefault() to use the default. |
| uploadCb | Required borrowed callback interface with both callbacks installed; must outlive this uploader and every active node. |
| maxUploads | Nonnegative maximum number of concurrent requests, not a byte limit or a limit on files within one multipart request. Zero disables uploads. The HttpUpload::service method sends a 503 HTTP response if the maximum number of concurrent uploads are reached. |
◆ HttpUpload_constructor()
Initialize an HttpUpload instance.
- Parameters
-
| io | Required borrowed writable I/O interface, valid until all uploads are destroyed. |
| alloc | Required borrowed allocator, valid until all uploads are destroyed. Pass AllocatorIntf_getDefault() to use the default. |
| uploadCb | Required borrowed callback interface with both callbacks installed; must outlive this uploader and every active node. |
| maxUploads | Nonnegative maximum number of concurrent requests, not a byte limit or a limit on files within one multipart request. Zero disables uploads. The HttpUpload::service method sends a 503 HTTP response if the maximum number of concurrent uploads are reached. |
| [out] | o | Caller-owned uploader storage. |
◆ HttpUpload_destructor()
| BA_API void HttpUpload_destructor |
( |
HttpUpload * |
o | ) |
|
Abort active uploads and release their storage.
- Parameters
-
| [in,out] | o | Initialized uploader; not in a callback and no external node references outstanding. See HttpUpload::~HttpUpload for callback/lifetime rules. |
◆ HttpUpload_service()
Start an upload for a PUT or multipart POST request.
- Parameters
-
| [in,out] | o | Initialized uploader. |
| [in] | name | Required copied destination path. For multipart POST, use a directory path ending in a slash when nonempty. |
| [in,out] | cmd | Borrowed current command; accepted requests become asynchronous. |
| [in] | userdata | Borrowed callback context, or NULL; never freed by the uploader. |
- Returns
- -1 unsupported request, 0 accepted, 1 startup failure. Returns -1 for an unsupported request, 0 when accepted (callbacks may already have run), or 1 when startup failed. On startup failure the caller must release userdata unless a synchronous callback already released it. Existing HTTP error responses are preserved.
◆ HttpUploadCbIntf()
Initialize a HttpUploadCbIntf interface.
- Parameters
-
| of | Required file/completion callback; see HttpUploadCbIntf_OnFile. |
| oe | Required failure callback; see HttpUploadCbIntf_OnError. |
◆ HttpUploadNode_decrRef()
Release one retained reference.
- Parameters
-
| [in,out] | o | Live node with a nonzero reference count. |
- Returns
- -1 if the count reached zero and the node was destroyed, otherwise 0. Do not access o after -1. Do not decrement an internal callback reference.
◆ HttpUploadNode_getConnection()
- Returns
- Borrowed receive connection only after reception has reached a state that needs no lingering close and before response mode. Returns NULL while an incomplete upload needs closing or after response mode starts. The pointer is not an ownership transfer.
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_getdata()
- Parameters
-
- Returns
- Borrowed userdata passed to service, possibly NULL.
◆ HttpUploadNode_getIoIntf()
| BA_API IoIntfPtr HttpUploadNode_getIoIntf |
( |
struct HttpUploadNode * |
o | ) |
|
- Returns
- Borrowed destination I/O interface owned by the application.
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_getName()
| BA_API const char * HttpUploadNode_getName |
( |
struct HttpUploadNode * |
o | ) |
|
- Returns
- Borrowed NUL-terminated path within the I/O interface. PUT returns the destination path; multipart POST returns the current file path, or the destination directory before a file is selected. Copy it before the next file callback or node destruction.
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_getResponse()
Switch from receiving the upload to producing its response.
Calling before completion aborts reception. Send the desired response from the callback, including on success; obtaining the object alone does not establish that any response was delivered.
- Returns
- Borrowed embedded response object, never NULL for a valid node. Its connection can be unusable; check the response operation results. Do not destroy or free this object separately from the upload node.
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_getSession()
- Returns
- Borrowed session found by its saved ID, or NULL if no session exists or it has expired.
The session object may expire at any time. See the explanation in the HttpSession for more information.
- See also
- HttpSession::incrRefCntr
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_getUrl()
| BA_API const char * HttpUploadNode_getUrl |
( |
struct HttpUploadNode * |
o | ) |
|
- Returns
- Borrowed URL generated from the request's current directory using HttpResponse::encodeRedirectURL with an empty relative path. It can include session encoding; it is not necessarily the original request URI or a URL identifying the current multipart file. Valid until node destruction.
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_incRef()
Retain a node beyond the current callback.
- Parameters
-
| [in,out] | o | Live node; increments its U8 reference counter. Do not exceed 255 total references, including internal callback references. Pair each external increment with decrRef; stop external use before parent destruction. Serialize access with the server. This does not make the node thread-safe. |
◆ HttpUploadNode_initial()
- Parameters
-
- Returns
- Saved HttpResponse_initial state from the command at upload startup.
◆ HttpUploadNode_isMultipartUpload()
- Returns
- True for multipart POST, false for PUT.
- Parameters
-
| [in,out] | o | Live upload node. |
◆ HttpUploadNode_isResponseMode()
- Parameters
-
- Returns
- TRUE after an asynchronous response connection has been installed; FALSE otherwise. This does not test whether sending will succeed.
◆ isMultipartUpload()
| bool HttpUploadNode::isMultipartUpload |
( |
| ) |
|
- Returns
- True for multipart POST, false for PUT.
◆ service()
| int HttpUpload::service |
( |
const char * |
name, |
|
|
HttpCommand * |
cmd, |
|
|
void * |
userdata = 0 |
|
) |
| |
The HttpUpload service method.
This method is typically called from a HttpDir or HttpPage service method.
- Parameters
-
| name | Required NUL-terminated destination, copied before return:
- if PUT: path + name relative to the I/O interface.
- if POST: directory path relative to the I/O interface, ending in a slash when nonempty. The full path+name is constructed from the name in the multipart message.
|
| cmd | Borrowed current command; call from its service handler. An accepted upload takes over asynchronous request processing. |
| userdata | Optional borrowed context (default NULL), retrievable with HttpUploadNode_getdata. Keep it valid until callbacks finish. The uploader does not free it. |
- Returns
- -1 for an unsupported request, 0 when accepted, or 1 on startup failure. See HttpUpload_service for callback-state ownership.
◆ set_inflategzip()
Install the process-wide gzip upload adapter in builds with zlib support.
- Parameters
-
| [in] | ptr | Callback used to open gzip-decoding output resources, or NULL to disable that adaptation. Configure before concurrent uploads begin. |
- See also
- IoIntf_InflateGzip
◆ ~HttpUpload()
| HttpUpload::~HttpUpload |
( |
| ) |
|
Terminate the HttpUpload instance and all active HttpUploadNode instances.
Calls the error callback for each active node. Do not call from an upload callback or while external node references remain. The I/O interface, allocator and callback interface are not destroyed; caller-provided userdata is not freed.