1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00

bug fixing + HTTP2 advance

This commit is contained in:
stefanocasazza 2015-08-06 19:08:59 +02:00
parent 41fa6bccbd
commit d355cc9264
12 changed files with 441 additions and 341 deletions

View File

@ -76,6 +76,7 @@
*/
class UHTTP;
class UHTTP2;
class U_EXPORT UMimeHeader {
public:
@ -444,6 +445,7 @@ private:
#endif
friend class UHTTP;
friend class UHTTP2;
};
#endif

View File

@ -390,8 +390,6 @@ protected:
#endif
private:
static int handlerDataPending() U_NO_EXPORT;
static bool isValidMethod( const char* ptr) U_NO_EXPORT;
static bool isValidRequest( const char* ptr, uint32_t sz) U_NO_EXPORT;
static bool isValidRequestExt(const char* ptr, uint32_t sz) U_NO_EXPORT;

View File

@ -28,7 +28,6 @@ public:
static void ctor();
static void dtor();
static bool manageSetting();
protected:
enum FrameTypesId {
@ -242,6 +241,7 @@ protected:
static void sendError();
static void manageData();
static void manageHeaders();
static int handlerRequest();
static void handlerResponse();
static bool readBodyRequest();
static bool updateSetting(const char* ptr, uint32_t len);
@ -306,6 +306,9 @@ protected:
static uint32_t hpackDecodeInt( const unsigned char* src, const unsigned char* src_end, int32_t* pvalue, uint8_t prefix_max);
private:
static unsigned char* pwbuffer;
static bool addHTTPHeader(UStringRep* key, void* value) U_NO_EXPORT;
friend class UHTTP;
friend class UClientImage_Base;

View File

@ -87,7 +87,6 @@ public:
static void dtor();
static bool readRequest();
static int handlerDataPending();
static void setStatusDescription();
static bool isValidMethod(const char* ptr) __pure;
static bool scanfHeaderRequest(const char* ptr, uint32_t size);
@ -1002,7 +1001,7 @@ public:
static UFileCacheData* getFileInCache(const char* path, uint32_t len);
private:
static UString getHeaderForResponse();
static void handlerResponse();
static UString getHTMLDirectoryList() U_NO_EXPORT;
static void setMimeIndex() // NB: it is used by server_plugin_ssi...

View File

@ -28,7 +28,6 @@ iPF UClientImage_Base::callerHandlerRequest;
iPF UClientImage_Base::callerHandlerReset;
bPF UClientImage_Base::callerHandlerCache;
vPF UClientImage_Base::callerHandlerEndRequest;
iPF UClientImage_Base::callerHandlerDataPending;
bool UClientImage_Base::bIPv6;
bool UClientImage_Base::log_request_partial;
char UClientImage_Base::cbuffer[128];
@ -249,33 +248,6 @@ U_NO_EXPORT bool UClientImage_Base::isValidMethod( const char* ptr)
U_NO_EXPORT bool UClientImage_Base::isValidRequest( const char* ptr, uint32_t sz) { return true; }
U_NO_EXPORT bool UClientImage_Base::isValidRequestExt(const char* ptr, uint32_t sz) { return true; }
U_NO_EXPORT int UClientImage_Base::handlerDataPending()
{
U_TRACE(0, "UClientImage_Base::handlerDataPending()")
if (UServer_Base::startParallelization(UServer_Base::num_client_for_parallelization))
{
// parent
U_ClientImage_state = U_PLUGIN_HANDLER_ERROR;
U_RETURN(-1);
}
if (U_ClientImage_parallelization == 1) // 1 => child of parallelization
{
if (UNotifier::waitForRead(UServer_Base::csocket->iSockDesc, U_TIMEOUT_MS) != 1 ||
(resetReadBuffer(), USocketExt::read(UServer_Base::csocket, *rbuffer, getCountToRead(), 0)) == false)
{
U_RETURN(-1);
}
U_RETURN(1);
}
U_RETURN(0);
}
void UClientImage_Base::init()
{
U_TRACE(0, "UClientImage_Base::init()")
@ -305,10 +277,9 @@ void UClientImage_Base::init()
_buffer = U_NEW(UString(U_CAPACITY));
_encoded = U_NEW(UString(U_CAPACITY));
callerIsValidMethod = isValidMethod;
callerIsValidRequest = isValidRequest;
callerIsValidRequestExt = isValidRequestExt;
callerHandlerDataPending = handlerDataPending;
callerIsValidMethod = isValidMethod;
callerIsValidRequest = isValidRequest;
callerIsValidRequestExt = isValidRequestExt;
#ifdef DEBUG
UError::callerDataDump = saveRequestResponse;
@ -989,12 +960,6 @@ bool UClientImage_Base::genericRead()
U_RETURN(true);
}
#ifdef U_HTTP2_DISABLE
#define U_CALL_DATA_PENDING handlerDataPending
#else
#define U_CALL_DATA_PENDING callerHandlerDataPending
#endif
int UClientImage_Base::handlerRead() // Connection-wide hooks
{
U_TRACE(0, "UClientImage_Base::handlerRead()")
@ -1063,34 +1028,47 @@ pipeline:
}
}
U_INTERNAL_DUMP("U_ClientImage_pipeline = %b U_ClientImage_data_missing = %b", U_ClientImage_pipeline, U_ClientImage_data_missing)
U_INTERNAL_ASSERT(request->invariant())
#ifdef U_LOG_ENABLE
if (logbuf) logRequest();
#endif
U_INTERNAL_DUMP("U_ClientImage_pipeline = %b U_ClientImage_data_missing = %b", U_ClientImage_pipeline, U_ClientImage_data_missing)
if (U_ClientImage_data_missing)
{
dmiss:
# if defined(U_LOG_ENABLE) || !defined(U_CACHE_REQUEST_DISABLE)
result = U_CALL_DATA_PENDING();
U_INTERNAL_DUMP("U_ClientImage_parallelization = %d", U_ClientImage_parallelization)
if (result)
if (U_ClientImage_parallelization == 1) // 1 => child of parallelization
{
if (result == 1) goto loop; // child of parallelization
if (result == -1) // parent of parallelization
if (UNotifier::waitForRead(UServer_Base::csocket->iSockDesc, U_TIMEOUT_MS) != 1 ||
(resetReadBuffer(), USocketExt::read(UServer_Base::csocket, *rbuffer, getCountToRead(), 0)) == false)
{
if ((U_ClientImage_state & U_PLUGIN_HANDLER_ERROR) != 0) U_RETURN(U_NOTIFIER_DELETE);
goto death;
}
goto loop;
}
# endif
U_ClientImage_data_missing = false;
# ifndef U_HTTP2_DISABLE
U_INTERNAL_DUMP("U_http_version = %C", U_http_version)
if (U_http_version == '2')
{
U_ClientImage_state = UHTTP2::handlerRequest();
if (UNLIKELY((U_ClientImage_state & U_PLUGIN_HANDLER_ERROR) != 0)) goto error;
goto processing;
}
# endif
U_INTERNAL_ASSERT_EQUALS(data_pending, 0)
data_pending = U_NEW(UString((void*)U_STRING_TO_PARAM(*request)));
@ -1271,6 +1249,9 @@ check:
}
}
#ifndef U_HTTP2_DISABLE
processing:
#endif
U_INTERNAL_DUMP("U_ClientImage_pipeline = %b size_request = %u request->size() = %u",
U_ClientImage_pipeline, size_request, request->size())

View File

@ -467,13 +467,12 @@ int UHttpPlugIn::handlerRun() // NB: we use this method because now we have the
// NB: we can shortcut the http request processing...
UClientImage_Base::callerHandlerRead = UHTTP::handlerREAD;
UClientImage_Base::callerHandlerCache = UHTTP::handlerCache;
UClientImage_Base::callerIsValidMethod = UHTTP::isValidMethod;
UClientImage_Base::callerIsValidRequest = UHTTP::isValidRequest;
UClientImage_Base::callerIsValidRequestExt = UHTTP::isValidRequestExt;
UClientImage_Base::callerHandlerEndRequest = UHTTP::setEndRequestProcessing;
UClientImage_Base::callerHandlerDataPending = UHTTP::handlerDataPending;
UClientImage_Base::callerHandlerRead = UHTTP::handlerREAD;
UClientImage_Base::callerHandlerCache = UHTTP::handlerCache;
UClientImage_Base::callerIsValidMethod = UHTTP::isValidMethod;
UClientImage_Base::callerIsValidRequest = UHTTP::isValidRequest;
UClientImage_Base::callerIsValidRequestExt = UHTTP::isValidRequestExt;
UClientImage_Base::callerHandlerEndRequest = UHTTP::setEndRequestProcessing;
}
U_ASSERT(UHTTP::cache_file_check_memory())

View File

@ -101,7 +101,7 @@ int USoapPlugIn::handlerRequest()
(void) UFile::writeToTmp(U_STRING_TO_PARAM(body), false, "soap.res", 0);
# endif
U_http_info.nResponseCode = HTTP_OK;
U_http_info.nResponseCode = HTTP_OK;
UHTTP::setResponse(UHTTP::str_ctype_soap, &body);
}

View File

@ -1055,8 +1055,9 @@ int USSIPlugIn::handlerRequest()
U_http_info.nResponseCode = HTTP_OK;
*UClientImage_Base::body = output;
*UClientImage_Base::wbuffer = UHTTP::getHeaderForResponse();
*UClientImage_Base::body = output;
UHTTP::handlerResponse();
}
else if (alternative_response > 1)
{

View File

@ -329,15 +329,15 @@ extern U_EXPORT bool runRUBY(const char* libdir, const char* script);
rbv = rb_ary_new();
env = rb_hash_new();
/*
"rack.version"=>[1, 0],
"rack.run_once"=>false,
"rack.multithread"=>false,
"rack.multiprocess"=>false,
"rack.url_scheme"=>"http",
"rack.errors"=>#<IO:<STDERR>>,
"rack.input"=>#<StringIO:0x007fa1bce039f8>,
*/
/**
* "rack.version"=>[1, 0],
* "rack.run_once"=>false,
* "rack.multithread"=>false,
* "rack.multiprocess"=>false,
* "rack.url_scheme"=>"http",
* "rack.errors"=>#<IO:<STDERR>>,
* "rack.input"=>#<StringIO:0x007fa1bce039f8>,
*/
(void) rb_ary_store(rbv, 0, INT2NUM(1));
(void) rb_ary_store(rbv, 1, INT2NUM(1));

View File

@ -11,6 +11,7 @@
//
// ============================================================================
#include <ulib/mime/header.h>
#include <ulib/utility/http2.h>
#include <ulib/utility/uhttp.h>
#include <ulib/utility/base64.h>
@ -25,6 +26,7 @@ bool UHTTP2::settings_ack;
void* UHTTP2::pConnectionEnd;
uint32_t UHTTP2::hash_static_table[61];
const char* UHTTP2::upgrade_settings;
unsigned char* UHTTP2::pwbuffer;
UHTTP2::Stream* UHTTP2::pStream;
UHTTP2::FrameHeader UHTTP2::frame;
UHTTP2::Connection* UHTTP2::pConnection;
@ -517,9 +519,22 @@ uint32_t UHTTP2::hpackEncodeString(unsigned char* dst, const char* src, uint32_t
U_INTERNAL_ASSERT_MAJOR(len, 0)
unsigned char* ptr;
if (len < 29)
{
// encode as-is
asis: *dst = '\0';
ptr = hpackEncodeInt(dst, len, (1<<7)-1);
u__memcpy(ptr, src, len, __PRETTY_FUNCTION__);
U_RETURN(ptr - dst + len);
}
uint64_t bits = 0;
int bits_left = 40;
unsigned char* ptr;
const char* src_end = src + len;
UString buffer(len + 1024U);
@ -528,45 +543,53 @@ uint32_t UHTTP2::hpackEncodeString(unsigned char* dst, const char* src, uint32_t
unsigned char* _dst_end = _dst + len;
unsigned char* _dst_start = _dst;
// try to encode in huffman
do {
const HuffSym* sym = huff_sym_table + *src++;
const HuffSym* sym = huff_sym_table + *(unsigned char*)src++;
// U_INTERNAL_DUMP("sym->nbits = %u sym->code = %u bits_left = %d", sym->nbits, sym->code, bits_left)
bits |= (uint64_t)sym->code << (bits_left - sym->nbits);
bits_left -= sym->nbits;
// U_INTERNAL_DUMP("bits = %llu bits_left = %d", bits, bits_left)
while (bits_left <= 32)
{
*_dst++ = bits >> 32;
// U_INTERNAL_DUMP("_dst = %u bits >> 32 = %u", _dst[-1], bits >> 32)
bits <<= 8;
bits_left += 8;
U_INTERNAL_ASSERT_MINOR(_dst, _dst_end)
}
}
while (src < src_end);
// U_INTERNAL_DUMP("bits = %llu bits_left = %d", bits, bits_left)
if (bits_left != 40)
{
bits |= (1UL << bits_left) - 1;
*_dst++ = bits >> 32;
// U_INTERNAL_DUMP("_dst = %u bits >> 32 = %u", _dst[-1], bits >> 32)
}
if (_dst >= _dst_end) // encode as-is
{
*dst = '\0';
ptr = hpackEncodeInt(dst, len, (1<<7)-1);
U_INTERNAL_DUMP("_dst_end = %p _dst = %p %#.*S", _dst_end, _dst, buffer.distance((const char*)_dst), _dst_start)
u__memcpy(ptr, src, len, __PRETTY_FUNCTION__);
if (_dst > _dst_end) goto asis; // encode as-is
U_RETURN(ptr - dst + len);
}
len = _dst - _dst_start;
*dst = '\x80';
len = _dst - _dst_start;
ptr = hpackEncodeInt(dst, len, (1<<7)-1);
u__memcpy(ptr, _dst, len, __PRETTY_FUNCTION__);
u__memcpy(ptr, _dst_start, len, __PRETTY_FUNCTION__);
U_RETURN(ptr - dst + len);
}
@ -588,7 +611,7 @@ err: pvalue->clear();
src += nmove;
U_INTERNAL_DUMP("is_huffman = %b", is_huffman)
U_INTERNAL_DUMP("is_huffman = %b len = %u src = %#.*S", is_huffman, len, len, src)
if (is_huffman == false)
{
@ -1505,110 +1528,6 @@ void UHTTP2::manageData()
(void) UClientImage_Base::body->append(ptr, sz);
}
bool UHTTP2::manageSetting()
{
U_TRACE(0, "UHTTP2::manageSetting()")
U_INTERNAL_ASSERT_EQUALS(U_http_version, '2')
U_INTERNAL_DUMP("HTTP2-Settings: = %.*S U_http_method_type = %B", U_http2_settings_len, UHTTP2::upgrade_settings, U_http_method_type)
if (U_http2_settings_len &&
USocketExt::write(UServer_Base::csocket, U_CONSTANT_TO_PARAM(HTTP2_CONNECTION_UPGRADE_AND_SETTING_BIN), UServer_Base::timeoutMS) !=
U_CONSTANT_SIZE(HTTP2_CONNECTION_UPGRADE_AND_SETTING_BIN))
{
U_RETURN(false);
}
U_INTERNAL_ASSERT(UClientImage_Base::request->same(*UClientImage_Base::rbuffer))
UClientImage_Base::request->clear();
// maybe we have read more data than necessary...
uint32_t sz = UClientImage_Base::rbuffer->size();
U_INTERNAL_ASSERT_MAJOR(sz, 0)
if (sz > U_http_info.endHeader) UClientImage_Base::rstart = U_http_info.endHeader;
else
{
// we wait for HTTP2_CONNECTION_PREFACE...
UClientImage_Base::rbuffer->setEmptyForce();
if (UNotifier::waitForRead(UServer_Base::csocket->iSockDesc, U_TIMEOUT_MS) != 1 ||
USocketExt::read(UServer_Base::csocket, *UClientImage_Base::rbuffer, U_SINGLE_READ, 0) == false)
{
U_RETURN(false);
}
UClientImage_Base::rstart = 0;
sz = UClientImage_Base::rbuffer->size();
}
const char* ptr = UClientImage_Base::rbuffer->c_pointer(UClientImage_Base::rstart);
if (u_get_unalignedp64(ptr) != U_MULTICHAR_CONSTANT64( 'P', 'R','I',' ', '*', ' ', 'H', 'T') ||
u_get_unalignedp64(ptr+8) != U_MULTICHAR_CONSTANT64( 'T', 'P','/','2', '.', '0','\r','\n') ||
u_get_unalignedp64(ptr+16) != U_MULTICHAR_CONSTANT64('\r','\n','S','M','\r','\n','\r','\n'))
{
U_RETURN(false);
}
pConnection = (Connection*)UServer_Base::pClientImage->connection;
pConnectionEnd = (char*)pConnection + sizeof(Connection);
pConnection->state = CONN_STATE_OPEN;
pConnection->peer_settings = settings;
pConnection->max_open_stream_id =
pConnection->num_responding_streams =
pConnection->max_processed_stream_id = 0;
pStream = pConnection->streams;
pStream->state = STREAM_STATE_IDLE;
if (U_http2_settings_len == 0)
{
if (USocketExt::write(UServer_Base::csocket, U_CONSTANT_TO_PARAM(HTTP2_SETTINGS_BIN), UServer_Base::timeoutMS) != U_CONSTANT_SIZE(HTTP2_SETTINGS_BIN)) U_RETURN(false);
}
else
{
UString buffer(U_CAPACITY);
UBase64::decodeUrl(upgrade_settings, U_http2_settings_len, buffer);
if (buffer.empty() ||
updateSetting(U_STRING_TO_PARAM(buffer)) == false)
{
U_RETURN(false);
}
}
settings_ack = false;
UClientImage_Base::rstart += U_CONSTANT_SIZE(HTTP2_CONNECTION_PREFACE);
loop:
readFrame();
if (nerror == NO_ERROR)
{
U_INTERNAL_DUMP("settings_ack = %b", settings_ack)
if (settings_ack == false) goto loop; // we wait for SETTINGS ack...
U_RETURN(true);
}
sendError();
U_RETURN(false);
}
void UHTTP2::sendError()
{
U_TRACE(0, "UHTTP2::sendError()")
@ -1647,60 +1566,140 @@ void UHTTP2::sendError()
}
}
U_NO_EXPORT bool UHTTP2::addHTTPHeader(UStringRep* key, void* value)
{
U_TRACE(0+256, "UHTTP2::addHTTPHeader(%V,%V)", key, value)
U_INTERNAL_ASSERT_POINTER(key)
U_INTERNAL_ASSERT_POINTER(value)
uint32_t key_sz = key->size(),
value_sz = ((UStringRep*)value)->size();
const char* key_ptr = key->data();
const char* value_ptr = ((UStringRep*)value)->data();
U_INTERNAL_DUMP("key(%u) = %#V value(%u) = %#V", key_sz, key, value_sz, (UStringRep*)value)
U_INTERNAL_ASSERT_EQUALS(u_isBinary((const unsigned char*)value_ptr, value_sz), false)
uint32_t index = U_NOT_FOUND;
if (hpack_static_table[30].name->equalnocase(key_ptr, key_sz)) index = 31; // content-type
else if (hpack_static_table[27].name->equalnocase(key_ptr, key_sz)) U_RETURN(true); // content-length
else if (hpack_static_table[35].name->equalnocase(key_ptr, key_sz)) index = 36; // expires
else if (hpack_static_table[43].name->equalnocase(key_ptr, key_sz)) index = 44; // last-modified
else if (hpack_static_table[45].name->equalnocase(key_ptr, key_sz)) index = 46; // location
else if (hpack_static_table[51].name->equalnocase(key_ptr, key_sz)) index = 52; // refresh
else if (hpack_static_table[60].name->equalnocase(key_ptr, key_sz)) index = 61; // www-authenticate
else if (hpack_static_table[29].name->equalnocase(key_ptr, key_sz)) index = 30; // content-range
else if (hpack_static_table[17].name->equalnocase(key_ptr, key_sz)) index = 18; // accept-ranges
else if (hpack_static_table[19].name->equalnocase(key_ptr, key_sz)) index = 20; // access-control-allow-origin
else if (hpack_static_table[20].name->equalnocase(key_ptr, key_sz)) index = 21; // age
else if (hpack_static_table[23].name->equalnocase(key_ptr, key_sz)) index = 24; // cache-control
else if (hpack_static_table[24].name->equalnocase(key_ptr, key_sz)) index = 25; // content-disposition
else if (hpack_static_table[25].name->equalnocase(key_ptr, key_sz)) index = 26; // content-encoding
else if (hpack_static_table[26].name->equalnocase(key_ptr, key_sz)) index = 27; // content-language
else if (hpack_static_table[28].name->equalnocase(key_ptr, key_sz)) index = 29; // content-location
else if (hpack_static_table[33].name->equalnocase(key_ptr, key_sz)) index = 34; // etag
else if (hpack_static_table[44].name->equalnocase(key_ptr, key_sz)) index = 45; // link
else if (hpack_static_table[47].name->equalnocase(key_ptr, key_sz)) index = 48; // proxy-authenticate
else if (hpack_static_table[52].name->equalnocase(key_ptr, key_sz)) index = 53; // retry-after
else if (hpack_static_table[55].name->equalnocase(key_ptr, key_sz)) index = 56; // strict-transport-security
else if (hpack_static_table[58].name->equalnocase(key_ptr, key_sz)) index = 59; // vary
else if (hpack_static_table[59].name->equalnocase(key_ptr, key_sz)) index = 60; // via
if (index != U_NOT_FOUND)
{
*pwbuffer = 0x40;
pwbuffer = hpackEncodeInt(pwbuffer, index, (1<<6)-1);
pwbuffer += hpackEncodeString(pwbuffer, value_ptr, value_sz);
}
/*
else
{
}
*/
U_RETURN(true);
}
void UHTTP2::handlerResponse()
{
U_TRACE(0, "UHTTP2::handlerResponse()")
unsigned char buffer[8192] = { 0, 0, 0, // frame size
HEADERS, // header frame
FLAG_END_HEADERS, // end header flags
0, 0, 0, 0, // stream id
8, 3, '0', '0', '0' }; // use literal header field without indexing - indexed name
U_ASSERT(UClientImage_Base::wbuffer->empty())
U_ASSERT(UClientImage_Base::wbuffer->capacity())
// \000\000#
// \001
// \004
// \000\000\000\001
// \b\003403
// v\004\000UHTa
U_INTERNAL_DUMP("ext(%u) = %#V", UHTTP::ext->size(), UHTTP::ext->rep)
char* ptr = (char*)buffer;
int32_t sz = HTTP2_FRAME_HEADER_SIZE+1;
char* ptr = (char*)UClientImage_Base::wbuffer->data();
uint32_t sz = HTTP2_FRAME_HEADER_SIZE+1, sz1 = UHTTP::set_cookie->size(), sz2 = UHTTP::ext->size();
switch (U_http_info.nResponseCode)
pwbuffer = (unsigned char*)ptr+HTTP2_FRAME_HEADER_SIZE+1;
if (U_http_info.nResponseCode == HTTP_NOT_IMPLEMENTED ||
U_http_info.nResponseCode == HTTP_OPTIONS_RESPONSE)
{
case HTTP_OK: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 8; break;
case HTTP_NO_CONTENT: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 9; break;
case HTTP_PARTIAL: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 10; break;
case HTTP_NOT_MODIFIED: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 11; break;
case HTTP_BAD_REQUEST: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 12; break;
case HTTP_NOT_FOUND: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 13; break;
case HTTP_INTERNAL_ERROR: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 14; break;
ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 8;
default: // use literal header field without indexing - indexed name
*pwbuffer = 0x40;
pwbuffer = hpackEncodeInt(pwbuffer, 22, (1<<6)-1);
pwbuffer += hpackEncodeString(pwbuffer,
U_CONSTANT_TO_PARAM("GET, HEAD, POST, PUT, DELETE, OPTIONS, " // request methods
"TRACE, CONNECT, " // pathological
"COPY, MOVE, LOCK, UNLOCK, MKCOL, PROPFIND, " // webdav
"PATCH, PURGE, " // rfc-5789
"MERGE, REPORT, CHECKOUT, MKACTIVITY, " // subversion
"NOTIFY, MSEARCH, SUBSCRIBE, UNSUBSCRIBE")); // upnp
UClientImage_Base::setCloseConnection();
}
else
{
if (sz2 == 0 &&
U_http_info.nResponseCode == HTTP_OK)
{
sz += 4;
ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 9; // HTTP_NO_CONTENT
}
else
{
switch (U_http_info.nResponseCode)
{
case HTTP_OK: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 8; break;
case HTTP_NO_CONTENT: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 9; break;
case HTTP_PARTIAL: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 10; break;
case HTTP_NOT_MODIFIED: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 11; break;
case HTTP_BAD_REQUEST: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 12; break;
case HTTP_NOT_FOUND: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 13; break;
case HTTP_INTERNAL_ERROR: ptr[HTTP2_FRAME_HEADER_SIZE] = 0x80 | 14; break;
ptr[HTTP2_FRAME_HEADER_SIZE+2] = (U_http_info.nResponseCode / 100) + '0';
U_NUM2STR16(ptr+HTTP2_FRAME_HEADER_SIZE+3, U_http_info.nResponseCode % 100);
default: // use literal header field without indexing - indexed name
{
u_put_unalignedp32(ptr+HTTP2_FRAME_HEADER_SIZE, U_MULTICHAR_CONSTANT32('\010','\003','0'+(U_http_info.nResponseCode / 100),'\0'));
U_NUM2STR16(ptr+HTTP2_FRAME_HEADER_SIZE+3, U_http_info.nResponseCode % 100);
sz += 4;
pwbuffer += 4;
}
}
}
}
// -------------------------------------------------
// literal header field with indexing (indexed name)
unsigned char* dst = buffer+sz;
// -------------------------------------------------
// server: ULib
// date: Wed, 20 Jun 2012 11:43:17 GMT
*dst = 0x40;
dst = hpackEncodeInt(dst, 54, (1<<6)-1);
dst += hpackEncodeString(dst, U_CONSTANT_TO_PARAM("ULib"));
*dst = 0x40;
dst = hpackEncodeInt(dst, 33, (1<<6)-1);
/**
* *pwbuffer = 0x40;
* pwbuffer = hpackEncodeInt(pwbuffer, 54, (1<<6)-1);
* pwbuffer += hpackEncodeString(pwbuffer, U_CONSTANT_TO_PARAM("ULib"));
* *pwbuffer = 0x40;
* pwbuffer = hpackEncodeInt(pwbuffer, 33, (1<<6)-1);
*/
// u__memcpy(dst, "v\004\000UHTa", U_CONSTANT_SIZE("v\004\000UHTa"), __PRETTY_FUNCTION__);
// dst += U_CONSTANT_SIZE("v\004\000UHTa");
u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('v','\004','U','L','i','b','a','\0'));
#if defined(ENABLE_THREAD) && !defined(U_LOG_ENABLE) && !defined(USE_LIBZ)
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
@ -1711,18 +1710,164 @@ void UHTTP2::handlerResponse()
ULog::updateDate3();
#endif
dst += hpackEncodeString(dst, ((char*)UClientImage_Base::iov_vec[1].iov_base)+6, 29); // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
pwbuffer += 7+hpackEncodeString(pwbuffer+7, ((char*)UClientImage_Base::iov_vec[1].iov_base)+6, 29); // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
sz = dst - buffer;
if (sz1)
{
UClientImage_Base::setRequestNoCache();
*pwbuffer = 0x40;
pwbuffer = hpackEncodeInt(pwbuffer, 55, (1<<6)-1);
pwbuffer += hpackEncodeString(pwbuffer, UHTTP::set_cookie->data(), sz1);
UHTTP::set_cookie->setEmpty();
}
if (sz2 == 0)
{
*pwbuffer = 0x40;
pwbuffer = hpackEncodeInt(pwbuffer, 28, (1<<6)-1);
pwbuffer += hpackEncodeString(pwbuffer, U_CONSTANT_TO_PARAM("0"));
}
else
{
UMimeHeader header;
if (header.parse(UHTTP::ext->data(), sz2)) header.table.callForAllEntry(addHTTPHeader);
}
sz = pwbuffer-(unsigned char*)ptr;
*(uint32_t*) ptr = htonl((sz-HTTP2_FRAME_HEADER_SIZE) << 8);
ptr[3] = HEADERS;
ptr[4] = FLAG_END_HEADERS;
*(uint32_t*)(ptr+5) = htonl(pStream->id);
U_DUMP("frame response { length = %d stream_id = %d type = (%d, %s) flags = %d } = %#.*S", ntohl(*(uint32_t*)ptr & 0x00ffffff) >> 8,
U_DUMP("frame header response { length = %d stream_id = %d type = (%d, %s) flags = %d } = %#.*S", ntohl(*(uint32_t*)ptr & 0x00ffffff) >> 8,
ntohl(*(uint32_t*)(ptr+5) & 0x7fffffff), ptr[3], getFrameTypeDescription(ptr[3]), ptr[4], ntohl(*(uint32_t*)ptr & 0x00ffffff) >> 8, ptr + HTTP2_FRAME_HEADER_SIZE)
if (USocketExt::write(UServer_Base::csocket, ptr, sz, UServer_Base::timeoutMS) != sz) nerror = FLOW_CONTROL_ERROR;
sz2 = UClientImage_Base::body->size();
if (sz2)
{
*(uint32_t*) pwbuffer = htonl(sz2 << 8);
pwbuffer[3] = DATA;
pwbuffer[4] = FLAG_END_STREAM;
*(uint32_t*)(pwbuffer+5) = htonl(pStream->id);
U_DUMP("frame data response { length = %d stream_id = %d type = (%d, %s) flags = %d }", ntohl(*(uint32_t*)pwbuffer & 0x00ffffff) >> 8,
ntohl(*(uint32_t*)(pwbuffer+5) & 0x7fffffff), pwbuffer[3], getFrameTypeDescription(pwbuffer[3]), pwbuffer[4])
sz += HTTP2_FRAME_HEADER_SIZE;
}
UClientImage_Base::wbuffer->size_adjust(sz);
UClientImage_Base::setNoHeaderForResponse();
}
int UHTTP2::handlerRequest()
{
U_TRACE(0, "UHTTP2::handlerRequest()")
U_INTERNAL_ASSERT_EQUALS(U_http_version, '2')
U_INTERNAL_DUMP("HTTP2-Settings: = %.*S U_http_method_type = %B", U_http2_settings_len, UHTTP2::upgrade_settings, U_http_method_type)
if (U_http2_settings_len &&
USocketExt::write(UServer_Base::csocket, U_CONSTANT_TO_PARAM(HTTP2_CONNECTION_UPGRADE_AND_SETTING_BIN), UServer_Base::timeoutMS) !=
U_CONSTANT_SIZE(HTTP2_CONNECTION_UPGRADE_AND_SETTING_BIN))
{
U_RETURN(U_PLUGIN_HANDLER_ERROR);
}
U_INTERNAL_ASSERT(UClientImage_Base::request->same(*UClientImage_Base::rbuffer))
UClientImage_Base::request->clear();
// maybe we have read more data than necessary...
uint32_t sz = UClientImage_Base::rbuffer->size();
U_INTERNAL_ASSERT_MAJOR(sz, 0)
if (sz > U_http_info.endHeader) UClientImage_Base::rstart = U_http_info.endHeader;
else
{
// we wait for HTTP2_CONNECTION_PREFACE...
UClientImage_Base::rbuffer->setEmptyForce();
if (UNotifier::waitForRead(UServer_Base::csocket->iSockDesc, U_TIMEOUT_MS) != 1 ||
USocketExt::read(UServer_Base::csocket, *UClientImage_Base::rbuffer, U_SINGLE_READ, 0) == false)
{
U_RETURN(U_PLUGIN_HANDLER_ERROR);
}
UClientImage_Base::rstart = 0;
sz = UClientImage_Base::rbuffer->size();
}
const char* ptr = UClientImage_Base::rbuffer->c_pointer(UClientImage_Base::rstart);
if (u_get_unalignedp64(ptr) != U_MULTICHAR_CONSTANT64( 'P', 'R','I',' ', '*', ' ', 'H', 'T') ||
u_get_unalignedp64(ptr+8) != U_MULTICHAR_CONSTANT64( 'T', 'P','/','2', '.', '0','\r','\n') ||
u_get_unalignedp64(ptr+16) != U_MULTICHAR_CONSTANT64('\r','\n','S','M','\r','\n','\r','\n'))
{
U_RETURN(U_PLUGIN_HANDLER_ERROR);
}
pConnection = (Connection*)UServer_Base::pClientImage->connection;
pConnectionEnd = (char*)pConnection + sizeof(Connection);
pConnection->state = CONN_STATE_OPEN;
pConnection->peer_settings = settings;
pConnection->max_open_stream_id =
pConnection->num_responding_streams =
pConnection->max_processed_stream_id = 0;
pStream = pConnection->streams;
pStream->state = STREAM_STATE_IDLE;
if (U_http2_settings_len == 0)
{
if (USocketExt::write(UServer_Base::csocket, U_CONSTANT_TO_PARAM(HTTP2_SETTINGS_BIN), UServer_Base::timeoutMS) != U_CONSTANT_SIZE(HTTP2_SETTINGS_BIN)) U_RETURN(U_PLUGIN_HANDLER_ERROR);
}
else
{
UString buffer(U_CAPACITY);
UBase64::decodeUrl(upgrade_settings, U_http2_settings_len, buffer);
if (buffer.empty() ||
updateSetting(U_STRING_TO_PARAM(buffer)) == false)
{
U_RETURN(U_PLUGIN_HANDLER_ERROR);
}
}
settings_ack = false;
UClientImage_Base::rstart += U_CONSTANT_SIZE(HTTP2_CONNECTION_PREFACE);
loop:
readFrame();
if (nerror == NO_ERROR)
{
U_INTERNAL_DUMP("settings_ack = %b", settings_ack)
if (settings_ack == false) goto loop; // we wait for SETTINGS ack...
return UHTTP::manageRequest();
}
sendError();
U_RETURN(U_PLUGIN_HANDLER_ERROR);
}
#ifdef ENTRY

View File

@ -1648,37 +1648,6 @@ __pure bool UHTTP::isValidRequestExt(const char* ptr, uint32_t sz)
U_RETURN(false);
}
int UHTTP::handlerDataPending()
{
U_TRACE(0, "UHTTP::handlerDataPending()")
#ifndef U_HTTP2_DISABLE
U_INTERNAL_DUMP("U_http_version = %C", U_http_version)
if (U_http_version == '2')
{
if (UHTTP2::manageSetting() == false)
{
U_ClientImage_state = U_PLUGIN_HANDLER_ERROR;
U_RETURN(-1);
}
U_ClientImage_data_missing = false;
UClientImage_Base::setRequestNeedProcessing();
(void) manageRequest();
U_ClientImage_state = U_PLUGIN_HANDLER_ERROR;
U_RETURN(-1);
}
#endif
return UClientImage_Base::handlerDataPending();
}
bool UHTTP::scanfHeaderRequest(const char* ptr, uint32_t size)
{
U_TRACE(0, "UHTTP::scanfHeaderRequest(%.*S,%u)", size, ptr, size)
@ -1923,7 +1892,7 @@ error: U_SRV_LOG("WARNING: invalid character %C in URI %.*S", c, ptr - U
}
// NB: there are case of requests fragmented (maybe because of VPN tunnel)
// for example something like: GET /info?Mac=00%3A40%3A63%3Afb%3A42%3A1c&ip=172.16.93.235&gateway=172.16.93.254%3A5280&ap=ap%4010.8.0.9
// for example something like: GET /info?Mac=00%3A40%3A63%3Afb%3A42%3A1c&ip=172.16.93.235&gateway=172.16.93.254%3A5280&ap=ap%4010.8.0.9
end:
U_ClientImage_data_missing = true;
@ -3426,7 +3395,7 @@ int UHTTP::handlerREAD()
if (readHeaderRequest() == false)
{
if (U_ClientImage_data_missing) goto dmiss;
if (U_ClientImage_data_missing) U_RETURN(U_PLUGIN_HANDLER_FINISHED);
if (UNLIKELY(UServer_Base::csocket->isClosed())) U_RETURN(U_PLUGIN_HANDLER_ERROR);
@ -3474,12 +3443,7 @@ int UHTTP::handlerREAD()
{
checkRequestForHeader();
if (U_ClientImage_data_missing)
{
dmiss: UClientImage_Base::setRequestProcessed();
U_RETURN(U_PLUGIN_HANDLER_FINISHED);
}
if (U_ClientImage_data_missing) U_RETURN(U_PLUGIN_HANDLER_FINISHED);
}
U_INTERNAL_DUMP("U_http_host_len = %u U_HTTP_HOST = %.*S", U_http_host_len, U_HTTP_HOST_TO_TRACE)
@ -4092,7 +4056,7 @@ int UHTTP::processRequest()
*UClientImage_Base::body = getBodyFromCache();
}
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
# endif
U_RETURN(U_PLUGIN_HANDLER_FINISHED);
@ -4138,7 +4102,7 @@ int UHTTP::processRequest()
(void) ext->append(getHeaderMimeType(0, sz, U_CTYPE_HTML));
*UClientImage_Base::wbuffer = getHeaderForResponse(); // build response...
handlerResponse();
}
U_RETURN(U_PLUGIN_HANDLER_FINISHED);
@ -4221,7 +4185,7 @@ empty_file: // NB: now we check for empty file...
ext->clear();
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
}
}
@ -5515,9 +5479,9 @@ void UHTTP::setStatusDescription()
U_INTERNAL_DUMP("UClientImage_Base::iov_vec[0] = %.*S", UClientImage_Base::iov_vec[0].iov_len, UClientImage_Base::iov_vec[0].iov_base)
}
UString UHTTP::getHeaderForResponse()
void UHTTP::handlerResponse()
{
U_TRACE(0, "UHTTP::getHeaderForResponse()")
U_TRACE(0, "UHTTP::handlerResponse()")
U_INTERNAL_DUMP("U_http_info.nResponseCode = %d", U_http_info.nResponseCode)
@ -5535,27 +5499,23 @@ UString UHTTP::getHeaderForResponse()
UClientImage_Base::setRequestProcessed();
#ifndef U_HTTP2_DISABLE
if (U_http_version == '2')
{
UHTTP2::handlerResponse();
return UString::getStringNull();
}
if (U_http_version == '2') UHTTP2::handlerResponse();
else
#endif
{
UClientImage_Base::setHeaderForResponse(6+29+2+12+2); // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n
if (U_http_info.nResponseCode == HTTP_NOT_IMPLEMENTED ||
U_http_info.nResponseCode == HTTP_OPTIONS_RESPONSE)
{
UString result = U_STRING_FROM_CONSTANT("Allow: "
(void) UClientImage_Base::wbuffer->assign(U_CONSTANT_TO_PARAM("Allow: "
"GET, HEAD, POST, PUT, DELETE, OPTIONS, " // request methods
"TRACE, CONNECT, " // pathological
"COPY, MOVE, LOCK, UNLOCK, MKCOL, PROPFIND, " // webdav
"PATCH, PURGE, " // rfc-5789
"MERGE, REPORT, CHECKOUT, MKACTIVITY, " // subversion
"NOTIFY, MSEARCH, SUBSCRIBE, UNSUBSCRIBE" // upnp
"\r\nContent-Length: 0\r\n\r\n");
"\r\nContent-Length: 0\r\n\r\n"));
UClientImage_Base::setRequestNoCache();
UClientImage_Base::setCloseConnection();
@ -5564,7 +5524,7 @@ UString UHTTP::getHeaderForResponse()
setStatusDescription();
U_RETURN_STRING(result);
return;
}
// NB: all other responses must include an entity body or a Content-Length header field defined with a value of zero (0)
@ -5600,9 +5560,9 @@ UString UHTTP::getHeaderForResponse()
setStatusDescription();
UString result(200U + sz1 + sz2);
UClientImage_Base::wbuffer->setBuffer(200U + sz1 + sz2);
base = ptr = result.data();
base = ptr = UClientImage_Base::wbuffer->data();
if (sz1)
{
@ -5673,11 +5633,11 @@ UString UHTTP::getHeaderForResponse()
u__memcpy(ptr, ptr2, sz2, __PRETTY_FUNCTION__);
result.size_adjust((ptr - base) + sz2);
UClientImage_Base::wbuffer->size_adjust((ptr - base) + sz2);
}
U_INTERNAL_DUMP("result(%u) = %V", result.size(), result.rep)
U_RETURN_STRING(result);
U_INTERNAL_DUMP("UClientImage_Base::wbuffer(%u) = %#V", UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
U_INTERNAL_DUMP("UClientImage_Base::body(%u) = %V", UClientImage_Base::body->size(), UClientImage_Base::body->rep)
}
void UHTTP::setResponse(const UString* content_type, UString* pbody)
@ -5709,55 +5669,65 @@ void UHTTP::setResponse(const UString* content_type, UString* pbody)
ptr += sz;
# ifndef U_HTTP2_DISABLE
if (U_http_version != '2')
# endif
{
u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
ptr += U_CONSTANT_SIZE("Content-Length: ");
}
if (pbody == 0) *ptr++ = '0';
else
if (pbody == 0)
{
sz = pbody->size();
# ifdef USE_LIBZ
if (UStringExt::isGzip(*pbody))
{
if (U_http_is_accept_gzip == false)
{
*pbody = UStringExt::gunzip(*pbody);
sz = pbody->size();
}
ptr += u_num2str32(ptr, sz);
if (U_http_is_accept_gzip)
{
u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('\r','\n','C','o','n','t','e','n'));
u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('t', '-','E','n','c','o','d','i'));
u_put_unalignedp64(ptr+16, U_MULTICHAR_CONSTANT64('n', 'g',':',' ','g','z','i','p'));
ptr += U_CONSTANT_SIZE("\r\nContent-Encoding: gzip");
}
}
else
# ifndef U_HTTP2_DISABLE
if (U_http_version != '2')
# endif
ptr += u_num2str32(ptr, sz);
*ptr++ = '0';
UClientImage_Base::body->clear(); // clean body to avoid writev() in response...
goto end;
}
u_put_unalignedp32(ptr, U_MULTICHAR_CONSTANT32('\r','\n','\r','\n'));
# ifdef USE_LIBZ
if (UStringExt::isGzip(*pbody))
{
if (U_http_is_accept_gzip) *pbody = UStringExt::gunzip(*pbody);
# ifndef U_HTTP2_DISABLE
if (U_http_version != '2')
# endif
ptr += u_num2str32(ptr, pbody->size());
if (U_http_is_accept_gzip)
{
u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('\r','\n','C','o','n','t','e','n'));
u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('t', '-','E','n','c','o','d','i'));
u_put_unalignedp64(ptr+16, U_MULTICHAR_CONSTANT64('n', 'g',':',' ','g','z','i','p'));
ptr += U_CONSTANT_SIZE("\r\nContent-Encoding: gzip");
}
}
else
# endif
{
# ifndef U_HTTP2_DISABLE
if (U_http_version != '2')
# endif
ptr += u_num2str32(ptr, pbody->size());
}
*UClientImage_Base::body = *pbody;
end: u_put_unalignedp32(ptr, U_MULTICHAR_CONSTANT32('\r','\n','\r','\n'));
ptr += U_CONSTANT_SIZE(U_CRLF2);
ext->size_adjust(ptr - start);
}
if (pbody) *UClientImage_Base::body = *pbody;
else UClientImage_Base::body->clear(); // clean body to avoid writev() in response...
*UClientImage_Base::wbuffer = getHeaderForResponse();
U_INTERNAL_DUMP("UClientImage_Base::wbuffer(%u) = %V", UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
U_INTERNAL_DUMP("UClientImage_Base::body(%u) = %V", UClientImage_Base::body->size(), UClientImage_Base::body->rep)
handlerResponse();
}
#define U_STR_FMR_BODY "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n" \
@ -6110,7 +6080,7 @@ end:
ext->size_adjust(ptr1);
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
}
U_NO_EXPORT bool UHTTP::processAuthorization()
@ -7680,8 +7650,9 @@ U_NO_EXPORT bool UHTTP::processFileCache()
*ext = getHeaderCompressFromCache();
*UClientImage_Base::wbuffer = getHeaderForResponse();
*UClientImage_Base::body = getBodyCompressFromCache();
*UClientImage_Base::body = getBodyCompressFromCache();
handlerResponse();
U_RETURN(true);
}
@ -7722,7 +7693,7 @@ U_NO_EXPORT bool UHTTP::processFileCache()
U_http_sendfile = true;
}
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
U_RETURN(result);
}
@ -8288,7 +8259,7 @@ bool UHTTP::getCGIEnvironment(UString& environment, int mask)
if (requestHeader.parse(UClientImage_Base::request->c_pointer(U_http_info.startHeader), U_http_info.endHeader - U_CONSTANT_SIZE(U_CRLF2) - U_http_info.startHeader))
{
// The environment must not contain the keys HTTP_CONTENT_TYPE or HTTP_CONTENT_LENGTH (we use the versions without HTTP_).
// The environment must not contain the keys HTTP_CONTENT_TYPE or HTTP_CONTENT_LENGTH (we use the versions without HTTP_)
requestHeader.removeHeader(*UString::str_content_type);
requestHeader.removeHeader(*UString::str_content_length);
@ -8869,7 +8840,7 @@ loop:
UClientImage_Base::body->clear();
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
U_RETURN(true);
}
@ -9083,11 +9054,11 @@ loop:
ext->clear();
UClientImage_Base::body->clear();
(void) set_cookie->append(UClientImage_Base::wbuffer->data(), sz - U_CONSTANT_SIZE(U_CRLF)); // NB: opportunism...
*UClientImage_Base::wbuffer = getHeaderForResponse();
UClientImage_Base::body->clear();
handlerResponse();
U_RETURN(true);
}
@ -9224,7 +9195,7 @@ bool UHTTP::checkContentLength(uint32_t length, uint32_t pos)
(void) ext->replace(pos, sz_len1, bp, sz_len2);
U_INTERNAL_DUMP("x(%u) = %#V", ext->size(), ext->rep)
U_INTERNAL_DUMP("ext(%u) = %#V", ext->size(), ext->rep)
U_RETURN(true);
}
@ -9522,8 +9493,9 @@ U_NO_EXPORT int UHTTP::checkGetRequestForRange(const UString& data)
(void) UFile::writeToTmp(U_STRING_TO_PARAM(*ext), false, "byteranges.%P", 0);
#endif
U_http_info.nResponseCode = HTTP_PARTIAL;
*UClientImage_Base::wbuffer = getHeaderForResponse();
U_http_info.nResponseCode = HTTP_PARTIAL;
handlerResponse();
U_RETURN(U_YES);
}
@ -9695,7 +9667,7 @@ U_NO_EXPORT void UHTTP::processGetRequest()
setResponseForRange(range_start, range_size-1, U_CONSTANT_SIZE(U_FLV_HEAD));
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
(void) UClientImage_Base::wbuffer->append(U_CONSTANT_TO_PARAM(U_FLV_HEAD));
@ -9704,7 +9676,7 @@ U_NO_EXPORT void UHTTP::processGetRequest()
}
build_response:
*UClientImage_Base::wbuffer = getHeaderForResponse();
handlerResponse();
next:
U_INTERNAL_DUMP("range_start = %u range_size = %u UServer_Base::min_size_for_sendfile = %u", range_start, range_size, UServer_Base::min_size_for_sendfile)

View File

@ -22,9 +22,9 @@ export ORM_DRIVER ORM_OPTION UMEMPOOL
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
# PLAINTEXT
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
#UMEMPOOL="982,0,0,36,9846,-24,-23,1727,1151"
#sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 16384|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
UMEMPOOL="982,0,0,36,9846,-24,-23,1727,1151"
sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 16384|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 4000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
@ -58,9 +58,9 @@ export ORM_DRIVER ORM_OPTION UMEMPOOL
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
# JSON
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
UMEMPOOL="56,0,0,40,150,-24,-13,-20,0"
sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#UMEMPOOL="56,0,0,40,150,-24,-13,-20,0"
#sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 50|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
# ----------------------------------------------------------------------------------------------------------------------------------------------------------