Skip to content

Commit

Permalink
Add File handler reference (#73)
Browse files Browse the repository at this point in the history
* Adding file handle example in req references

* Adding reference to file handler (MultiPartParser)
  • Loading branch information
ProTankerAlfa authored May 30, 2024
1 parent 95046e9 commit 22cf9d2
Show file tree
Hide file tree
Showing 3 changed files with 301 additions and 10 deletions.
48 changes: 38 additions & 10 deletions ENG-09-0-References-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The HttpRequest type pointer commonly named `req` in the examples in this documentation represents the data contained in a request received or sent by drogon, below are the some methods by which you can interact with this object:

- ### isOnSecureConnection()
- ### `isOnSecureConnection()`

#### Summary:
Function that returns if the request was made on https.
Expand All @@ -13,7 +13,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
#### Returns:
bool type.

- ### getMethod()
- ### `getMethod()`

#### Summary:
Function that returns the request method. Useful to differentiate the request method if a single handle allows more than one type.
Expand All @@ -39,7 +39,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```
- ### getParameter(const std::string &key)
- ### `getParameter(const std::string &key)`
#### Summary:
Function that returns the value of a parameter based on an identifier. The behavior changes based on the Get or Post request type.
Expand Down Expand Up @@ -81,7 +81,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```
- ### getPath()
- ### `getPath()`
#### Similar:
path()
Expand Down Expand Up @@ -110,7 +110,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```

- ### getBody()
- ### `getBody()`

#### Similar:
body()
Expand Down Expand Up @@ -149,7 +149,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```
- ### headers()
- ### `headers()`
#### Summary:
Function that returns all headers of a request.
Expand All @@ -176,7 +176,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```

- ### getCookie()
- ### `getCookie()`

#### Summary:
Function that returns request cookie based on an identifier.
Expand All @@ -187,7 +187,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
#### Returns:
Value of cookie on string format.

- ### cookies()
- ### `cookies()`

#### Summary:
Function that returns all cookies of a request.
Expand All @@ -214,7 +214,7 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```
- ### getJsonObject()
- ### `getJsonObject()`
#### Summary:
Function that converts the body value of a request into a Json object (normally POST requests).
Expand All @@ -239,4 +239,32 @@ The HttpRequest type pointer commonly named `req` in the examples in this docume
}
```

# Next: [Plugins](ENG-10-Plugins)
## Useful Things

###### From here are not methods of the Http Request object, but some useful things you can do to process the requests you will receive

### Parsing File Request

```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser file;
file.parse(req);

if (file.getFiles().empty()) {
// Not Files Found
}

// Get First file and save then
const HttpFile archive = file.getFiles()[0];
archive.saveAs("/tmp/" + archive.getFileName());
}
```
For more information about parsing file: [File Handler](ENG-09-1-File-Handler)
# Next: [Plugins](ENG-09-1-File-Handler)
262 changes: 262 additions & 0 deletions ENG-09-1-File-Handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@

File parsing is extracting the file (or files) from a multipart-data POST request to an `HttpFile` object through `MultiPartParser`, here is some information about:

## `MultiPartParser` Object

#### Summary:

It is the object that you will use to extract and temporarily store the request files.

- ### `parse(const std::shared_ptr<HttpRequest> &req)`

#### Summary:
Receives the request object as a parameter, reads and identifies the files (if heard) and transfers it to the MultiPartParser variable.

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);
}
```

- ### `getFiles()`

#### Summary
Must be called after `parse()`, returns files of request in the format std::vector&ltHttpFile&gt.

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

// Check if have files
if (fileParser.getFiles().empty()) {
// No files found
}

size_t num_of_files = fileParser.getFiles().size();
}
```

- ### `getParameters()`

#### Summary
Must be called after `parse()`, returns the list of other parts from the MultiPartData form.

#### Returns:
std::unordered_map&ltstd::basic_string&ltchar&gt&gt (key, value)

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

if (!fileParser.getFiles().empty()) {
for (const auto &header : fileParser.getParameters()){
header.first // Key form
header.second // Value from key form
}
}
}
```

- ### `getParameter<Typename T>(const std::string &key)`

#### Summary
Must be called after `parse()`, individual version of getParameters().

#### Inputs:
The type of the expected object (will be converted automatically), the key value of the parameter.

#### Returns:
The content of the parameter corresponding to the key in the informed format, if it does not exist, will return the default value of the T Object.

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

std::string email = fileParser.getParameter<std::string>("email_form");

// Default type of string is ""
if (email.empty()) {
// email_form not found
}
}
```

## `HttpFile` Object

#### Summary:
It is the object that represents a file in memory, used by `MultiPartParser`.

- ### `getFileName()`

#### Summary
Self-explanatory name, gets the original name of the file that was received.

#### Returns:
std::string.

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

std::string filename = fileParser.getFiles()[0].getFileName();
}
```

- ### `fileLength()`

#### Summary
Gets the file size.

#### Returns:
`size_t`

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

size_t filesize = fileParser.getFiles()[0].fileLength();
}
```

- ### `getFileExtension()`

#### Summary
Gets the file extension.

#### Returns:
std::string

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

std::string file_extension = fileParser.getFiles()[0].getFileExtension();
}
```

- ### `getMd5()`

#### Summary
Get MD5 hash of file to check integrity.

#### Returns:
std::string

- ### `save()`

#### Summary
Save the file to the file system. The folder saving the file is `UploadPath` configured in config.json (or equivalent). The full path is
```c++
drogon::app().getUploadPath()+"/"+this->getFileName()
```
Or to simplify, it is saved as: UploadPath/filename


- ### `save(const std::string &path)`

#### Summary
Version if parameter is not omitted, uses the &path parameter instead of UploadPath.

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

// Relative path
fileParser.getFiles()[0].save("./"); // Writes the file to the same directory on the server, with the original name

// Absolute path
fileParser.getFiles()[0].save("/home/user/downloads/"); // Writes the file in the indicated directory, with the original name
}
```

- ### `saveAs(const std::string &path)`

#### Summary
Writes the file to the path parameter with a new name (ignores the original name).

#### Example:
```c++
#include "mycontroller.h"

using namespace drogon;

void mycontroller::postfile(const HttpRequestPtr &req, std::function<void (const HttpResponsePtr &)> &&callback) {
// Only Post Requests (File Form)

MultiPartParser fileParser;
fileParser.parse(req);

// Relative path
fileParser.getFiles()[0].saveAs("./image.png"); // Same path of server
/* Just example, Don't do this, you would overwrite the file format without checking if it really is png */

// Absolute path
fileParser.getFiles()[0].save("/home/user/downloads/anyname." + fileParser.getFiles()[0].getFileExtension());
}
```

# Next: [Plugins](ENG-10-Plugins)
1 change: 1 addition & 0 deletions _Sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
* [Automatic batch mode](ENG-08-5-Database-auto_batch)
* [References](ENG-09-0-References-request)
* [Request References](ENG-09-0-References-request)
* [File Handler](ENG-09-1-File-Handler)
* [Plugins](ENG-10-Plugins)
* [Configuration File](ENG-11-Configuration-File)
* [drogon_ctl Command](ENG-12-drogon_ctl-Command)
Expand Down

0 comments on commit 22cf9d2

Please sign in to comment.