/*---------------------------------------------------------------------- | NPT_File::Load +---------------------------------------------------------------------*/ NPT_Result NPT_File::Load(const char* path, NPT_String& data, NPT_FileInterface::OpenMode mode) { NPT_DataBuffer buffer; // reset ouput params data = ""; // create and open the file NPT_File file(path); NPT_Result result = file.Open(mode); if (NPT_FAILED(result)) return result; // load the file result = file.Load(buffer); if (NPT_SUCCEEDED(result) && buffer.GetDataSize() > 0) { data.Assign((const char*)buffer.GetData(), buffer.GetDataSize()); data.SetLength(buffer.GetDataSize()); } // close the file file.Close(); return result; }
/*---------------------------------------------------------------------- | NPT_Zip::Inflate +---------------------------------------------------------------------*/ NPT_Result NPT_Zip::Inflate(const NPT_DataBuffer& in, NPT_DataBuffer& out, bool raw) { // assume an output buffer twice the size of the input plus a bit NPT_CHECK_WARNING(out.Reserve(32+2*in.GetDataSize())); // setup the stream z_stream stream; stream.next_in = (Bytef*)in.GetData(); stream.avail_in = (uInt)in.GetDataSize(); stream.next_out = out.UseData(); stream.avail_out = (uInt)out.GetBufferSize(); // setup the memory functions stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; // initialize the decompressor int err = inflateInit2(&stream, raw?-15:15+32); // 15 = default window bits, +32 = automatic header if (err != Z_OK) return MapError(err); // decompress until the end do { err = inflate(&stream, Z_SYNC_FLUSH); if (err == Z_STREAM_END || err == Z_OK || err == Z_BUF_ERROR) { out.SetDataSize((NPT_Size)stream.total_out); if ((err == Z_OK && stream.avail_out == 0) || err == Z_BUF_ERROR) { // grow the output buffer out.Reserve(out.GetBufferSize()*2); stream.next_out = out.UseData()+stream.total_out; stream.avail_out = out.GetBufferSize()-(NPT_Size)stream.total_out; } } } while (err == Z_OK); // check for errors if (err != Z_STREAM_END) { inflateEnd(&stream); return MapError(err); } // cleanup err = inflateEnd(&stream); return MapError(err); }
/*---------------------------------------------------------------------- | NPT_Zip::Deflate +---------------------------------------------------------------------*/ NPT_Result NPT_Zip::Deflate(const NPT_DataBuffer& in, NPT_DataBuffer& out, int compression_level, Format format /* = ZLIB */) { // default return state out.SetDataSize(0); // check parameters if (compression_level < NPT_ZIP_COMPRESSION_LEVEL_DEFAULT || compression_level > NPT_ZIP_COMPRESSION_LEVEL_MAX) { return NPT_ERROR_INVALID_PARAMETERS; } // setup the stream z_stream stream; NPT_SetMemory(&stream, 0, sizeof(stream)); stream.next_in = (Bytef*)in.GetData(); stream.avail_in = (uInt)in.GetDataSize(); // setup the memory functions stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; // initialize the compressor int err = deflateInit2(&stream, compression_level, Z_DEFLATED, 15 + (format == GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return MapError(err); // reserve an output buffer known to be large enough out.Reserve(deflateBound(&stream, stream.avail_in) + (format==GZIP?10:0)); stream.next_out = out.UseData(); stream.avail_out = out.GetBufferSize(); // decompress err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { deflateEnd(&stream); return MapError(err); } // update the output size out.SetDataSize(stream.total_out); // cleanup err = deflateEnd(&stream); return MapError(err); }
/*---------------------------------------------------------------------- | NPT_File::Save +---------------------------------------------------------------------*/ NPT_Result NPT_File::Save(const NPT_DataBuffer& buffer) { NPT_OutputStreamReference output; // get the output stream for the file NPT_CHECK_FATAL(GetOutputStream(output)); // write to the stream return output->WriteFully(buffer.GetData(), buffer.GetDataSize()); }
/*---------------------------------------------------------------------- | NPT_LogManager::ParseConfigFile +---------------------------------------------------------------------*/ NPT_Result NPT_LogManager::ParseConfigFile(const char* filename) { NPT_Result result; /* load the file */ NPT_DataBuffer buffer; result = NPT_File::Load(filename, buffer); if (NPT_FAILED(result)) return result; /* parse the config */ return ParseConfig((const char*)buffer.GetData(), buffer.GetDataSize()); }
void FrontEnd::ssdpConnectorOnPacket(SsdpServerTask *task, Interface *intf, const NPT_DataBuffer& data, const NPT_SocketAddress& fromAddr) { const char *dataStr = reinterpret_cast<const char*>(data.GetData()); if (data.GetDataSize() > 10) { if (NPT_String::CompareN(dataStr, "NOTIFY", 6) == 0) { ReadLocker locker(m_cpLock); for (NPT_Ordinal i = 0; i < m_controlPointList.GetItemCount(); i++) { NPT_List<ControlPointInfo*>::Iterator it = m_controlPointList.GetItem(i); ControlPointInfo *info = *it; if (task->aborted()) { return; } info->m_controlPoint->processSsdpNotify(&intf->m_context, data, fromAddr); } } else if (NPT_String::CompareN(dataStr, "M-SEARCH", 8) == 0) { processSsdpSearch(task, intf, data, fromAddr); } } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /*argc*/, char** /*argv*/) { NPT_Result result; NPT_String t = "hello"; NPT_String base64; NPT_DataBuffer data; result = NPT_Base64::Encode((const NPT_Byte*)t.GetChars(), t.GetLength(), base64); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == "aGVsbG8="); result = NPT_Base64::Decode(base64.GetChars(), base64.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == t.GetLength()); NPT_String tt((const char*)data.GetData(), data.GetDataSize()); NPT_ASSERT(tt == t); t = "hello!"; result = NPT_Base64::Encode((const NPT_Byte*)t.GetChars(), t.GetLength(), base64); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == "aGVsbG8h"); result = NPT_Base64::Decode(base64.GetChars(), base64.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == t.GetLength()); tt.Assign((const char*)data.GetData(), data.GetDataSize()); NPT_ASSERT(tt == t); t = "hello!!"; result = NPT_Base64::Encode((const NPT_Byte*)t.GetChars(), t.GetLength(), base64); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == "aGVsbG8hIQ=="); result = NPT_Base64::Decode(base64.GetChars(), base64.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == t.GetLength()); tt.Assign((const char*)data.GetData(), data.GetDataSize()); NPT_ASSERT(tt == t); unsigned char r256_bin[] = { 0x7d, 0x5f, 0xd0, 0xf4, 0x6a, 0xa8, 0xae, 0x34, 0x6e, 0x32, 0x1d, 0xa1, 0xef, 0x66, 0xdd, 0x82, 0x76, 0xa6, 0xfd, 0x8c, 0x75, 0x97, 0xa0, 0x01, 0x00, 0xde, 0x52, 0xef, 0xdf, 0xb6, 0x3e, 0xe4, 0x7b, 0x45, 0xdd, 0x2b, 0xa1, 0x9c, 0xb0, 0x6d, 0x2c, 0x75, 0xb1, 0x87, 0x43, 0x0f, 0xea, 0x24, 0x36, 0x11, 0x7e, 0xee, 0xd1, 0x91, 0x7f, 0x7b, 0x02, 0xea, 0x9a, 0x2a, 0x25, 0xc0, 0xac, 0x99, 0xa4, 0x89, 0x55, 0x5b, 0x82, 0xdf, 0xb0, 0x7e, 0xa1, 0x78, 0x0f, 0xdf, 0x25, 0x5f, 0x3d, 0xba, 0xcb, 0xbc, 0x35, 0x04, 0xc3, 0xf4, 0xb8, 0xc0, 0x17, 0x8e, 0x75, 0x01, 0xe6, 0x2f, 0x88, 0x2c, 0x76, 0x0a, 0x8c, 0x3f, 0x83, 0xd4, 0x10, 0xa8, 0x00, 0xfc, 0xa0, 0x92, 0x7b, 0xae, 0xa3, 0x8c, 0x47, 0xea, 0x25, 0xf9, 0x29, 0x81, 0x1c, 0x21, 0xf2, 0xf4, 0xfe, 0x07, 0x7e, 0x4b, 0x01, 0x79, 0x41, 0x3a, 0xb6, 0x71, 0x0b, 0x75, 0xa7, 0x9d, 0x1b, 0x12, 0xc4, 0x46, 0x06, 0xf3, 0x5f, 0x00, 0x05, 0x2a, 0x1b, 0x34, 0xd6, 0x87, 0xc4, 0x70, 0xcc, 0xc3, 0x9e, 0xa8, 0x24, 0x2c, 0x97, 0x4e, 0xfc, 0x91, 0x70, 0x1c, 0x29, 0x66, 0xc3, 0x23, 0xbf, 0xd7, 0x4d, 0x35, 0x51, 0xff, 0xeb, 0xde, 0x45, 0xbd, 0x8d, 0x80, 0x44, 0x2a, 0x8d, 0xc0, 0xe8, 0x6a, 0xe2, 0x86, 0x46, 0x9f, 0xf2, 0x3c, 0x93, 0x0d, 0x27, 0x02, 0xe4, 0x79, 0xa1, 0x21, 0xf4, 0x43, 0xcd, 0x4c, 0x22, 0x25, 0x9e, 0x93, 0xeb, 0x77, 0x8e, 0x1e, 0x57, 0x1e, 0x9b, 0xcb, 0x91, 0x86, 0xcf, 0x15, 0xaf, 0xd5, 0x03, 0x0f, 0x70, 0xbe, 0x6e, 0x37, 0xea, 0x37, 0xdd, 0xf6, 0xa1, 0xb1, 0xf7, 0x05, 0xbc, 0x2d, 0x44, 0x60, 0x35, 0xa4, 0x05, 0x0b, 0x22, 0x7d, 0x7a, 0x71, 0xe5, 0x1d, 0x8e, 0xcb, 0xc3, 0xb8, 0x3a, 0xe1 }; NPT_String b64; NPT_Base64::Encode(r256_bin, sizeof(r256_bin), b64); NPT_DataBuffer r256_out; NPT_Base64::Decode(b64.GetChars(), b64.GetLength(), r256_out); NPT_ASSERT(r256_out.GetDataSize() == sizeof(r256_bin)); NPT_ASSERT(r256_bin[sizeof(r256_bin)-1] == r256_out.GetData()[sizeof(r256_bin)-1]); unsigned char random_bytes[] = { 0xc7, 0xee, 0x49, 0x9e, 0x2c, 0x8b, 0x1c, 0x16, 0x9e, 0x7f, 0x30, 0xd0, 0xc6, 0x12, 0x30, 0x80, 0x81, 0xcd, 0x20, 0x20, 0x26, 0xaf, 0x4f, 0xd6, 0xfc, 0x86, 0x2e, 0x85, 0xf3, 0x10, 0x38, 0x2b, 0x0e, 0xbb, 0x80, 0x68, 0xbe, 0xff, 0x1c, 0xdc, 0x72, 0xb5, 0x0d, 0x8f, 0x8e, 0x6c, 0x09, 0x63, 0xba, 0x21, 0x23, 0xb2, 0x24, 0x17, 0xd3, 0x17, 0x69, 0x44, 0x77, 0x11, 0x36, 0x6a, 0x6e, 0xf2, 0x44, 0x87, 0xa1, 0xd3, 0xf3, 0x1f, 0x6c, 0x38, 0x22, 0x4a, 0x44, 0x70, 0x66, 0xef, 0x8c, 0x3a, 0x51, 0xc8, 0xee, 0x85, 0x00, 0x25, 0x93, 0x10, 0x2e, 0x0b, 0x1b, 0x03, 0x94, 0x47, 0x05, 0x22, 0xd0, 0xc4, 0xec, 0x2e, 0xcc, 0xbc, 0xbb, 0x67, 0xfd, 0xec, 0x0e, 0xb1, 0x3f, 0xbc, 0x82, 0xe0, 0xa7, 0x9c, 0xf3, 0xae, 0xbd, 0xb7, 0xab, 0x02, 0xf1, 0xd9, 0x17, 0x4c, 0x9d, 0xeb, 0xe2, 0x00, 0x1e, 0x19, 0x6e, 0xb3, 0xfd, 0x7d, 0xea, 0x49, 0x85, 0x43, 0x2f, 0x56, 0x81, 0x89, 0xba, 0x71, 0x37, 0x10, 0xb5, 0x74, 0xab, 0x90, 0x4d, 0xc4, 0xd1, 0x0d, 0x8d, 0x6f, 0x01, 0xf5, 0x2c, 0xc9, 0x1a, 0x79, 0xa1, 0x41, 0x71, 0x2b, 0xfb, 0xf3, 0xd5, 0xe4, 0x2a, 0xf5, 0xad, 0x80, 0x7a, 0x03, 0xff, 0x5f, 0x45, 0x8c, 0xec, 0x6a, 0x4b, 0x05, 0xe3, 0x65, 0x19, 0x70, 0x05, 0xad, 0xc4, 0xb8, 0x4e, 0x9e, 0x9a, 0x36, 0x4a, 0x86, 0x9d, 0xf5, 0x99, 0xcb, 0x00, 0xb8, 0xb9, 0xa7, 0x86, 0x18, 0xfc, 0x9a, 0xe7, 0x00, 0x6a, 0x67, 0xfa, 0x42, 0x9d, 0xff, 0x4d, 0x7a, 0xe4, 0xe8, 0x03, 0x88, 0xff, 0x60, 0xe1, 0x8d, 0x09, 0x5f, 0x6f, 0xde, 0x6b }; NPT_Array<unsigned char> random(random_bytes, NPT_ARRAY_SIZE(random_bytes)); t = "x+5JniyLHBaefzDQxhIwgIHNICAmr0/W/IYuhfMQOCsOu4Bovv8c3HK1DY+ObAlj\r\n" "uiEjsiQX0xdpRHcRNmpu8kSHodPzH2w4IkpEcGbvjDpRyO6FACWTEC4LGwOURwUi\r\n" "0MTsLsy8u2f97A6xP7yC4Kec8669t6sC8dkXTJ3r4gAeGW6z/X3qSYVDL1aBibpx\r\n" "NxC1dKuQTcTRDY1vAfUsyRp5oUFxK/vz1eQq9a2AegP/X0WM7GpLBeNlGXAFrcS4\r\n" "Tp6aNkqGnfWZywC4uaeGGPya5wBqZ/pCnf9NeuToA4j/YOGNCV9v3ms="; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == 233); NPT_Array<unsigned char> verif(data.GetData(), data.GetDataSize()); NPT_ASSERT(verif == random); result = NPT_Base64::Encode(&random[0], random.GetItemCount(), base64, NPT_BASE64_PEM_BLOCKS_PER_LINE); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == t); NPT_String t_url = t; t.Replace('/', '_'); t.Replace('+', '-'); result = NPT_Base64::Encode(&random[0], random.GetItemCount(), base64, NPT_BASE64_PEM_BLOCKS_PER_LINE, true); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == t); t = "76768484767685839"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); t = "76869=978686"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); t = "7686=8978686"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); t = "7686==978686"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); // test IP address parsing NPT_IpAddress ip; NPT_ASSERT(NPT_FAILED(ip.Parse(""))); NPT_ASSERT(NPT_FAILED(ip.Parse("a.b.c.d"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.3.4.5"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.3.4."))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.3.4f"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.g.3.4"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2..3.4"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.300.4"))); NPT_ASSERT(NPT_SUCCEEDED(ip.Parse("1.2.3.4"))); NPT_ASSERT(ip.AsBytes()[0] == 1); NPT_ASSERT(ip.AsBytes()[1] == 2); NPT_ASSERT(ip.AsBytes()[2] == 3); NPT_ASSERT(ip.AsBytes()[3] == 4); NPT_ASSERT(NPT_SUCCEEDED(ip.Parse("255.255.0.1"))); NPT_ASSERT(ip.AsBytes()[0] == 255); NPT_ASSERT(ip.AsBytes()[1] == 255); NPT_ASSERT(ip.AsBytes()[2] == 0); NPT_ASSERT(ip.AsBytes()[3] == 1); NPT_ASSERT(NPT_SUCCEEDED(ip.Parse("0.0.0.0"))); NPT_ASSERT(ip.AsBytes()[0] == 0); NPT_ASSERT(ip.AsBytes()[1] == 0); NPT_ASSERT(ip.AsBytes()[2] == 0); NPT_ASSERT(ip.AsBytes()[3] == 0); return 0; }
/*---------------------------------------------------------------------- | DcfParser_ParseV2Header +---------------------------------------------------------------------*/ static BLT_Result DcfParser_ParseV2Header(DcfParser* self, ATX_InputStream* stream) { /* rewind the byte stream */ ATX_InputStream_Seek(stream, 0); /* parse the atoms from the stream */ AP4_ByteStream* mp4_stream = new ATX_InputStream_To_AP4_ByteStream_Adapter(stream); AP4_AtomParent atoms; AP4_Result result = AP4_DefaultAtomFactory::Instance.CreateAtomsFromStream(*mp4_stream, atoms); mp4_stream->Release(); AP4_ByteStream* decrypting_stream = NULL; AP4_ContainerAtom* odrm = dynamic_cast<AP4_ContainerAtom*>(atoms.GetChild(AP4_ATOM_TYPE_ODRM)); if (odrm) { AP4_OdheAtom* odhe = dynamic_cast<AP4_OdheAtom*>(odrm->GetChild(AP4_ATOM_TYPE_ODHE)); AP4_OddaAtom* odda = dynamic_cast<AP4_OddaAtom*>(odrm->GetChild(AP4_ATOM_TYPE_ODDA)); if (odhe && odda) { const char* content_id = ""; /* get the content ID */ AP4_OhdrAtom* ohdr = dynamic_cast<AP4_OhdrAtom*>(odhe->GetChild(AP4_ATOM_TYPE_OHDR)); if (ohdr) { content_id = ohdr->GetContentId().GetChars(); } /* get the content key */ NPT_DataBuffer key; result = DcfParser_GetContentKey(self, content_id, key); if (BLT_FAILED(result)) { ATX_LOG_FINE_2("GetKeyForContent(%s) returned %d", content_id, result); return BLT_ERROR_NO_MEDIA_KEY; } /* create the decrypting stream */ result = AP4_OmaDcfAtomDecrypter::CreateDecryptingStream(*odrm, key.GetData(), key.GetDataSize(), self->cipher_factory, decrypting_stream); if (AP4_SUCCEEDED(result)) { /* update the content type */ ATX_CopyStringN(self->input.content_type, odhe->GetContentType().GetChars(), sizeof(self->input.content_type)); /* update the encrypted size */ self->input.encrypted_size = odda->GetEncryptedDataLength(); } } } /* check that we have found what we needed in the atoms */ if (decrypting_stream == NULL) return BLT_ERROR_INVALID_MEDIA_FORMAT; /* update the output size */ AP4_LargeSize plaintext_size = 0; if (AP4_SUCCEEDED(decrypting_stream->GetSize(plaintext_size))) { self->output.size = plaintext_size; } else { self->output.size = self->input.encrypted_size; } /* create a reverse adapter */ result = AP4_ByteStream_To_ATX_InputStream_Adapter_Create(decrypting_stream, &self->output.stream); decrypting_stream->Release(); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | DcfParser_ParseV1Header +---------------------------------------------------------------------*/ static BLT_Result DcfParser_ParseV1Header(DcfParser* self, ATX_InputStream* stream) { /* rewind the byte stream */ ATX_InputStream_Seek(stream, 0); /* user a buffer for parsing */ ATX_UInt8 buffer[3]; /* read the first 3 fields */ ATX_Result result; result = ATX_InputStream_ReadFully(stream, buffer, 3); if (ATX_FAILED(result)) return result; /* check the version */ ATX_UInt8 version = buffer[0]; if (version != 1) { ATX_LOG_FINE_1("unsupported DCF version (%d)", version); return BLT_ERROR_UNSUPPORTED_FORMAT; } /* read the content type */ ATX_UInt8 content_type_length = buffer[1]; self->input.content_type[content_type_length] = 0; // null-terminate result = ATX_InputStream_ReadFully(stream, self->input.content_type, content_type_length); if (ATX_FAILED(result)) return result; /* read the content URI */ ATX_UInt8 content_uri_length = buffer[2]; self->input.content_uri[content_uri_length] = 0; // null-terminate result = ATX_InputStream_ReadFully(stream, self->input.content_uri, content_uri_length); if (ATX_FAILED(result)) return result; /* read the variable-length fields */ unsigned int var_length_1, var_length_2; ATX_UInt32 headers_length = 0; result = DcfParser_ReadUintvar(stream, headers_length, var_length_1); if (ATX_FAILED(result)) return result; ATX_UInt32 data_length = 0; result = DcfParser_ReadUintvar(stream, data_length, var_length_2); if (ATX_FAILED(result)) return result; /* check that the encrypted size makes sense */ if (data_length < 32) return BLT_ERROR_INVALID_MEDIA_FORMAT; self->input.encrypted_size = data_length; /* get the content key */ NPT_DataBuffer key; result = DcfParser_GetContentKey(self, self->input.content_uri, key); if (BLT_FAILED(result)) { ATX_LOG_FINE_2("GetKeyForContent(%s) returned %d", self->input.content_uri, result); return BLT_ERROR_NO_MEDIA_KEY; } /* read the headers */ if (headers_length > BLT_DCF_PARSER_MAX_HEADERS_LENGTH) return BLT_ERROR_INVALID_MEDIA_FORMAT; char* headers = new char[headers_length+1]; headers[headers_length] = '\0'; result = ATX_InputStream_ReadFully(stream, headers, headers_length); if (ATX_FAILED(result)) { delete[] headers; return result; } /* as a first-order estimate, set the output size to the encrypted size minus the IV */ self->output.size = self->input.encrypted_size-16; /* parse the headers */ NPT_MemoryStream* headers_memory_stream = new NPT_MemoryStream(headers, headers_length); NPT_InputStreamReference headers_memory_stream_ref(headers_memory_stream); NPT_BufferedInputStream* headers_buffered_stream = new NPT_BufferedInputStream(headers_memory_stream_ref); NPT_HttpHeaders content_headers; content_headers.Parse(*headers_buffered_stream); delete headers_buffered_stream; delete[] headers; /* find out about the encryption from the headers */ const NPT_String* encryption_method = content_headers.GetHeaderValue("Encryption-Method"); if (encryption_method == NULL) return BLT_ERROR_INVALID_MEDIA_FORMAT; /* check the encryption method */ bool encryption_supported = false; NPT_Map<NPT_String,NPT_String> encryption_params; NPT_Size algorithm_id_length = 0; /* parse the algorithm id */ int separator = encryption_method->Find(';', 0, true); if (separator > 0) { algorithm_id_length = separator; /* parse the params */ result = NPT_ParseMimeParameters(((const char*)(*encryption_method))+separator+1, encryption_params); if (NPT_FAILED(result)) { ATX_LOG_FINE_1("cannot parse Encryption-Method parameters (%s)", (const char*)encryption_method); return BLT_ERROR_INVALID_MEDIA_FORMAT; } /* parse the plaintext-length header, if present */ NPT_String* plaintext_length = NULL; if (NPT_SUCCEEDED(encryption_params.Get("plaintext-length", plaintext_length))) { NPT_UInt64 value = 0; if (NPT_SUCCEEDED(plaintext_length->ToInteger64(value, true))) { self->output.size = value; } } } else { algorithm_id_length = encryption_method->GetLength(); } if (NPT_StringsEqualN((const char*)(*encryption_method), BLT_DCF_PARSER_ALGORITHM_ID_AES128CBC, algorithm_id_length)) { encryption_supported = true; NPT_String* padding = NULL; if (NPT_SUCCEEDED(encryption_params.Get("padding", padding))) { if (*padding == BLT_DCF_PARSER_PADDING_RFC2630) { encryption_supported = false; // hmmm, unknown padding } } } if (!encryption_supported) { ATX_LOG_FINE_1("unsupported encryption format (%s)", encryption_method); return BLT_ERROR_UNSUPPORTED_FORMAT; } /* read the IV */ AP4_UI08 iv[16]; result = ATX_InputStream_ReadFully(stream, iv, sizeof(iv)); if (BLT_FAILED(result)) return result; /* create a byte stream to represent the encrypted data */ ATX_Size header_size = 3+content_type_length+content_uri_length+var_length_1+var_length_2+headers_length; ATX_InputStream* data_stream = NULL; ATX_SubInputStream_Create(stream, header_size+16, // skip the IV self->input.encrypted_size-16, NULL, &data_stream); ATX_InputStream_To_AP4_ByteStream_Adapter* encrypted_stream = new ATX_InputStream_To_AP4_ByteStream_Adapter(data_stream); ATX_RELEASE_OBJECT(data_stream); /* create a decrypting stream for the content */ // FIXME: temporary AP4_ByteStream* decrypting_stream = NULL; result = AP4_DecryptingStream::Create(AP4_BlockCipher::CBC, *encrypted_stream, self->output.size, iv, 16, key.GetData(), key.GetDataSize(), self->cipher_factory, decrypting_stream); encrypted_stream->Release(); if (AP4_FAILED(result)) return result; /* create a reverse adapter */ result = AP4_ByteStream_To_ATX_InputStream_Adapter_Create(decrypting_stream, &self->output.stream); decrypting_stream->Release(); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | ShowResponse +---------------------------------------------------------------------*/ static void ShowResponse(NPT_HttpResponse* response, ShowMode mode) { // show response info NPT_Debug("RESPONSE: protocol=%s, code=%d, reason=%s\n", response->GetProtocol().GetChars(), response->GetStatusCode(), response->GetReasonPhrase().GetChars()); // show headers NPT_HttpHeaders& headers = response->GetHeaders(); NPT_List<NPT_HttpHeader*>::Iterator header = headers.GetHeaders().GetFirstItem(); while (header) { NPT_Debug("%s: %s\n", (const char*)(*header)->GetName(), (const char*)(*header)->GetValue()); ++header; } // show entity NPT_HttpEntity* entity = response->GetEntity(); if (entity != NULL) { NPT_Debug("ENTITY: length=%lld, type=%s, encoding=%s\n", entity->GetContentLength(), entity->GetContentType().GetChars(), entity->GetContentEncoding().GetChars()); switch (mode) { case SHOW_MODE_LOAD: { NPT_DataBuffer body; NPT_Result result =entity->Load(body); if (NPT_FAILED(result)) { NPT_Debug("ERROR: failed to load entity (%d)\n", result); } else { NPT_Debug("BODY: loaded %d bytes\n", (int)body.GetDataSize()); // dump the body NPT_OutputStreamReference output; NPT_File standard_out(NPT_FILE_STANDARD_OUTPUT); standard_out.Open(NPT_FILE_OPEN_MODE_WRITE); standard_out.GetOutputStream(output); NPT_Debug("%s", (char *)body.GetData()); // ÔÝʱ²»Ö§³Ö // output->Write(body.GetData(), body.GetDataSize()); } break; } case SHOW_MODE_STREAM_BLOCKING: { NPT_DataBuffer buffer(4096); NPT_Result result; NPT_InputStreamReference input; entity->GetInputStream(input); do { NPT_Size bytes_read = 0; result = input->Read(buffer.UseData(), 4096, &bytes_read); NPT_Debug("read %d bytes\n", bytes_read); } while (NPT_SUCCEEDED(result)); break; } } } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /*argc*/, char** /*argv*/) { // setup debugging #if defined(WIN32) && defined(_DEBUG) int flags = _crtDbgFlag | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(flags); //AllocConsole(); //freopen("CONOUT$", "w", stdout); #endif for (unsigned int t=0; t<sizeof(TestVectors)/sizeof(TestVectors[0]); t++) { TestVector* v = &TestVectors[t]; NPT_DataBuffer in1(v->compressed, v->compressed_len); NPT_DataBuffer out1; NPT_Result result = NPT_Zip::Inflate(in1, out1); CHECK(result == NPT_SUCCESS); CHECK(out1.GetDataSize() == v->uncompressed_len); CHECK(NPT_MemoryEqual(out1.GetData(), v->uncompressed, v->uncompressed_len)); NPT_DataBuffer in2(v->uncompressed, v->uncompressed_len); NPT_DataBuffer out2; NPT_DataBuffer out2_check; result = NPT_Zip::Deflate(in2, out2, NPT_ZIP_COMPRESSION_LEVEL_MAX, NPT_Zip::GZIP); CHECK(result == NPT_SUCCESS); result = NPT_Zip::Inflate(out2, out2_check); CHECK(result == NPT_SUCCESS); CHECK(out2_check.GetDataSize() == in2.GetDataSize()); CHECK(NPT_MemoryEqual(v->uncompressed, out2_check.GetData(), in2.GetDataSize())); // try with random data NPT_DataBuffer in3(300000); unsigned char* in3_p = in3.UseData(); for (int i=0; i<300000; i++) { *in3_p++ = NPT_System::GetRandomInteger(); } in3.SetDataSize(300000); NPT_DataBuffer out3; result = NPT_Zip::Deflate(in3, out3); CHECK(result == NPT_SUCCESS); NPT_DataBuffer out3_check; result = NPT_Zip::Inflate(out3, out3_check); CHECK(result == NPT_SUCCESS); CHECK(in3 == out3_check); // try with redundant data in3_p = in3.UseData(); for (int i=0; i<200000; i+=4) { *in3_p++ = NPT_System::GetRandomInteger(); *in3_p++ = 0; *in3_p++ = 0; *in3_p++ = 0; } result = NPT_Zip::Deflate(in3, out3); CHECK(result == NPT_SUCCESS); result = NPT_Zip::Inflate(out3, out3_check); CHECK(result == NPT_SUCCESS); CHECK(in3 == out3_check); // streams for (unsigned int x=0; x<1000; x++) { NPT_MemoryStream* ms_gz = new NPT_MemoryStream(v->compressed, v->compressed_len); NPT_InputStreamReference ms_gz_ref(ms_gz); NPT_ZipInflatingInputStream ziis(ms_gz_ref); NPT_DataBuffer buffer; NPT_Position position = 0; bool expect_eos = false; for (;;) { NPT_Size chunk = NPT_System::GetRandomInteger()%40000; buffer.SetDataSize(chunk); NPT_Size bytes_read = 0; result = ziis.Read(buffer.UseData(), chunk, &bytes_read); if (expect_eos) { CHECK(result == NPT_ERROR_EOS); break; } if (result == NPT_ERROR_EOS) { CHECK(position == v->uncompressed_len); } else { CHECK(result == NPT_SUCCESS); } CHECK(bytes_read <= chunk); if (bytes_read != chunk) expect_eos = true; CHECK(NPT_MemoryEqual(v->uncompressed+position, buffer.GetData(), bytes_read)); position += bytes_read; } CHECK(position == v->uncompressed_len); } for (unsigned int x=0; x<1000; x++) { NPT_MemoryStream* ms = new NPT_MemoryStream(v->uncompressed, v->uncompressed_len); NPT_InputStreamReference ms_ref(ms); NPT_ZipDeflatingInputStream zdis(ms_ref, NPT_ZIP_COMPRESSION_LEVEL_MAX, NPT_Zip::GZIP); NPT_DataBuffer buffer; NPT_Position position = 0; bool expect_eos = false; for (;;) { NPT_Size chunk = NPT_System::GetRandomInteger()%40000; buffer.Reserve(buffer.GetDataSize()+chunk); NPT_Size bytes_read = 0; result = zdis.Read(buffer.UseData()+buffer.GetDataSize(), chunk, &bytes_read); if (expect_eos) { CHECK(result == NPT_ERROR_EOS); break; } CHECK(result == NPT_SUCCESS); CHECK(bytes_read <= chunk); if (bytes_read != chunk) expect_eos = true; position += bytes_read; buffer.SetDataSize(buffer.GetDataSize()+bytes_read); } NPT_DataBuffer out; NPT_DataBuffer check(v->uncompressed, v->uncompressed_len); CHECK(NPT_Zip::Inflate(buffer, out) == NPT_SUCCESS); CHECK(out == check); } } return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /*argc*/, char** /*argv*/) { NPT_Result result; NPT_String t = "hello"; NPT_String base64; NPT_DataBuffer data; result = NPT_Base64::Encode((const NPT_Byte*)t.GetChars(), t.GetLength(), base64); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == "aGVsbG8="); result = NPT_Base64::Decode(base64.GetChars(), base64.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == t.GetLength()); NPT_String tt((const char*)data.GetData(), data.GetDataSize()); NPT_ASSERT(tt == t); t = "hello!"; result = NPT_Base64::Encode((const NPT_Byte*)t.GetChars(), t.GetLength(), base64); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == "aGVsbG8h"); result = NPT_Base64::Decode(base64.GetChars(), base64.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == t.GetLength()); tt.Assign((const char*)data.GetData(), data.GetDataSize()); NPT_ASSERT(tt == t); t = "hello!!"; result = NPT_Base64::Encode((const NPT_Byte*)t.GetChars(), t.GetLength(), base64); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == "aGVsbG8hIQ=="); result = NPT_Base64::Decode(base64.GetChars(), base64.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == t.GetLength()); tt.Assign((const char*)data.GetData(), data.GetDataSize()); NPT_ASSERT(tt == t); unsigned char r256_bin[] = { 0x7d, 0x5f, 0xd0, 0xf4, 0x6a, 0xa8, 0xae, 0x34, 0x6e, 0x32, 0x1d, 0xa1, 0xef, 0x66, 0xdd, 0x82, 0x76, 0xa6, 0xfd, 0x8c, 0x75, 0x97, 0xa0, 0x01, 0x00, 0xde, 0x52, 0xef, 0xdf, 0xb6, 0x3e, 0xe4, 0x7b, 0x45, 0xdd, 0x2b, 0xa1, 0x9c, 0xb0, 0x6d, 0x2c, 0x75, 0xb1, 0x87, 0x43, 0x0f, 0xea, 0x24, 0x36, 0x11, 0x7e, 0xee, 0xd1, 0x91, 0x7f, 0x7b, 0x02, 0xea, 0x9a, 0x2a, 0x25, 0xc0, 0xac, 0x99, 0xa4, 0x89, 0x55, 0x5b, 0x82, 0xdf, 0xb0, 0x7e, 0xa1, 0x78, 0x0f, 0xdf, 0x25, 0x5f, 0x3d, 0xba, 0xcb, 0xbc, 0x35, 0x04, 0xc3, 0xf4, 0xb8, 0xc0, 0x17, 0x8e, 0x75, 0x01, 0xe6, 0x2f, 0x88, 0x2c, 0x76, 0x0a, 0x8c, 0x3f, 0x83, 0xd4, 0x10, 0xa8, 0x00, 0xfc, 0xa0, 0x92, 0x7b, 0xae, 0xa3, 0x8c, 0x47, 0xea, 0x25, 0xf9, 0x29, 0x81, 0x1c, 0x21, 0xf2, 0xf4, 0xfe, 0x07, 0x7e, 0x4b, 0x01, 0x79, 0x41, 0x3a, 0xb6, 0x71, 0x0b, 0x75, 0xa7, 0x9d, 0x1b, 0x12, 0xc4, 0x46, 0x06, 0xf3, 0x5f, 0x00, 0x05, 0x2a, 0x1b, 0x34, 0xd6, 0x87, 0xc4, 0x70, 0xcc, 0xc3, 0x9e, 0xa8, 0x24, 0x2c, 0x97, 0x4e, 0xfc, 0x91, 0x70, 0x1c, 0x29, 0x66, 0xc3, 0x23, 0xbf, 0xd7, 0x4d, 0x35, 0x51, 0xff, 0xeb, 0xde, 0x45, 0xbd, 0x8d, 0x80, 0x44, 0x2a, 0x8d, 0xc0, 0xe8, 0x6a, 0xe2, 0x86, 0x46, 0x9f, 0xf2, 0x3c, 0x93, 0x0d, 0x27, 0x02, 0xe4, 0x79, 0xa1, 0x21, 0xf4, 0x43, 0xcd, 0x4c, 0x22, 0x25, 0x9e, 0x93, 0xeb, 0x77, 0x8e, 0x1e, 0x57, 0x1e, 0x9b, 0xcb, 0x91, 0x86, 0xcf, 0x15, 0xaf, 0xd5, 0x03, 0x0f, 0x70, 0xbe, 0x6e, 0x37, 0xea, 0x37, 0xdd, 0xf6, 0xa1, 0xb1, 0xf7, 0x05, 0xbc, 0x2d, 0x44, 0x60, 0x35, 0xa4, 0x05, 0x0b, 0x22, 0x7d, 0x7a, 0x71, 0xe5, 0x1d, 0x8e, 0xcb, 0xc3, 0xb8, 0x3a, 0xe1 }; NPT_String b64; NPT_Base64::Encode(r256_bin, sizeof(r256_bin), b64); NPT_DataBuffer r256_out; NPT_Base64::Decode(b64.GetChars(), b64.GetLength(), r256_out); NPT_ASSERT(r256_out.GetDataSize() == sizeof(r256_bin)); NPT_ASSERT(r256_bin[sizeof(r256_bin)-1] == r256_out.GetData()[sizeof(r256_bin)-1]); unsigned char random_bytes[] = { 0xc7, 0xee, 0x49, 0x9e, 0x2c, 0x8b, 0x1c, 0x16, 0x9e, 0x7f, 0x30, 0xd0, 0xc6, 0x12, 0x30, 0x80, 0x81, 0xcd, 0x20, 0x20, 0x26, 0xaf, 0x4f, 0xd6, 0xfc, 0x86, 0x2e, 0x85, 0xf3, 0x10, 0x38, 0x2b, 0x0e, 0xbb, 0x80, 0x68, 0xbe, 0xff, 0x1c, 0xdc, 0x72, 0xb5, 0x0d, 0x8f, 0x8e, 0x6c, 0x09, 0x63, 0xba, 0x21, 0x23, 0xb2, 0x24, 0x17, 0xd3, 0x17, 0x69, 0x44, 0x77, 0x11, 0x36, 0x6a, 0x6e, 0xf2, 0x44, 0x87, 0xa1, 0xd3, 0xf3, 0x1f, 0x6c, 0x38, 0x22, 0x4a, 0x44, 0x70, 0x66, 0xef, 0x8c, 0x3a, 0x51, 0xc8, 0xee, 0x85, 0x00, 0x25, 0x93, 0x10, 0x2e, 0x0b, 0x1b, 0x03, 0x94, 0x47, 0x05, 0x22, 0xd0, 0xc4, 0xec, 0x2e, 0xcc, 0xbc, 0xbb, 0x67, 0xfd, 0xec, 0x0e, 0xb1, 0x3f, 0xbc, 0x82, 0xe0, 0xa7, 0x9c, 0xf3, 0xae, 0xbd, 0xb7, 0xab, 0x02, 0xf1, 0xd9, 0x17, 0x4c, 0x9d, 0xeb, 0xe2, 0x00, 0x1e, 0x19, 0x6e, 0xb3, 0xfd, 0x7d, 0xea, 0x49, 0x85, 0x43, 0x2f, 0x56, 0x81, 0x89, 0xba, 0x71, 0x37, 0x10, 0xb5, 0x74, 0xab, 0x90, 0x4d, 0xc4, 0xd1, 0x0d, 0x8d, 0x6f, 0x01, 0xf5, 0x2c, 0xc9, 0x1a, 0x79, 0xa1, 0x41, 0x71, 0x2b, 0xfb, 0xf3, 0xd5, 0xe4, 0x2a, 0xf5, 0xad, 0x80, 0x7a, 0x03, 0xff, 0x5f, 0x45, 0x8c, 0xec, 0x6a, 0x4b, 0x05, 0xe3, 0x65, 0x19, 0x70, 0x05, 0xad, 0xc4, 0xb8, 0x4e, 0x9e, 0x9a, 0x36, 0x4a, 0x86, 0x9d, 0xf5, 0x99, 0xcb, 0x00, 0xb8, 0xb9, 0xa7, 0x86, 0x18, 0xfc, 0x9a, 0xe7, 0x00, 0x6a, 0x67, 0xfa, 0x42, 0x9d, 0xff, 0x4d, 0x7a, 0xe4, 0xe8, 0x03, 0x88, 0xff, 0x60, 0xe1, 0x8d, 0x09, 0x5f, 0x6f, 0xde, 0x6b }; NPT_Array<unsigned char> random(random_bytes, NPT_ARRAY_SIZE(random_bytes)); t = "x+5JniyLHBaefzDQxhIwgIHNICAmr0/W/IYuhfMQOCsOu4Bovv8c3HK1DY+ObAlj\r\n" "uiEjsiQX0xdpRHcRNmpu8kSHodPzH2w4IkpEcGbvjDpRyO6FACWTEC4LGwOURwUi\r\n" "0MTsLsy8u2f97A6xP7yC4Kec8669t6sC8dkXTJ3r4gAeGW6z/X3qSYVDL1aBibpx\r\n" "NxC1dKuQTcTRDY1vAfUsyRp5oUFxK/vz1eQq9a2AegP/X0WM7GpLBeNlGXAFrcS4\r\n" "Tp6aNkqGnfWZywC4uaeGGPya5wBqZ/pCnf9NeuToA4j/YOGNCV9v3ms="; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(data.GetDataSize() == 233); NPT_Array<unsigned char> verif(data.GetData(), data.GetDataSize()); NPT_ASSERT(verif == random); result = NPT_Base64::Encode(&random[0], random.GetItemCount(), base64, NPT_BASE64_PEM_BLOCKS_PER_LINE); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == t); NPT_String t_url = t; t.Replace('/', '_'); t.Replace('+', '-'); result = NPT_Base64::Encode(&random[0], random.GetItemCount(), base64, NPT_BASE64_PEM_BLOCKS_PER_LINE, true); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(base64 == t); t = "76768484767685839"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); t = "76869=978686"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); t = "7686=8978686"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); t = "7686==978686"; result = NPT_Base64::Decode(t.GetChars(), t.GetLength(), data); NPT_ASSERT(result == NPT_ERROR_INVALID_FORMAT); // test IP address parsing NPT_IpAddress ip; NPT_ASSERT(NPT_FAILED(ip.Parse(""))); NPT_ASSERT(NPT_FAILED(ip.Parse("a.b.c.d"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.3.4.5"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.3.4."))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.3.4f"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.g.3.4"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2..3.4"))); NPT_ASSERT(NPT_FAILED(ip.Parse("1.2.300.4"))); NPT_ASSERT(NPT_SUCCEEDED(ip.Parse("1.2.3.4"))); NPT_ASSERT(ip.AsBytes()[0] == 1); NPT_ASSERT(ip.AsBytes()[1] == 2); NPT_ASSERT(ip.AsBytes()[2] == 3); NPT_ASSERT(ip.AsBytes()[3] == 4); NPT_ASSERT(NPT_SUCCEEDED(ip.Parse("255.255.0.1"))); NPT_ASSERT(ip.AsBytes()[0] == 255); NPT_ASSERT(ip.AsBytes()[1] == 255); NPT_ASSERT(ip.AsBytes()[2] == 0); NPT_ASSERT(ip.AsBytes()[3] == 1); NPT_ASSERT(NPT_SUCCEEDED(ip.Parse("0.0.0.0"))); NPT_ASSERT(ip.AsBytes()[0] == 0); NPT_ASSERT(ip.AsBytes()[1] == 0); NPT_ASSERT(ip.AsBytes()[2] == 0); NPT_ASSERT(ip.AsBytes()[3] == 0); // MIME parameter parser NPT_Map<NPT_String,NPT_String> params; result = NPT_ParseMimeParameters(NULL, params); NPT_ASSERT(result == NPT_ERROR_INVALID_PARAMETERS); result = NPT_ParseMimeParameters("", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 0); result = NPT_ParseMimeParameters("foo=bar", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar"); params.Clear(); result = NPT_ParseMimeParameters(" foo =bar", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar"); params.Clear(); result = NPT_ParseMimeParameters(" foo= bar", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar"); params.Clear(); result = NPT_ParseMimeParameters(" foo= bar;", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar"); params.Clear(); result = NPT_ParseMimeParameters("foo=\"bar\"", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar"); params.Clear(); result = NPT_ParseMimeParameters("foo=\"ba\"r\"", params); NPT_ASSERT(result == NPT_ERROR_INVALID_SYNTAX); params.Clear(); result = NPT_ParseMimeParameters("foo=\"ba\\\"r\"", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "ba\"r"); params.Clear(); result = NPT_ParseMimeParameters("foo=\"bar\\\"\"", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar\""); params.Clear(); result = NPT_ParseMimeParameters("foo=\"bar\\\\\"", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 1); NPT_ASSERT(params["foo"] == "bar\\"); params.Clear(); result = NPT_ParseMimeParameters("a=1;b=2; c=3; d=4 ; e=\"\\;\"; f=\";\"", params); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(params.GetEntryCount() == 6); NPT_ASSERT(params["a"] == "1"); NPT_ASSERT(params["b"] == "2"); NPT_ASSERT(params["c"] == "3"); NPT_ASSERT(params["d"] == "4"); NPT_ASSERT(params["e"] == ";"); NPT_ASSERT(params["f"] == ";"); params.Clear(); // number parsing float f; int i; NPT_Int32 i32; NPT_UInt32 ui32; NPT_Int64 i64; NPT_UInt64 ui64; SHOULD_FAIL(NPT_ParseInteger("ssdfsdf", i, false)); SHOULD_FAIL(NPT_ParseInteger("", i, false)); SHOULD_FAIL(NPT_ParseInteger(NULL, i, false)); SHOULD_FAIL(NPT_ParseInteger("123a", i, false)); SHOULD_FAIL(NPT_ParseInteger("a123", i, false)); SHOULD_FAIL(NPT_ParseInteger(" 123", i, false)); SHOULD_FAIL(NPT_ParseInteger("a 123", i, true)); SHOULD_FAIL(NPT_ParseInteger(" a123", i, true)); SHOULD_SUCCEED(NPT_ParseInteger("+1", i, false)); SHOULD_EQUAL_I(i, 1); SHOULD_SUCCEED(NPT_ParseInteger("+123", i, false)); SHOULD_EQUAL_I(i, 123); SHOULD_SUCCEED(NPT_ParseInteger("-1", i, false)); SHOULD_EQUAL_I(i, -1); SHOULD_SUCCEED(NPT_ParseInteger("-123", i, false)); SHOULD_EQUAL_I(i, -123); SHOULD_SUCCEED(NPT_ParseInteger("-123fgs", i, true)); SHOULD_EQUAL_I(i, -123); SHOULD_SUCCEED(NPT_ParseInteger(" -123fgs", i, true)); SHOULD_EQUAL_I(i, -123); SHOULD_SUCCEED(NPT_ParseInteger("0", i, true)); SHOULD_EQUAL_I(i, 0); SHOULD_SUCCEED(NPT_ParseInteger("7768", i, true)); SHOULD_EQUAL_I(i, 7768); SHOULD_SUCCEED(NPT_ParseInteger32("2147483647", i32, false)); SHOULD_EQUAL_I(i32, 2147483647); SHOULD_SUCCEED(NPT_ParseInteger32("-2147483647", i32, false)); SHOULD_EQUAL_I(i32, -2147483647); SHOULD_SUCCEED(NPT_ParseInteger32("-2147483648", i32, false)); SHOULD_EQUAL_I(i32, (-2147483647 - 1)); SHOULD_FAIL(NPT_ParseInteger32("2147483648", i32, false)); SHOULD_FAIL(NPT_ParseInteger32("-2147483649", i32, false)); SHOULD_FAIL(NPT_ParseInteger32("-21474836480", i32, false)); SHOULD_FAIL(NPT_ParseInteger32("21474836470", i32, false)); SHOULD_SUCCEED(NPT_ParseInteger32U("4294967295", ui32, false)); SHOULD_EQUAL_I(ui32, 4294967295U); SHOULD_FAIL(NPT_ParseInteger32U("4294967296", ui32, false)); SHOULD_FAIL(NPT_ParseInteger32U("-1", ui32, false)); SHOULD_SUCCEED(NPT_ParseInteger64("9223372036854775807", i64, false)); SHOULD_EQUAL_I(i64, NPT_INT64_C(9223372036854775807)); SHOULD_SUCCEED(NPT_ParseInteger64("-9223372036854775807", i64, false)); SHOULD_EQUAL_I(i64, NPT_INT64_C(-9223372036854775807)); SHOULD_SUCCEED(NPT_ParseInteger64("-9223372036854775808", i64, false)); SHOULD_EQUAL_I(i64, (NPT_INT64_C(-9223372036854775807) - NPT_INT64_C(1))); SHOULD_FAIL(NPT_ParseInteger64("9223372036854775808", i64, false)); SHOULD_FAIL(NPT_ParseInteger64("-9223372036854775809", i64, false)); SHOULD_FAIL(NPT_ParseInteger64("-9223372036854775897", i64, false)); SHOULD_FAIL(NPT_ParseInteger64("9223372036854775897", i64, false)); SHOULD_SUCCEED(NPT_ParseInteger64U("18446744073709551615", ui64, false)); SHOULD_EQUAL_I(ui64, NPT_UINT64_C(18446744073709551615)); SHOULD_FAIL(NPT_ParseInteger64U("18446744073709551616", ui64, false)); SHOULD_FAIL(NPT_ParseInteger64U("-1", ui64, false)); SHOULD_FAIL(NPT_ParseFloat("ssdfsdf", f, false)); SHOULD_FAIL(NPT_ParseFloat("", f, false)); SHOULD_FAIL(NPT_ParseFloat(NULL, f, false)); SHOULD_FAIL(NPT_ParseFloat("123.", f, false)); SHOULD_FAIL(NPT_ParseFloat("a123", f, false)); SHOULD_FAIL(NPT_ParseFloat(" 123", f, false)); SHOULD_FAIL(NPT_ParseFloat(" 127.89E5ff", f, false)); SHOULD_SUCCEED(NPT_ParseFloat("+1.0", f, false)); SHOULD_EQUAL_F(f, 1.0f); SHOULD_SUCCEED(NPT_ParseFloat("+123", f, false)); SHOULD_EQUAL_F(f, 123.0f); SHOULD_SUCCEED(NPT_ParseFloat("-0.1", f, false)); SHOULD_EQUAL_F(f, -0.1f); SHOULD_SUCCEED(NPT_ParseFloat("0.23e-13", f, false)); SHOULD_EQUAL_F(f, 0.23e-13f); SHOULD_SUCCEED(NPT_ParseFloat(" 127.89E5ff", f, true)); SHOULD_EQUAL_F(f, 127.89E5f); SHOULD_SUCCEED(NPT_ParseFloat("+0.3db", f, true)); SHOULD_EQUAL_F(f, 0.3f); SHOULD_SUCCEED(NPT_ParseFloat("+.3db", f, true)); SHOULD_EQUAL_F(f, 0.3f); SHOULD_SUCCEED(NPT_ParseFloat("-.3db", f, true)); SHOULD_EQUAL_F(f, -0.3f); SHOULD_SUCCEED(NPT_ParseFloat(".3db", f, true)); SHOULD_EQUAL_F(f, .3f); return 0; }
void FrontEnd::HttpOutputImpl::writeData(const NPT_DataBuffer& data) { m_outputStream->WriteFully(data.GetData(), data.GetDataSize()); }
void FrontEnd::processSsdpSearch(SsdpServerTask *task, Interface *intf, const NPT_DataBuffer& data, const NPT_SocketAddress& fromAddr) { do { NPT_HttpRequest *req; NPT_InputStreamReference inputStream0(new NPT_MemoryStream(data.GetData(), data.GetDataSize())); NPT_BufferedInputStream inputStream(inputStream0); if (NPT_FAILED(NPT_HttpRequest::Parse(inputStream, NULL, req))) { break; } PtrHolder<NPT_HttpRequest> req1(req); if (req->GetMethod().Compare("M-SEARCH") != 0 || req->GetProtocol().Compare(NPT_HTTP_PROTOCOL_1_1) != 0 || req->GetUrl().GetPath().Compare("*") != 0) { break; } NPT_HttpHeader *hdrMan = req->GetHeaders().GetHeader("MAN"); if (!hdrMan || hdrMan->GetValue().Compare("\"ssdp:discover\"") != 0) { break; } NPT_HttpHeader *hdrHost = req->GetHeaders().GetHeader("HOST"); if (!hdrHost || (hdrHost->GetValue().Compare("239.255.255.250:1900") != 0 && hdrHost->GetValue().Compare("239.255.255.250") != 0)) { break; } int mx; NPT_HttpHeader *hdrMX = req->GetHeaders().GetHeader("MX"); if (!hdrMX || NPT_FAILED(NPT_ParseInteger(hdrMX->GetValue(), mx)) || mx < 1) { break; } if (mx > 120) { mx = 120; } NPT_HttpHeader *hdrST = req->GetHeaders().GetHeader("ST"); if (!hdrST) { break; } NPT_List<MatchContext*> matchList; NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE); sock.Bind(NPT_SocketAddress(intf->m_context.m_ifAddr, 0)); NPT_SharedVariable waitVar; waitVar.SetValue(0); { ReadLocker locker(m_dsLock); for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) { NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i); DeviceImplInfo *info = *it; MatchContext *matchContext = new MatchContext(); if (info->m_deviceImpl->match(hdrST->GetValue(), matchContext->matches)) { matchList.Add(matchContext); matchContext->deviceUuid = info->m_deviceImpl->uuid(); matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds; matchContext->descPath = info->m_deviceImpl->m_descPath; matchContext->httpRoot = info->m_context.m_httpRoot; } else { delete matchContext; } } } SsdpSearchAbortCallback abortCallback(&sock, &waitVar); if (task->registerAbortCallback(&abortCallback)) { for (NPT_Ordinal i = 0; i < matchList.GetItemCount(); i++) { MatchContext *matchContext = *matchList.GetItem(i); NPT_String location = NPT_String::Format("http://%s:%d%s%s", intf->m_context.m_ifAddr.ToString().GetChars(), intf->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars()); bool broken = false; for (NPT_Ordinal j = 0; j < matchContext->matches.GetItemCount(); j++) { NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(j); NPT_Timeout timeout = NPT_System::GetRandomInteger() % (mx * 1000); // TODO: wait or not ??? timeout = 0; if (NPT_SUCCEEDED(waitVar.WaitWhileEquals(0, timeout))) { break; } { ReadLocker locker(m_dsLock); if (m_deviceImplIndex.HasKey(matchContext->deviceUuid)) { NPT_TimeStamp ts; NPT_System::GetCurrentTimeStamp(ts); NPT_String dateStr = NPT_DateTime(ts).ToString(NPT_DateTime::FORMAT_RFC_1123); NPT_String resp = NPT_String::Format("HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=%d\r\nDATE: %s\r\nEXT: \r\nLOCATION: %s\r\nSERVER: %s\r\nST: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n", matchContext->expireSeconds, dateStr.GetChars(), location.GetChars(), m_serverHeader.GetChars(), it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars()); NPT_DataBuffer packet(resp.GetChars(), resp.GetLength(), false); sock.Send(packet, &fromAddr); } } } if (broken) { break; } } task->unregisterAbortCallback(&abortCallback); } matchList.Apply(NPT_ObjectDeleter<MatchContext>()); } while (false); }
void Server::listen() { _aliveThread = new std::thread([] () { int delay = 10000; while (true) { sleep(delay); printf("SENDING ALIVE\n"); sendAlive(); delay = (delay == 10000 ? 20000 : 180000); } }); _listenerThread = new std::thread([] () { bool bindErrorReported = false; while (true) { NPT_UdpMulticastSocket socket; NPT_IpAddress upnpAddress = getUPNPAddress(); // TODO: Setup local port and network interface socket.SetTimeToLive(4); socket.JoinGroup(upnpAddress); while (true) { char* buf = new char[1024]; NPT_DataBuffer receivePacket; NPT_SocketAddress address; receivePacket.SetBuffer((NPT_Byte*)buf, 1024); socket.Receive(receivePacket, &address); std::string s((char*)receivePacket.GetData(), receivePacket.GetDataSize()); if (s.compare(0, 8, "M-SEARCH") == 0) { NPT_String remoteAddr = address.GetIpAddress().ToString(); int remotePort = address.GetPort(); // if (gMS->isAddressAllowed(address)) { if (s.find_first_of("urn:schemas-upnp-org:service:ContentDirectory:1") > 0) { sendDiscover(remoteAddr.GetChars(), remotePort, "urn:schemas-upnp-org:service:ContentDirectory:1"); } if (s.find_first_of("upnp:rootdevice") > 0) { sendDiscover(remoteAddr.GetChars(), remotePort, "upnp:rootdevice"); } if (s.find_first_of("urn:schemas-upnp-org:device:MediaServer:1") > 0) { sendDiscover(remoteAddr.GetChars(), remotePort, "urn:schemas-upnp-org:device:MediaServer:1"); } if (s.find_first_of("ssdp:all") > 0) { sendDiscover(remoteAddr.GetChars(), remotePort, "urn:schemas-upnp-org:device:MediaServer:1"); } if (s.find_first_of(gMS->udnString()) > 0) { sendDiscover(remoteAddr.GetChars(), remotePort, gMS->udnString()); } } } else if (s.compare(0, 6, "NOTIFY") == 0) { /* String remoteAddr = address.getHostAddress(); int remotePort = receivePacket.getPort(); logger.trace("Receiving a NOTIFY from [" + remoteAddr + ":" + remotePort + "]"); */ } } } }); }