blob: 15b3184fb6026c06a4c524dbd810a554dbfc6067 [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBSERVER_WEBSERVD_REQUEST_H_
#define WEBSERVER_WEBSERVD_REQUEST_H_
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <base/macros.h>
struct MHD_Connection;
struct MHD_PostProcessor;
namespace webservd {
class ProtocolHandler;
using PairOfStrings = std::pair<std::string, std::string>;
// This class represents the file information about a file uploaded via
// POST request using multipart/form-data request.
class FileInfo final {
public:
FileInfo(const std::string& in_field_name,
const std::string& in_file_name,
const std::string& in_content_type,
const std::string& in_transfer_encoding);
// The name of the form field for the file upload.
std::string field_name;
// The name of the file name specified in the form field.
std::string file_name;
// The content type of the file data.
std::string content_type;
// Data transfer encoding specified. Could be empty if no transfer encoding
// was specified.
std::string transfer_encoding;
// The file content data.
std::vector<uint8_t> data;
private:
DISALLOW_COPY_AND_ASSIGN(FileInfo);
};
// A class that represents the HTTP request data.
class Request final {
public:
Request(const std::string& request_handler_id,
const std::string& url,
const std::string& method,
MHD_Connection* connection,
ProtocolHandler* protocol_handler);
~Request();
// Obtains the content data of uploaded file identified by |file_id|.
bool GetFileData(int file_id, std::vector<uint8_t>* contents);
// Finishes the request and provides the reply data.
bool Complete(
int32_t status_code,
const std::vector<std::tuple<std::string, std::string>>& headers,
const std::vector<uint8_t>& data);
// Helper function to provide the string data and mime type.
bool Complete(
int32_t status_code,
const std::vector<std::tuple<std::string, std::string>>& headers,
const std::string& mime_type,
const std::string& data);
// Returns the unique ID of this request (GUID).
const std::string& GetID() const { return id_; }
// Returns the unique ID of the request handler this request is processed by
// (GUID).
const std::string& GetRequestHandlerID() const { return request_handler_id_; }
// Returns the unique ID of the protocol handler this request is received
// from (GUID or "http"/"https" for the two default handlers).
const std::string& GetProtocolHandlerID() const;
// Returns the object path of the HTTP request (e.g. "/privet/info").
const std::string& GetURL() const { return url_; }
// Returns the request method (e.g. "GET", "POST", ...).
const std::string& GetMethod() const { return method_; }
// Returns the raw body of the request, or empty byte array of the request
// had no body or a POST request has been parsed into form data.
const std::vector<uint8_t>& GetBody() const { return raw_data_; }
// Returns the POST form field data.
const std::vector<PairOfStrings>& GetDataPost() const { return post_data_; }
// Returns query parameters specified on the URL (as in "?param=value").
const std::vector<PairOfStrings>& GetDataGet() const { return get_data_; }
// Returns the information about any files uploaded as part of POST request.
const std::vector<std::unique_ptr<FileInfo>>& GetFileInfo() const {
return file_info_;
}
// Returns the HTTP request headers.
const std::vector<PairOfStrings>& GetHeaders() const { return headers_; }
private:
friend class RequestHelper;
friend class ServerHelper;
enum class State { kIdle, kWaitingForResponse, kResponseReceived, kDone };
// Helper methods for processing request data coming from the raw HTTP
// connection.
// Helper callback methods used by ProtocolHandler's ConnectionHandler to
// transfer request headers and data to the Request object.
bool BeginRequestData();
bool AddRequestData(const void* data, size_t size);
void EndRequestData();
// Callback for libmicrohttpd's PostProcessor.
bool ProcessPostData(const char* key,
const char* filename,
const char* content_type,
const char* transfer_encoding,
const char* data,
uint64_t off,
size_t size);
// These methods parse the request headers and data so they can be accessed
// by request handlers later.
bool AddRawRequestData(const void* data, size_t size);
bool AddPostFieldData(const char* key,
const char* filename,
const char* content_type,
const char* transfer_encoding,
const char* data,
size_t size);
bool AppendPostFieldData(const char* key, const char* data, size_t size);
std::string id_;
std::string request_handler_id_;
std::string url_;
std::string method_;
MHD_Connection* connection_{nullptr};
MHD_PostProcessor* post_processor_{nullptr};
std::vector<uint8_t> raw_data_;
bool last_posted_data_was_file_{false};
State state_{State::kIdle};
std::vector<PairOfStrings> post_data_;
std::vector<PairOfStrings> get_data_;
std::vector<std::unique_ptr<FileInfo>> file_info_;
std::vector<PairOfStrings> headers_;
int response_status_code_{0};
std::vector<uint8_t> response_data_;
std::vector<PairOfStrings> response_headers_;
ProtocolHandler* protocol_handler_;
DISALLOW_COPY_AND_ASSIGN(Request);
};
} // namespace webservd
#endif // WEBSERVER_WEBSERVD_REQUEST_H_