Skip to content

Commit

Permalink
Refactored HttpClient, HttpServer and WebsocketConnection. (#1112)
Browse files Browse the repository at this point in the history
- Better Code Design
- Faster and powerful HttpParser used in both HttpClient and Server
- Support for pipelinging in both HttpClient and HttpServer
- Suppot for connection reusage for both HttpClient and HttpServer
- SSL session resumption support for HttpClient and HttpServer
- Added ResourceTree to the HttpServer to allow more flexible definition of resources
- Added streaming support to both Http and WebSocket processing.
- rBootHttpUpdate should fail now as early as possible.
- Changed the ContentType code to allow easier definition of new mime types.

## Backwards-Incompatible changes
- WebSocket is renamed to WebSocketConnection to reflect better its meaning and intended use.
- Removed the tightly coupled websocket methods inside the HttpServer. You can use WebSocketResource and add it to the HttpServer resource tree to achieve the same results.
- Moved writeInit(), writeFlash(const u8 *data, u16 size) and writeEnd() methods from rBootHttpUpdate to rBootItemOutputStream.
- TemplateFileStream::setVarsFromRequest needs to be refactored completely. The current code couples TemplateFileStream to HttpRequest, which is too restrictive. TemplateFileStream::setVars method should be introduced that accepts HashMap<String,String>
- HttpRequest::getRequestMethod() is removed. Use HttpRequest::method instead.
- CommandExecutor with WebsocketConnection won't work.
  • Loading branch information
slaff authored May 4, 2017
1 parent 9b30d58 commit 5cb4ce3
Show file tree
Hide file tree
Showing 73 changed files with 8,321 additions and 1,932 deletions.
8 changes: 8 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@
path = Sming/third-party/esp-open-lwip
url = https://github.com/pfalcon/esp-open-lwip.git
ignore = dirty
[submodule "Sming/third-party/http-parser"]
path = Sming/third-party/http-parser
url = https://github.com/nodejs/http-parser.git
ignore = dirty
[submodule "Sming/third-party/ws_parser"]
path = Sming/third-party/ws_parser
url = https://github.com/charliesome/ws_parser.git
ignore = dirty
41 changes: 30 additions & 11 deletions Sming/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ export COMPILE := gcc
export PATH := $(ESP_HOME)/xtensa-lx106-elf/bin:$(PATH)
XTENSA_TOOLS_ROOT := $(ESP_HOME)/xtensa-lx106-elf/bin

# select which tools to use as compiler, librarian and linker
AS := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
CXX := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-g++
AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
OBJCOPY := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objcopy
OBJDUMP := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objdump

## COM port parameters
# Default COM port speed (generic)
COM_SPEED ?= 115200
Expand Down Expand Up @@ -143,7 +152,7 @@ TARGET = app
CUSTOM_TARGETS ?=

# which modules (subdirectories) of the project to include in compiling
MODULES = system system/helpers Wiring SmingCore appinit $(filter %/, $(wildcard SmingCore/*/)) $(filter %/, $(wildcard Services/*/)) $(filter %/, $(wildcard Libraries/*/))
MODULES = system system/helpers Wiring appinit $(shell find SmingCore -type d) $(filter %/, $(wildcard Services/*/)) $(filter %/, $(wildcard Libraries/*/))
EXTRA_INCDIR = include system/include Wiring Libraries SmingCore $(SDK_BASE)/../include

# Place a file that should exist in a submodule that is fetched separately
Expand All @@ -156,6 +165,16 @@ THIRD_PARTY_DATA += third-party/spiffs/makefile
MODULES += third-party/spiffs/src
EXTRA_INCDIR += third-party/spiffs/src

# => http-parser
THIRD_PARTY_DATA += third-party/http-parser/Makefile
MODULES += third-party/http-parser/
EXTRA_INCDIR += third-party/http-parser/

# => webscoket-parser
THIRD_PARTY_DATA += third-party/ws_parser/Makefile
MODULES += third-party/ws_parser/
EXTRA_INCDIR += third-party/ws_parser/

# => esp-gdbstub
ifeq ($(ENABLE_GDB), 1)
THIRD_PARTY_DATA += third-party/esp-gdbstub/Makefile
Expand Down Expand Up @@ -201,6 +220,8 @@ ifeq ($(ENABLE_CUSTOM_PWM), 1)
THIRD_PARTY_DATA += third-party/pwm/pwm.c
endif

MFORCE32 := $(shell $(CC) --help=target | grep mforce-l32)

# compiler flags using during compilation of source files. Add '-pg' for debugging
CFLAGS = -Wpointer-arith -Wundef -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -finline-functions -fdata-sections -ffunction-sections -D__ets__ -DICACHE_FLASH -DARDUINO=106 -DCOM_SPEED_SERIAL=$(COM_SPEED_SERIAL) -DENABLE_CMD_EXECUTOR=$(ENABLE_CMD_EXECUTOR)
ifeq ($(SMING_RELEASE),1)
Expand All @@ -212,7 +233,14 @@ else ifeq ($(ENABLE_GDB), 1)
else
CFLAGS += -Os -g
endif

ifneq ($(MFORCE32),)
# Your compiler supports the -mforce-l32 flag which means that
# constants can be stored in flash (program) memory instead of SRAM.
# See: https://www.arduino.cc/en/Reference/PROGMEM
CFLAGS += -DPROGMEM_L32="__attribute__((aligned(4))) __attribute__((section(\".irom.text\")))" -mforce-l32
else
CFLAGS += -DPROGMEM_L32=""
endif
#Append debug options
CFLAGS += -DCUST_FILE_BASE=$$* -DDEBUG_VERBOSE_LEVEL=$(DEBUG_VERBOSE_LEVEL) -DDEBUG_PRINT_FILENAME_AND_LINE=$(DEBUG_PRINT_FILENAME_AND_LINE)

Expand Down Expand Up @@ -246,15 +274,6 @@ ifeq ($(ENABLE_SSL),1)
CXXFLAGS += $(AXTLS_FLAGS)
endif

# select which tools to use as compiler, librarian and linker
AS := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
CXX := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-g++
AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
OBJCOPY := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objcopy
OBJDUMP := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objdump

SRC_DIR := $(MODULES)
BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES))

Expand Down
2 changes: 1 addition & 1 deletion Sming/Services/CommandProcessing/CommandExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CommandExecutor::CommandExecutor(Stream* reqStream) : CommandExecutor()
}
}

CommandExecutor::CommandExecutor(WebSocket* reqSocket)
CommandExecutor::CommandExecutor(WebSocketConnection* reqSocket)
{
commandOutput = new CommandOutput(reqSocket);
if (commandHandler.getVerboseMode() != SILENT)
Expand Down
2 changes: 1 addition & 1 deletion Sming/Services/CommandProcessing/CommandExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CommandExecutor
public:
CommandExecutor(TcpClient* cmdClient);
CommandExecutor(Stream* reqStream);
CommandExecutor(WebSocket* reqSocket);
CommandExecutor(WebSocketConnection* reqSocket);
~CommandExecutor();

int executorReceive(char *recvData, int recvSize);
Expand Down
2 changes: 1 addition & 1 deletion Sming/Services/CommandProcessing/CommandOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CommandOutput::CommandOutput(Stream* reqStream)
{
}

CommandOutput::CommandOutput(WebSocket* reqSocket)
CommandOutput::CommandOutput(WebSocketConnection* reqSocket)
: outputSocket(reqSocket)
{
}
Expand Down
6 changes: 3 additions & 3 deletions Sming/Services/CommandProcessing/CommandOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@
#include "Stream.h"
#include "Print.h"
#include "WiringFrameworkDependencies.h"
#include "Network/WebSocket.h"
#include "Network/Http/Websocket/WebSocketConnection.h"

class CommandOutput: public Print
{
public:
CommandOutput(TcpClient* reqClient);
CommandOutput(Stream* reqStream);
CommandOutput(WebSocket* reqSocket);
CommandOutput(WebSocketConnection* reqSocket);
virtual ~CommandOutput();

size_t write(uint8_t outChar);

TcpClient* outputTcpClient = nullptr;
Stream* outputStream = nullptr;
WebSocket* outputSocket = nullptr;
WebSocketConnection* outputSocket = nullptr;
String tempSocket = "";
};

Expand Down
27 changes: 17 additions & 10 deletions Sming/SmingCore/DataSourceStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
****/

#include "../SmingCore/DataSourceStream.h"
#include "../SmingCore/Network/TcpConnection.h"
#include "../SmingCore/Network/HttpRequest.h"
#include "WiringFrameworkDependencies.h"

MemoryDataStream::MemoryDataStream()
{
Expand Down Expand Up @@ -306,13 +303,14 @@ void TemplateFileStream::setVar(String name, String value)
templateData[name] = value;
}

void TemplateFileStream::setVarsFromRequest(const HttpRequest& request)
{
if (request.requestGetParameters != NULL)
templateData.setMultiple(*request.requestGetParameters);
if (request.requestPostParameters != NULL)
templateData.setMultiple(*request.requestPostParameters);
}
// TODO: Remove that dependency from here ...
//void TemplateFileStream::setVarsFromRequest(const HttpRequest& request)
//{
// if (request.requestGetParameters != NULL)
// templateData.setMultiple(*request.requestGetParameters);
// if (request.requestPostParameters != NULL)
// templateData.setMultiple(*request.requestPostParameters);
//}

///////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -340,3 +338,12 @@ uint16_t JsonObjectStream::readMemoryBlock(char* data, int bufSize)

return MemoryDataStream::readMemoryBlock(data, bufSize);
}

int JsonObjectStream::length()
{
if (rootNode != JsonObject::invalid()) {
return -1;
}

return rootNode.measureLength();
}
28 changes: 27 additions & 1 deletion Sming/SmingCore/DataSourceStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ class IDataSourceStream
* @retval bool True on success.
*/
virtual bool isFinished() = 0;

/**
* @brief Return the total length of the stream
* @retval int -1 is returned when the size cannot be determined
*/
virtual int length() { return -1; }
};

/// Memory data stream class
Expand All @@ -96,9 +102,17 @@ class MemoryDataStream : public Print, public IDataSourceStream

/** @brief Get size of stream
* @retval int Quantity of chars in stream
*
* @deprecated Use getLength instead
*/
int getStreamLength() { return size; }

/**
* @brief Return the total length of the stream
* @retval int -1 is returned when the size cannot be determined
*/
int length() { return size; }

/** @brief Write a single char to stream
* @param charToWrite Char to write to the stream
* @retval size_t Quantity of chars written to stream (always 1)
Expand Down Expand Up @@ -136,7 +150,7 @@ class FileStream : public IDataSourceStream
/** @brief Create a file stream
* @param fileName Name of file to open
*/
FileStream();
FileStream();
FileStream(String fileName);
virtual ~FileStream();

Expand Down Expand Up @@ -164,6 +178,12 @@ class FileStream : public IDataSourceStream
*/
inline int getPos() { return pos; }

/**
* @brief Return the total length of the stream
* @retval int -1 is returned when the size cannot be determined
*/
int length() { return size; }

private:
file_t handle;
int pos;
Expand Down Expand Up @@ -253,6 +273,12 @@ class JsonObjectStream : public MemoryDataStream
//Use base class documentation
virtual uint16_t readMemoryBlock(char* data, int bufSize);

/**
* @brief Return the total length of the stream
* @retval int -1 is returned when the size cannot be determined
*/
int length();

private:
DynamicJsonBuffer buffer;
JsonObject &rootNode;
Expand Down
68 changes: 68 additions & 0 deletions Sming/SmingCore/Network/Http/HttpCommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/****
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
*
* HttpServerResource
*
* @author: 2017 - Slavey Karadzhov <[email protected]>
*
* All files of the Sming Core are provided under the LGPL v3 license.
****/

#ifndef _SMING_CORE_HTTP_COMMON_H_
#define _SMING_CORE_HTTP_COMMON_H_

#define ENABLE_HTTP_REQUEST_AUTH 1

#include "../../Wiring/WString.h"
#include "../../Wiring/WHashMap.h"
#include "../../Delegate.h"
#include "../../Wiring/FILO.h"
#include "../WebConstants.h"
#include "../URL.h"

#ifndef HTTP_MAX_HEADER_SIZE
#define HTTP_MAX_HEADER_SIZE (8*1024)
#endif

/* Number of maximum tcp connections to be kept in the pool */
#ifndef HTTP_REQUEST_POOL_SIZE
#define HTTP_REQUEST_POOL_SIZE 20
#endif

#include "../http-parser/http_parser.h"

/**
* WARNING: For the moment the name "SimpleConcurrentQueue" is very misleading.
*/
template<typename T, int rawSize>
class SimpleConcurrentQueue: public FIFO<T, rawSize> {
public:
virtual const T& operator[](unsigned int) const { }
virtual T& operator[](unsigned int) { }

T peek() const
{
if(!FIFO<T, rawSize>::numberOfElements) {
return NULL;
}

return FIFO<T, rawSize>::peek();
}

T dequeue()
{
if(!FIFO<T, rawSize>::numberOfElements) {
return NULL;
}

return FIFO<T, rawSize>::dequeue();
}
};

typedef HashMap<String, String> HttpParams;
typedef HashMap<String, String> HttpHeaders;
typedef enum http_method HttpMethod;

#endif /* _SMING_CORE_HTTP_COMMON_H_ */
Loading

0 comments on commit 5cb4ce3

Please sign in to comment.