add FileUpload,not complete yet
This commit is contained in:
parent
9ddd79b194
commit
10a6d39a32
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
*
|
||||
* @file
|
||||
* @author An Tao
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma
|
||||
|
||||
#include "HttpRequest.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
namespace drogon
|
||||
{
|
||||
class HttpFile
|
||||
{
|
||||
public:
|
||||
const std::string& getFileName() const {return fileName_;};
|
||||
void setFileName(const std::string& filename){fileName_=filename;};
|
||||
void setFile(const std::string& file){fileContent_=file;};
|
||||
int save(const std::string& path);
|
||||
int saveAs(const std::string& filename);
|
||||
int64_t fileLength() const {return fileContent_.length();};
|
||||
const std::string getMd5()const;
|
||||
protected:
|
||||
std::string fileName_;
|
||||
std::string fileContent_;
|
||||
};
|
||||
class FileUpload
|
||||
{
|
||||
public:
|
||||
FileUpload(){};
|
||||
~FileUpload(){};
|
||||
const std::vector<HttpFile> getFiles();
|
||||
const std::map<std::string,std::string>& getPremeter() const;
|
||||
int parse(const HttpRequest& req);
|
||||
|
||||
protected:
|
||||
std::vector<HttpFile> files_;
|
||||
std::map<std::string,std::string> premeter_;
|
||||
int parseEntity(const std::string& str);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
#include <drogon/FileUpload.h>
|
||||
#include "Funcs.h"
|
||||
#include <openssl/md5.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
using namespace drogon;
|
||||
|
||||
const std::vector<HttpFile> FileUpload::getFiles()
|
||||
{
|
||||
return files_;
|
||||
}
|
||||
const std::map<std::string, std::string> &FileUpload::getPremeter() const
|
||||
{
|
||||
return premeter_;
|
||||
};
|
||||
int FileUpload::parse(const HttpRequest &req)
|
||||
{
|
||||
if (req.method() != HttpRequest::kPost)
|
||||
return -1;
|
||||
std::map<std::string, std::string> headers = req.headers();
|
||||
if (headers.find("Content-Type") == headers.end())
|
||||
return -1;
|
||||
std::string &contentType = headers["Content-Type"];
|
||||
std::string::size_type pos = contentType.find(";");
|
||||
if (pos == std::string::npos)
|
||||
return -1;
|
||||
|
||||
std::string type = contentType.substr(0, pos);
|
||||
if (type != "multipart/form-data")
|
||||
return -1;
|
||||
pos = contentType.find("boundary=");
|
||||
if (pos == std::string::npos)
|
||||
return -1;
|
||||
std::string boundary = contentType.substr(pos + 9);
|
||||
std::cout << "boundary[" << boundary << "]" << std::endl;
|
||||
std::string content = req.query();
|
||||
std::string::size_type pos1, pos2;
|
||||
pos1 = pos2 = 0;
|
||||
pos2 = content.find(boundary);
|
||||
while (1)
|
||||
{
|
||||
pos1 = pos2;
|
||||
if (pos1 == std::string::npos)
|
||||
break;
|
||||
pos1 += boundary.length();
|
||||
if (content[pos1] == '\r' && content[pos1 + 1] == '\n')
|
||||
pos1 += 2;
|
||||
pos2 = content.find(boundary, pos1);
|
||||
if (pos2 == std::string::npos)
|
||||
break;
|
||||
// std::cout<<"pos1="<<pos1<<" pos2="<<pos2<<std::endl;
|
||||
if (content[pos2 - 4] == '\r' && content[pos2 - 3] == '\n' && content[pos2 - 2] == '-' && content[pos2 - 1] == '-')
|
||||
pos2 -= 4;
|
||||
if (parseEntity(content.substr(pos1, pos2 - pos1)) != 0)
|
||||
return -1;
|
||||
//pos2+=boundary.length();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int FileUpload::parseEntity(const std::string &str)
|
||||
{
|
||||
// parseEntity:[Content-Disposition: form-data; name="userfile1"; filename="appID.txt"
|
||||
// Content-Type: text/plain
|
||||
//
|
||||
// AA004MV7QI]
|
||||
// pos1=190 pos2=251
|
||||
// parseEntity:[YvBu
|
||||
// Content-Disposition: form-data; name="text"
|
||||
//
|
||||
// text]
|
||||
|
||||
// std::cout<<"parseEntity:["<<str<<"]"<<std::endl;
|
||||
std::string::size_type pos = str.find("name=\"");
|
||||
if (pos == std::string::npos)
|
||||
return -1;
|
||||
pos += 6;
|
||||
std::string::size_type pos1 = str.find("\"", pos);
|
||||
if (pos1 == std::string::npos)
|
||||
return -1;
|
||||
std::string name = str.substr(pos, pos1 - pos);
|
||||
// std::cout<<"name=["<<name<<"]\n";
|
||||
pos = str.find("filename=\"");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
pos1 = str.find("\r\n\r\n");
|
||||
if (pos1 == std::string::npos)
|
||||
return -1;
|
||||
premeter_[name] = str.substr(pos1 + 4);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += 10;
|
||||
std::string::size_type pos1 = str.find("\"", pos);
|
||||
if (pos1 == std::string::npos)
|
||||
return -1;
|
||||
HttpFile file;
|
||||
file.setFileName(str.substr(pos, pos1 - pos));
|
||||
pos1 = str.find("\r\n\r\n");
|
||||
if (pos1 == std::string::npos)
|
||||
return -1;
|
||||
file.setFile(str.substr(pos1 + 4));
|
||||
files_.push_back(file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int HttpFile::save(const std::string &path)
|
||||
{
|
||||
if (fileName_ == "")
|
||||
return -1;
|
||||
std::string filename;
|
||||
if (path[path.length()] != '/')
|
||||
{
|
||||
filename = path + "/" + fileName_;
|
||||
}
|
||||
else
|
||||
filename = path + fileName_;
|
||||
return saveAs(filename);
|
||||
}
|
||||
int HttpFile::saveAs(const std::string &filename)
|
||||
{
|
||||
std::ofstream file(filename);
|
||||
if (file.is_open())
|
||||
{
|
||||
file << fileContent_;
|
||||
file.close();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
const std::string HttpFile::getMd5() const
|
||||
{
|
||||
MD5_CTX c;
|
||||
unsigned char md5[16] = {0};
|
||||
MD5_Init(&c);
|
||||
MD5_Update(&c, fileContent_.c_str(), fileContent_.size());
|
||||
MD5_Final(md5, &c);
|
||||
return StringToHex(md5, 16);
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
#include "Funcs.h"
|
||||
#include <openssl/sha.h>
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
bool isInteger(const std::string &str)
|
||||
{
|
||||
for(auto c:str)
|
||||
{
|
||||
if(c>'9'||c<'0')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
std::string genRandomString(int length)
|
||||
{
|
||||
int flag, i;
|
||||
char str[length + 1];
|
||||
|
||||
timespec tp;
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
|
||||
//LOG_INFO<<"time: "<<tp.tv_nsec;
|
||||
srand(static_cast<unsigned int>(tp.tv_nsec));
|
||||
std::string char_space = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
str[i] = char_space[rand() % char_space.length()];
|
||||
}
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
std::string StringToHex(unsigned char* ptr, long long length)
|
||||
{
|
||||
std::string idString;
|
||||
for (long long i = 0; i < length; i++)
|
||||
{
|
||||
int value = (ptr[i] & 0xf0)>>4;
|
||||
if (value < 10)
|
||||
{
|
||||
idString.append(1, char(value + 48));
|
||||
} else
|
||||
{
|
||||
idString.append(1, char(value + 55));
|
||||
}
|
||||
|
||||
value = (ptr[i] & 0x0f);
|
||||
if (value < 10)
|
||||
{
|
||||
idString.append(1, char(value + 48));
|
||||
} else
|
||||
{
|
||||
idString.append(1, char(value + 55));
|
||||
}
|
||||
}
|
||||
return idString;
|
||||
}
|
||||
std::vector<std::string> splitString(const std::string &str, const std::string &separator)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
std::string::size_type pos1, pos2;
|
||||
pos1 = pos2 = 0;
|
||||
pos1 = str.find(separator);
|
||||
while (pos1 != std::string::npos)
|
||||
{
|
||||
if (pos1 != 0)
|
||||
{
|
||||
std::string item = str.substr(pos2, pos1 - pos2);
|
||||
ret.push_back(item);
|
||||
}
|
||||
pos2 = pos1 + separator.length();
|
||||
while (pos2 < str.length() && str.substr(pos2, separator.length()) == separator)
|
||||
pos2 += separator.length();
|
||||
pos1 = str.find(separator, pos2);
|
||||
}
|
||||
if (pos2 < str.length())
|
||||
ret.push_back(str.substr(pos2));
|
||||
return ret;
|
||||
}
|
||||
std::string getuuid()
|
||||
{
|
||||
uuid_t uu;
|
||||
uuid_generate(uu);
|
||||
return StringToHex(uu, 16);
|
||||
}
|
||||
|
||||
std::string stringPreProcess(const std::string& str)
|
||||
{
|
||||
std::string ret;
|
||||
for(int i = 0; i < str.length(); i++)
|
||||
{
|
||||
if(str[i] == '\'')
|
||||
{
|
||||
ret += "\'\'";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += str[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string encryptPassword(const std::string& plainPasswd,const std::string& salt)
|
||||
{
|
||||
unsigned char psd[SHA256_DIGEST_LENGTH];
|
||||
SHA256(reinterpret_cast<const unsigned char *>(plainPasswd.c_str()), plainPasswd.length(), psd);
|
||||
std::string encryptPasswd = std::string((char *)psd, SHA256_DIGEST_LENGTH);
|
||||
encryptPasswd +=salt;
|
||||
SHA256(reinterpret_cast<const unsigned char *>(encryptPasswd.c_str()), encryptPasswd.length(), psd);
|
||||
encryptPasswd = StringToHex(psd, SHA256_DIGEST_LENGTH);
|
||||
return encryptPasswd;
|
||||
}
|
||||
std::string encryptHashPassword(const std::string& hashPasswd,const std::string& salt)
|
||||
{
|
||||
unsigned char psd[SHA256_DIGEST_LENGTH];
|
||||
std::string encryptPasswd = hashPasswd+salt;
|
||||
SHA256(reinterpret_cast<const unsigned char *>(encryptPasswd.c_str()), encryptPasswd.length(), psd);
|
||||
encryptPasswd = StringToHex(psd, SHA256_DIGEST_LENGTH);
|
||||
return encryptPasswd;
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string UrlDecode(const std::string& szToDecode)
|
||||
{
|
||||
std::string result;
|
||||
int hex = 0;
|
||||
for (size_t i = 0; i < szToDecode.length(); ++i)
|
||||
{
|
||||
switch (szToDecode[i])
|
||||
{
|
||||
case '+':
|
||||
result += ' ';
|
||||
break;
|
||||
case '%':
|
||||
if (isxdigit(szToDecode[i + 1]) && isxdigit(szToDecode[i + 2]))
|
||||
{
|
||||
std::string hexStr = szToDecode.substr(i + 1, 2);
|
||||
hex = strtol(hexStr.c_str(), 0, 16);
|
||||
//字母和数字[0-9a-zA-Z]、一些特殊符号[$-_.+!*'(),] 、以及某些保留字[$&+,/:;=?@]
|
||||
//可以不经过编码直接用于URL
|
||||
if (!((hex >= 48 && hex <= 57) || //0-9
|
||||
(hex >=97 && hex <= 122) || //a-z
|
||||
(hex >=65 && hex <= 90) || //A-Z
|
||||
//一些特殊符号及保留字[$-_.+!*'(),] [$&+,/:;=?@]
|
||||
hex == 0x21 || hex == 0x24 || hex == 0x26 || hex == 0x27 || hex == 0x28 || hex == 0x29
|
||||
|| hex == 0x2a || hex == 0x2b|| hex == 0x2c || hex == 0x2d || hex == 0x2e || hex == 0x2f
|
||||
|| hex == 0x3A || hex == 0x3B|| hex == 0x3D || hex == 0x3f || hex == 0x40 || hex == 0x5f
|
||||
))
|
||||
{
|
||||
result += char(hex);
|
||||
i += 2;
|
||||
}
|
||||
else result += '%';
|
||||
}else {
|
||||
result += '%';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result += szToDecode[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef FUNCS_H_
|
||||
#define FUNCS_H_
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <pqxx/pqxx>
|
||||
|
||||
#define USING_PQXX_TO_STRING
|
||||
|
||||
using namespace pqxx;
|
||||
|
||||
bool isInteger(const std::string &str);
|
||||
std::string genRandomString(int length);
|
||||
std::string StringToHex(unsigned char* ptr, long long length);
|
||||
std::vector<std::string> splitString(const std::string &str,const std::string &separator);
|
||||
std::string getuuid();
|
||||
std::string stringPreProcess(const std::string& str);
|
||||
std::string encryptPassword(const std::string& plainPasswd,const std::string& salt);
|
||||
std::string encryptHashPassword(const std::string& hashPasswd,const std::string& salt);
|
||||
template <typename T>
|
||||
std::string toString(const T &obj)
|
||||
{
|
||||
#ifdef USING_PQXX_TO_STRING
|
||||
return pqxx::to_string(obj);
|
||||
#else
|
||||
char str[32];
|
||||
if(typeid(obj).name() == typeid(long).name())
|
||||
{
|
||||
sprintf(str, "%ld", obj);
|
||||
return std::string(str);
|
||||
}
|
||||
else if(typeid(obj).name() == typeid(int).name())
|
||||
{
|
||||
sprintf(str, "%d", obj);
|
||||
return std::string(str);
|
||||
}
|
||||
else if(typeid(obj).name() == typeid(std::string).name())
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
else if(typeid(obj).name() == typeid(bool).name())
|
||||
{
|
||||
return obj ? "true" : "false";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR<<"no way to transfer to string"
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fromString(const std::string& str, T &obj)
|
||||
{
|
||||
#ifdef USING_PQXX_TO_STRING
|
||||
pqxx::from_string(str, obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
|
||||
std::string base64_decode(std::string const& encoded_string);
|
||||
std::string UrlDecode(const std::string& szToDecode);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue