void HTTPSession::PrintPair(const ReadBuffer& key, const ReadBuffer& value) { if (!conn) return; if (!headerSent) { if (type == JSON) json.Start(); else conn->WriteHeader(HTTP_STATUS_CODE_OK); headerSent = true; } if (type == JSON) json.PrintPair(key.GetBuffer(), key.GetLength(), value.GetBuffer(), value.GetLength()); else { conn->Write(key.GetBuffer(), key.GetLength()); conn->Print(": "); conn->Write(value.GetBuffer(), value.GetLength()); conn->Print("\n"); } }
void StorageMemoKeyValue::Set(ReadBuffer key_, ReadBuffer value_) { if (buffer != NULL) free(buffer); keyLength = key_.GetLength(); valueLength = value_.GetLength(); buffer = (char*) malloc(GetLength()); memcpy(buffer, key_.GetBuffer(), keyLength); memcpy(buffer + keyLength, value_.GetBuffer(), valueLength); }
bool HTTPSession::ParseRequest(HTTPRequest& request, ReadBuffer& cmd, UrlParam& params) { char* qmark; ReadBuffer rb; ReadBuffer jsonCallback; ReadBuffer mimeType; ReadBuffer origin; // TODO: when adding keep-alive HTTP sessions, move this to an Init() function isFlushed = false; uri = request.line.uri; rb = request.line.uri; if (rb.GetCharAt(0) == '/') rb.Advance(1); mimeType.Reset(); ParseType(rb); cmd = rb; qmark = NULL; if (rb.GetLength() > 0) qmark = FindInBuffer(rb.GetBuffer(), rb.GetLength() - 1, '?'); if (qmark) { rb.Advance((unsigned) (qmark - rb.GetBuffer() + 1)); params.Init(rb.GetBuffer(), rb.GetLength(), '&'); cmd.SetLength((unsigned) (qmark - cmd.GetBuffer())); if (type == JSON) { HTTP_GET_OPT_PARAM(params, "callback", jsonCallback); json.SetCallbackPrefix(jsonCallback); } // mime type is overridable HTTP_GET_OPT_PARAM(params, "mimetype", mimeType); if (mimeType.GetLength() != 0) conn->SetContentType(mimeType); // CORS support // http://www.w3.org/TR/cors/ HTTP_GET_OPT_PARAM(params, "origin", origin); } return true; }
void HTTPSession::Print(const ReadBuffer& line) { Buffer header; ReadBuffer tmp; if (!conn) return; if (!headerSent) { if (type == JSON) json.Start(); else conn->WriteHeader(HTTP_STATUS_CODE_OK); headerSent = true; } if (type == JSON) { tmp = "response"; json.PrintString(tmp); json.PrintColon(); json.PrintString(line); } else { conn->Write(line.GetBuffer(), line.GetLength()); conn->Print("\n"); } }
void StorageMemoKeyValue::Delete(ReadBuffer key_) { if (buffer != NULL) free(buffer); keyLength = key_.GetLength(); valueLength = DELETE_LENGTH_VALUE; buffer = (char*) malloc(GetLength()); memcpy(buffer, key_.GetBuffer(), keyLength); }
bool Endpoint::Set(ReadBuffer ip_port, bool resolv) { const char* p; const char* start; int port; bool ret; Buffer ipbuf; Buffer portbuf; if (!IsValidEndpoint(ReadBuffer(ip_port))) return false; start = p = ip_port.GetBuffer(); p = RevFindInBuffer(ip_port.GetBuffer(), ip_port.GetLength(), ':'); if (p == NULL) { Log_Trace("No ':' in host specification"); return false; } ipbuf.Append(start, p - start); ipbuf.NullTerminate(); p++; portbuf.Append(p, ip_port.GetLength() - (p - start)); portbuf.NullTerminate(); port = -1; port = atoi(portbuf.GetBuffer()); if (port < 1 || port > 65535) { Log_Trace("atoi() failed to produce a sensible value"); return false; } ret = Set(ipbuf.GetBuffer(), port, resolv); return ret; }
uint64_t QuorumDatabase::GetUint64(const char* name) { ReadBuffer key(name); ReadBuffer value; uint64_t u64; unsigned nread; int ret; ret = paxosShard->Get(key, value); if (!ret) return false; nread = 0; u64 = BufferToUInt64(value.GetBuffer(), value.GetLength(), &nread); if (nread != value.GetLength()) { Log_Trace(); u64 = 0; } return u64; }
bool Endpoint::IsValidEndpoint(ReadBuffer ip_port) { // Valid endpoint is either <IPv4-Address>:<port> or <IPv6-Address>:<port> or <Domain-Name>:<port> // Valid IPv4-Address consists only from numbers and three dots between the numbers // Valid IPv6-Adresses: http://en.wikipedia.org/wiki/IPv6#Addressing // Valid domain names: http://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names const char VALID_CHARS[] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; unsigned i; bool labelStart; bool isNumeric; bool isHexnum; bool isPort; bool isIPv6; unsigned numCommas; unsigned numPortChars; char c; char prev; char sep; char* lastColon; // assuming fully numeric names isNumeric = true; isHexnum = true; isPort = false; numCommas = 0; numPortChars = 0; labelStart = true; isIPv6 = false; prev = ' '; sep = ' '; lastColon = NULL; for (i = 0; i < ip_port.GetLength(); i++) { c = ip_port.GetCharAt(i); if (c == '.' || c == ':') { if (i == 0) { // IPv4 and DNS must not start with comma or colon if (c == '.') return false; isIPv6 = true; isHexnum = true; } // labels must not end with hyphens if (prev == VALID_CHARS[0]) return false; if (c == '.') { labelStart = true; numCommas++; sep = c; } if (c == ':') { // cannot mix IPv4 and IPv6 addresses this way // this however is legal in IPv6: ::ffff:192.0.2.128 if (isHexnum && sep != '.') { isIPv6 = true; sep = ':'; isPort = true; numPortChars = 0; } else { if (isPort && !isIPv6) return false; isPort = true; numPortChars = 0; } lastColon = ip_port.GetBuffer() + i; } } else { // labels must not start with hyphens if (labelStart && c == VALID_CHARS[0]) return false; if (isPort) { if (!isdigit(c)) { if (isIPv6) isPort = false; else return false; } else numPortChars++; } if (isNumeric && !isdigit(c)) isNumeric = false; if (isHexnum && !isxdigit(c)) { if (isIPv6) return false; isHexnum = false; } if (strchr(VALID_CHARS, c) == NULL) return false; labelStart = false; } prev = c; } if (isNumeric && numCommas != 3) return false; if (isIPv6 && numCommas != 0 && numCommas != 3) return false; if (numPortChars < 1 || numPortChars > 5) return false; return true; }
void Buffer::Append(ReadBuffer other) { Append(other.GetBuffer(), other.GetLength()); }
void Buffer::Write(const ReadBuffer other) { Write(other.GetBuffer(), other.GetLength()); }