123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #include "httpreqdata.h"
- #include <util/stream/mem.h>
- TBaseServerRequestData::TBaseServerRequestData(SOCKET s)
- : Addr(nullptr)
- , Host()
- , Port()
- , Path(nullptr)
- , Search(nullptr)
- , SearchLength(0)
- , Socket(s)
- , BeginTime(MicroSeconds())
- {
- }
- TBaseServerRequestData::TBaseServerRequestData(const char* qs, SOCKET s)
- : Addr(nullptr)
- , Host()
- , Port()
- , Path(nullptr)
- , Search((char*)qs)
- , SearchLength(qs ? strlen(qs) : 0)
- , OrigSearch(Search, SearchLength)
- , Socket(s)
- , BeginTime(MicroSeconds())
- {
- }
- void TBaseServerRequestData::AppendQueryString(const char* str, size_t length) {
- if (Y_UNLIKELY(Search)) {
- Y_ASSERT(strlen(Search) == SearchLength);
- ModifiedQueryString.Reserve(SearchLength + length + 2);
- ModifiedQueryString.Assign(Search, SearchLength);
- if (SearchLength > 0 && Search[SearchLength - 1] != '&' &&
- length > 0 && str[0] != '&') {
- ModifiedQueryString.Append('&');
- }
- ModifiedQueryString.Append(str, length);
- } else {
- ModifiedQueryString.Reserve(length + 1);
- ModifiedQueryString.Assign(str, length);
- }
- ModifiedQueryString.Append('\0');
- Search = ModifiedQueryString.data();
- SearchLength = ModifiedQueryString.size() - 1; // ignore terminator
- }
- void TBaseServerRequestData::SetRemoteAddr(TStringBuf addr) {
- TMemoryOutput out(AddrData, Y_ARRAY_SIZE(AddrData) - 1);
- out.Write(addr.substr(0, Y_ARRAY_SIZE(AddrData) - 1));
- *out.Buf() = '\0';
- Addr = AddrData;
- }
- const char* TBaseServerRequestData::RemoteAddr() const {
- if (!Addr) {
- *AddrData = 0;
- GetRemoteAddr(Socket, AddrData, sizeof(AddrData));
- Addr = AddrData;
- }
- return Addr;
- }
- const char* TBaseServerRequestData::HeaderIn(TStringBuf key) const {
- auto it = HeadersIn_.find(key);
- if (it == HeadersIn_.end()) {
- return nullptr;
- }
- return it->second.data();
- }
- TString TBaseServerRequestData::HeaderByIndex(size_t n) const noexcept {
- if (n >= HeadersCount()) {
- return nullptr;
- }
- THttpHeadersContainer::const_iterator i = HeadersIn_.begin();
- while (n) {
- ++i;
- --n;
- }
- return TString(i->first) + TStringBuf(": ") + i->second;
- }
- const char* TBaseServerRequestData::Environment(const char* key) const {
- if (stricmp(key, "REMOTE_ADDR") == 0) {
- const char* ip = HeaderIn("X-Real-IP");
- if (ip)
- return ip;
- return RemoteAddr();
- } else if (stricmp(key, "QUERY_STRING") == 0) {
- return QueryString();
- } else if (stricmp(key, "SERVER_NAME") == 0) {
- return ServerName().data();
- } else if (stricmp(key, "SERVER_PORT") == 0) {
- return ServerPort().data();
- } else if (stricmp(key, "SCRIPT_NAME") == 0) {
- return ScriptName();
- }
- return nullptr;
- }
- void TBaseServerRequestData::Clear() {
- HeadersIn_.clear();
- Addr = Path = Search = nullptr;
- OrigSearch = {};
- SearchLength = 0;
- Host.clear();
- Port.clear();
- CurPage.remove();
- ParseBuf.Clear();
- BeginTime = MicroSeconds();
- }
- const char* TBaseServerRequestData::GetCurPage() const {
- if (!CurPage && Host) {
- CurPage = "http://";
- CurPage += Host;
- if (Port) {
- CurPage += ':';
- CurPage += Port;
- }
- CurPage += Path;
- if (Search) {
- CurPage += '?';
- CurPage += Search;
- }
- }
- return CurPage.data();
- }
- bool TBaseServerRequestData::Parse(const char* origReq) {
- size_t origReqLength = strlen(origReq);
- ParseBuf.Assign(origReq, origReqLength + 1);
- char* req = ParseBuf.Data();
- while (*req == ' ' || *req == '\t')
- req++;
- if (*req != '/')
- return false; // we are not a proxy
- while (req[1] == '/') // remove redundant slashes
- req++;
- // detect url end (can contain some garbage after whitespace, e.g. 'HTTP 1.1')
- char* urlEnd = req;
- while (*urlEnd && *urlEnd != ' ' && *urlEnd != '\t')
- urlEnd++;
- if (*urlEnd)
- *urlEnd = 0;
- // cut fragment if exists
- char* fragment = strchr(req, '#');
- if (fragment)
- *fragment = 0; // ignore fragment
- else
- fragment = urlEnd;
- Path = req;
- // calculate Search length without additional strlen-ing
- Search = strchr(Path, '?');
- if (Search) {
- *Search++ = 0;
- ptrdiff_t delta = fragment - Search;
- // indeed, second case is a parse error
- SearchLength = (delta >= 0) ? delta : (urlEnd - Search);
- Y_ASSERT(strlen(Search) == SearchLength);
- } else {
- SearchLength = 0;
- }
- OrigSearch = {Search, SearchLength};
- return true;
- }
- void TBaseServerRequestData::AddHeader(const TString& name, const TString& value) {
- HeadersIn_[name] = value;
- if (stricmp(name.data(), "Host") == 0) {
- size_t hostLen = strcspn(value.data(), ":");
- if (value[hostLen] == ':')
- Port = value.substr(hostLen + 1);
- Host = value.substr(0, hostLen);
- }
- }
- void TBaseServerRequestData::SetPath(const TString& path) {
- PathStorage = TBuffer(path.data(), path.size() + 1);
- Path = PathStorage.Data();
- }
|