diff --git a/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj b/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj index b4c05539..893f7c4c 100644 --- a/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj +++ b/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj @@ -108,6 +108,7 @@ + diff --git a/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj.filters b/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj.filters index 7a14bdad..71da9e5c 100644 --- a/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj.filters +++ b/Build/libHttpClient.140.UWP.C/libHttpClient.140.UWP.C.vcxproj.filters @@ -81,6 +81,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -198,46 +201,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {84EAA571-662D-338E-93ED-5F199E278D3A} + {B245C598-513E-31E2-86F2-B936F07371C7} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {19F27A1D-1A07-34C1-BD02-058666E43986} + {4EF99C88-F2E5-32A2-8923-C7AC29483D0D} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj b/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj index 41f2762d..8bdb23a9 100644 --- a/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj +++ b/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj @@ -99,6 +99,7 @@ + diff --git a/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj.filters b/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj.filters index 0b01976f..7c121e53 100644 --- a/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj.filters +++ b/Build/libHttpClient.140.Win32.C/libHttpClient.140.Win32.C.vcxproj.filters @@ -75,6 +75,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -186,46 +189,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {4BEDE216-DAE5-33E7-93E9-294BBFE29520} + {7A5EA885-D945-3941-BA96-ED8304FE3455} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {D32651A6-7E85-35EF-B860-E8E3CF1E6177} + {8EE7BD63-CD1F-30B2-BB86-794DE9F2EA90} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj b/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj index 51191089..57425aa8 100644 --- a/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj +++ b/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj @@ -78,6 +78,7 @@ + diff --git a/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj.filters b/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj.filters index 48923f46..f8710b65 100644 --- a/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj.filters +++ b/Build/libHttpClient.140.XDK.C/libHttpClient.140.XDK.C.vcxproj.filters @@ -81,6 +81,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -198,46 +201,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {84EAA571-662D-338E-93ED-5F199E278D3A} + {B245C598-513E-31E2-86F2-B936F07371C7} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {19F27A1D-1A07-34C1-BD02-058666E43986} + {4EF99C88-F2E5-32A2-8923-C7AC29483D0D} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj b/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj index cf41a6da..060f2dfe 100644 --- a/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj +++ b/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj @@ -99,6 +99,7 @@ + @@ -119,8 +120,12 @@ - - + + + + + + diff --git a/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj.filters b/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj.filters index b6007e81..73e37c7e 100644 --- a/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj.filters +++ b/Build/libHttpClient.141.GDK.C/libHttpClient.141.GDK.C.vcxproj.filters @@ -22,8 +22,14 @@ C++ Source\Global - - C++ Source\HTTP\WinHttp + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl C++ Source\HTTP @@ -60,6 +66,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -90,8 +99,14 @@ C++ Source\Global - - C++ Source\HTTP\WinHttp + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl C++ Source\HTTP @@ -138,40 +153,40 @@ - {4B24093D-5F61-3E7B-B53A-155D833CE990} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {5DB96368-8B66-3AD7-8E55-F250991593AE} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {7FA52DF8-9864-3D90-8217-C02E81138559} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {5DE2D652-C0DA-3F33-B684-A0C93FEA6009} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {B06E9020-4922-3461-9A26-D85D45D52710} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - - {6CB3A0CF-6B86-31AF-AFFD-88577A6FD759} + + {8A8BB441-2DBF-39CE-BF15-42D8FA1F2451} - {4BC6EB69-E166-3264-A585-E5996C2AF5B9} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {3D96EFFD-6054-3227-B362-297897876C05} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {FA75CFAD-BC14-3A9D-A907-23E1F994DB66} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {D048DED3-BA76-342E-AC88-0640A35BF2F3} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {32F0BE1E-07C2-3438-A72C-E0F17C94E14B} + {8EE7BD63-CD1F-30B2-BB86-794DE9F2EA90} - {8D3620F6-F6C6-3211-B325-CE19BE6BA40A} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj b/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj index f5f025be..da2852d9 100644 --- a/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj +++ b/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj @@ -123,6 +123,7 @@ + diff --git a/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj.filters b/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj.filters index 7a14bdad..71da9e5c 100644 --- a/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj.filters +++ b/Build/libHttpClient.141.UWP.C/libHttpClient.141.UWP.C.vcxproj.filters @@ -81,6 +81,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -198,46 +201,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {84EAA571-662D-338E-93ED-5F199E278D3A} + {B245C598-513E-31E2-86F2-B936F07371C7} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {19F27A1D-1A07-34C1-BD02-058666E43986} + {4EF99C88-F2E5-32A2-8923-C7AC29483D0D} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj b/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj index 0a42fd0f..eb62e3b3 100644 --- a/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj +++ b/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj @@ -112,6 +112,7 @@ + diff --git a/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj.filters b/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj.filters index 0b01976f..7c121e53 100644 --- a/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj.filters +++ b/Build/libHttpClient.141.Win32.C/libHttpClient.141.Win32.C.vcxproj.filters @@ -75,6 +75,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -186,46 +189,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {4BEDE216-DAE5-33E7-93E9-294BBFE29520} + {7A5EA885-D945-3941-BA96-ED8304FE3455} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {D32651A6-7E85-35EF-B860-E8E3CF1E6177} + {8EE7BD63-CD1F-30B2-BB86-794DE9F2EA90} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj b/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj index a0ea3dc8..92c0a020 100644 --- a/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj +++ b/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj @@ -79,6 +79,7 @@ + diff --git a/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj.filters b/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj.filters index 48923f46..f8710b65 100644 --- a/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj.filters +++ b/Build/libHttpClient.141.XDK.C/libHttpClient.141.XDK.C.vcxproj.filters @@ -81,6 +81,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -198,46 +201,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {84EAA571-662D-338E-93ED-5F199E278D3A} + {B245C598-513E-31E2-86F2-B936F07371C7} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {19F27A1D-1A07-34C1-BD02-058666E43986} + {4EF99C88-F2E5-32A2-8923-C7AC29483D0D} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj b/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj index 8b4624ba..e767af62 100644 --- a/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj +++ b/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj @@ -99,6 +99,7 @@ + @@ -119,8 +120,12 @@ - - + + + + + + diff --git a/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj.filters b/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj.filters index b6007e81..73e37c7e 100644 --- a/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj.filters +++ b/Build/libHttpClient.142.GDK.C/libHttpClient.142.GDK.C.vcxproj.filters @@ -22,8 +22,14 @@ C++ Source\Global - - C++ Source\HTTP\WinHttp + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl C++ Source\HTTP @@ -60,6 +66,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -90,8 +99,14 @@ C++ Source\Global - - C++ Source\HTTP\WinHttp + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl + + + C++ Source\HTTP\Curl C++ Source\HTTP @@ -138,40 +153,40 @@ - {4B24093D-5F61-3E7B-B53A-155D833CE990} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {5DB96368-8B66-3AD7-8E55-F250991593AE} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {7FA52DF8-9864-3D90-8217-C02E81138559} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {5DE2D652-C0DA-3F33-B684-A0C93FEA6009} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {B06E9020-4922-3461-9A26-D85D45D52710} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - - {6CB3A0CF-6B86-31AF-AFFD-88577A6FD759} + + {8A8BB441-2DBF-39CE-BF15-42D8FA1F2451} - {4BC6EB69-E166-3264-A585-E5996C2AF5B9} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {3D96EFFD-6054-3227-B362-297897876C05} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {FA75CFAD-BC14-3A9D-A907-23E1F994DB66} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {D048DED3-BA76-342E-AC88-0640A35BF2F3} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {32F0BE1E-07C2-3438-A72C-E0F17C94E14B} + {8EE7BD63-CD1F-30B2-BB86-794DE9F2EA90} - {8D3620F6-F6C6-3211-B325-CE19BE6BA40A} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj b/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj index e75f492a..2a6891a2 100644 --- a/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj +++ b/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj @@ -123,6 +123,7 @@ + diff --git a/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj.filters b/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj.filters index 7a14bdad..71da9e5c 100644 --- a/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj.filters +++ b/Build/libHttpClient.142.UWP.C/libHttpClient.142.UWP.C.vcxproj.filters @@ -81,6 +81,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -198,46 +201,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {84EAA571-662D-338E-93ED-5F199E278D3A} + {B245C598-513E-31E2-86F2-B936F07371C7} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {19F27A1D-1A07-34C1-BD02-058666E43986} + {4EF99C88-F2E5-32A2-8923-C7AC29483D0D} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj b/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj index 20aa523c..6e7325b7 100644 --- a/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj +++ b/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj @@ -112,6 +112,7 @@ + diff --git a/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj.filters b/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj.filters index 0b01976f..7c121e53 100644 --- a/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj.filters +++ b/Build/libHttpClient.142.Win32.C/libHttpClient.142.Win32.C.vcxproj.filters @@ -75,6 +75,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -186,46 +189,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {4BEDE216-DAE5-33E7-93E9-294BBFE29520} + {7A5EA885-D945-3941-BA96-ED8304FE3455} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {D32651A6-7E85-35EF-B860-E8E3CF1E6177} + {8EE7BD63-CD1F-30B2-BB86-794DE9F2EA90} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj b/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj index 907e9c4b..a5588d90 100644 --- a/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj +++ b/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj @@ -79,6 +79,7 @@ + diff --git a/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj.filters b/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj.filters index 48923f46..f8710b65 100644 --- a/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj.filters +++ b/Build/libHttpClient.142.XDK.C/libHttpClient.142.XDK.C.vcxproj.filters @@ -81,6 +81,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -198,46 +201,46 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {84EAA571-662D-338E-93ED-5F199E278D3A} + {B245C598-513E-31E2-86F2-B936F07371C7} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {19F27A1D-1A07-34C1-BD02-058666E43986} + {4EF99C88-F2E5-32A2-8923-C7AC29483D0D} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj b/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj index 9b2ab34c..5d06d665 100644 --- a/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj +++ b/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj @@ -56,12 +56,16 @@ /bigobj /Zm512 /GS %(AdditionalOptions) - $(WindowsSDKDir_10)Testing\Development\inc;$(MSBuildThisFileDirectory)..\..\Source\Task;%(AdditionalIncludeDirectories) + + c:\Program Files (x86)\Windows Kits\10\Testing\Development\inc; + $(MSBuildThisFileDirectory)..\..\Source\Task; + %(AdditionalIncludeDirectories) + - $(WindowsSDKDir_10)Testing\Development\lib\x64;%(AdditionalLibraryDirectories) - $(WindowsSDKDir_10)Testing\Development\lib\x86;%(AdditionalLibraryDirectories) - $(WindowsSDKDir_10)Testing\Development\lib\arm64;%(AdditionalLibraryDirectories) + C:\Program Files (x86)\Windows Kits\10\Testing\Development\lib\x64;%(AdditionalLibraryDirectories) + C:\Program Files (x86)\Windows Kits\10\Testing\Development\lib\x86;%(AdditionalLibraryDirectories) + C:\Program Files (x86)\Windows Kits\10\Testing\Development\lib\arm64;%(AdditionalLibraryDirectories) @@ -110,6 +114,7 @@ + @@ -189,9 +194,9 @@ Microsoft.Xbox.System.UnitTest - $(WindowsSDKDir_10)Testing\Runtimes\TAEF\x64\TE.exe + C:\Program Files (x86)\Windows Kits\10\Testing\Runtimes\TAEF\x64\TE.exe $(TargetPath) /inproc WindowsLocalDebugger - \ No newline at end of file + diff --git a/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj.filters b/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj.filters index 7971da36..d65a2fa4 100644 --- a/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj.filters +++ b/Build/libHttpClient.UnitTest.141.TAEF/libHttpClient.UnitTest.141.TAEF.vcxproj.filters @@ -99,6 +99,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -222,55 +225,55 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {6D0EEE4B-8A61-37FC-BFB1-2B242FD06B77} + {449C188B-2421-3ECF-88BD-7B85E0FFB8B4} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {EC698838-C450-37D0-B39D-05B2997275C7} + {D8238937-E47F-352E-AF00-EAAC1AF0C700} - {07B17B8F-467C-3701-BBA0-ECEAD5ECCC2F} + {16308D30-130C-394A-AD28-51E91740ED63} - {622663E3-C17A-32F2-AFB2-825B97C95BF3} + {8DEE0723-9333-3E6E-BD8A-FDE4969E749A} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {1F0C99DD-47D3-3404-8982-9B4C0F5454CE} + {216D66A1-4EBE-3C4B-9BAC-88EB74CC3262} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj b/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj index fe6a9fc6..7192aff0 100644 --- a/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj +++ b/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj @@ -34,7 +34,7 @@ $(IntDir)pch.pch true /bigobj /Zm512 %(AdditionalOptions) - C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\store\references;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\vcpackages;C:\Program Files (x86)\Windows Kits\10\UnionMetadata;%(AdditionalUsingDirectories) + C:\Program Files (x86)\Windows Kits\10\UnionMetadata;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\store\references;%(AdditionalUsingDirectories) true @@ -178,6 +178,7 @@ + @@ -254,4 +255,4 @@ - \ No newline at end of file + diff --git a/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj.filters b/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj.filters index 07907cfe..3dc05b46 100644 --- a/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj.filters +++ b/Build/libHttpClient.UnitTest.141.TE/libHttpClient.UnitTest.141.TE.vcxproj.filters @@ -96,6 +96,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -216,55 +219,55 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {6D0EEE4B-8A61-37FC-BFB1-2B242FD06B77} + {449C188B-2421-3ECF-88BD-7B85E0FFB8B4} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {EC698838-C450-37D0-B39D-05B2997275C7} + {D8238937-E47F-352E-AF00-EAAC1AF0C700} - {07B17B8F-467C-3701-BBA0-ECEAD5ECCC2F} + {16308D30-130C-394A-AD28-51E91740ED63} - {622663E3-C17A-32F2-AFB2-825B97C95BF3} + {8DEE0723-9333-3E6E-BD8A-FDE4969E749A} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {1F0C99DD-47D3-3404-8982-9B4C0F5454CE} + {216D66A1-4EBE-3C4B-9BAC-88EB74CC3262} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj b/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj index 281cbd02..315a8b94 100644 --- a/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj +++ b/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj @@ -102,6 +102,7 @@ + diff --git a/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj.filters b/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj.filters index 7971da36..d65a2fa4 100644 --- a/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj.filters +++ b/Build/libHttpClient.UnitTest.142.TAEF/libHttpClient.UnitTest.142.TAEF.vcxproj.filters @@ -99,6 +99,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -222,55 +225,55 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {6D0EEE4B-8A61-37FC-BFB1-2B242FD06B77} + {449C188B-2421-3ECF-88BD-7B85E0FFB8B4} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {EC698838-C450-37D0-B39D-05B2997275C7} + {D8238937-E47F-352E-AF00-EAAC1AF0C700} - {07B17B8F-467C-3701-BBA0-ECEAD5ECCC2F} + {16308D30-130C-394A-AD28-51E91740ED63} - {622663E3-C17A-32F2-AFB2-825B97C95BF3} + {8DEE0723-9333-3E6E-BD8A-FDE4969E749A} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {1F0C99DD-47D3-3404-8982-9B4C0F5454CE} + {216D66A1-4EBE-3C4B-9BAC-88EB74CC3262} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj b/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj index 8f069ff2..db94d543 100644 --- a/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj +++ b/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj @@ -178,6 +178,7 @@ + diff --git a/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj.filters b/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj.filters index 07907cfe..3dc05b46 100644 --- a/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj.filters +++ b/Build/libHttpClient.UnitTest.142.TE/libHttpClient.UnitTest.142.TE.vcxproj.filters @@ -96,6 +96,9 @@ C++ Source\Common + + C++ Source\Common + C++ Source\Common @@ -216,55 +219,55 @@ - {A1D6BFE0-C752-37C4-84A8-DC1BAD7ACDBB} + {7AC647CD-3FC4-3617-ACC3-BBFE274959CB} - {311C2E0C-757A-396B-B005-9C3E2AC974F6} + {9DF77FF5-7EF8-3DA6-8C65-36B669024AB4} - {B9434CE8-713E-36C3-BCDA-769594459CD1} + {43E16D74-2A1C-32E2-B3CE-5A63B678C17C} - {748EFFF4-1C27-379F-90E2-0343E1267432} + {5A22794E-EF59-3A69-8DA2-FC7906ABE95D} - {EBBC7A73-32B3-304C-A088-0766E8E09094} + {CAD911E1-C397-3832-9431-A7DC58D7E2E8} - {6D0EEE4B-8A61-37FC-BFB1-2B242FD06B77} + {449C188B-2421-3ECF-88BD-7B85E0FFB8B4} - {EE80538A-4E77-32F6-9CB6-FD60616A0C52} + {D6B64F15-5825-33F1-8FFC-1929189AC0FA} - {7FBD5635-E218-3828-9907-011F9FEB0020} + {EBFE27FD-29C5-3AD4-BFE3-9D4524A9C9EB} - {C1D0A9B1-A7E8-307D-B0E3-6D0577F43340} + {4394D2D2-0582-3D96-91ED-DCDAE0B58239} - {424D80A0-2669-3072-B27A-D961C7D2D31B} + {4DEAFEB9-86B2-3358-BD19-E0AE4159EBE0} - {839B03FA-A816-3B0D-B78E-80E1B8A6B4E4} + {EF64EA95-FEED-3E91-BC0E-4A59FDE0770D} - {EC698838-C450-37D0-B39D-05B2997275C7} + {D8238937-E47F-352E-AF00-EAAC1AF0C700} - {07B17B8F-467C-3701-BBA0-ECEAD5ECCC2F} + {16308D30-130C-394A-AD28-51E91740ED63} - {622663E3-C17A-32F2-AFB2-825B97C95BF3} + {8DEE0723-9333-3E6E-BD8A-FDE4969E749A} - {3928859A-5E7E-3865-8877-2AD5FBB92278} + {8CC08048-6545-3E2E-97E1-12D79A5FA30C} - {1F0C99DD-47D3-3404-8982-9B4C0F5454CE} + {216D66A1-4EBE-3C4B-9BAC-88EB74CC3262} - {DBC2122A-8939-3C43-8F28-44E5561A58D4} + {8FC5B9E5-7989-3075-B3FA-AFD7C7C58F28} diff --git a/Include/httpClient/httpClient.h b/Include/httpClient/httpClient.h index c803c8a7..60aedfc2 100644 --- a/Include/httpClient/httpClient.h +++ b/Include/httpClient/httpClient.h @@ -677,7 +677,9 @@ STDAPI HCHttpCallResponseGetStatusCode( /// The network error code of the HTTP call. Possible values are S_OK, or E_FAIL. /// The platform specific network error code of the HTTP call to be used for tracing / debugging. /// Result code for this API operation. Possible values are S_OK, E_INVALIDARG, or E_FAIL. -/// This can only be called after calling HCHttpCallPerformAsync when the HTTP task is completed. +/// This can only be called after calling HCHttpCallPerformAsync when the HTTP task is completed. On the GDK Platform, HTTP calls that fail +/// due to the title being suspended will have platformNetworkErrorCode set to HRESULT_FROM_WIN32(PROCESS_SUSPEND_RESUME). +/// STDAPI HCHttpCallResponseGetNetworkErrorCode( _In_ HCCallHandle call, _Out_ HRESULT* networkErrorCode, diff --git a/Source/Common/Result.h b/Source/Common/Result.h new file mode 100644 index 00000000..06b21b97 --- /dev/null +++ b/Source/Common/Result.h @@ -0,0 +1,88 @@ +#pragma once + +template +class Result +{ +public: + // Construct successful result + Result(T&& payload); + + // Failed result (no payload) + Result(HRESULT hr); + + Result(const Result&) = default; + Result(Result&&) = default; + Result& operator=(const Result&) = default; + Result& operator=(Result&&) = default; + ~Result() = default; + + HRESULT const hr; + + // Get result payload. Asserts if result isn't successful. + const T& Payload() const; + T&& ExtractPayload(); + +private: + T m_payload{}; +}; + +// Result specialization without a payload +template<> +class Result +{ +public: + // Construct successful result + Result(); + + // Failed result (no payload) + Result(HRESULT hr); + + Result(const Result&) = default; + Result(Result&&) = default; + Result& operator=(const Result&) = default; + Result& operator=(Result&&) = default; + ~Result() = default; + + HRESULT const hr; +}; + +//------------------------------------------------------------------------------ +// Template implementations +//------------------------------------------------------------------------------ + +template +Result::Result(T&& payload) : + hr{ S_OK }, + m_payload{ std::move(payload) } +{ +} + +template +Result::Result(HRESULT hr_) : + hr{ hr_ } +{ +} + +template +const T& Result::Payload() const +{ + assert(SUCCEEDED(hr)); + return m_payload; +} + +template +T&& Result::ExtractPayload() +{ + assert(SUCCEEDED(hr)); + return std::move(m_payload); +} + +inline Result::Result() : + hr{ S_OK } +{ +} + +inline Result::Result(HRESULT hr_) : + hr{ hr_ } +{ +} diff --git a/Source/Global/mem.h b/Source/Global/mem.h index 2679707f..93ff7d61 100644 --- a/Source/Global/mem.h +++ b/Source/Global/mem.h @@ -165,3 +165,5 @@ using http_internal_dequeue = std::deque>; template using http_internal_queue = std::queue>; +template +using http_internal_list = std::list>; diff --git a/Source/HTTP/Curl/CurlEasyRequest.cpp b/Source/HTTP/Curl/CurlEasyRequest.cpp new file mode 100644 index 00000000..e0cf9a9b --- /dev/null +++ b/Source/HTTP/Curl/CurlEasyRequest.cpp @@ -0,0 +1,366 @@ +#include "pch.h" +#include "CurlEasyRequest.h" +#include "CurlProvider.h" + +namespace xbox +{ +namespace http_client +{ + +CurlEasyRequest::CurlEasyRequest(CURL* curlEasyHandle, HCCallHandle hcCall, XAsyncBlock* async) + : m_curlEasyHandle{ curlEasyHandle }, + m_hcCallHandle{ hcCall }, + m_asyncBlock{ async } +{ +} + +CurlEasyRequest::~CurlEasyRequest() +{ + curl_easy_cleanup(m_curlEasyHandle); + curl_slist_free_all(m_headers); +} + +Result> CurlEasyRequest::Initialize(HCCallHandle hcCall, XAsyncBlock* async) +{ + CURL* curlEasyHandle{ curl_easy_init() }; + if (!curlEasyHandle) + { + HC_TRACE_ERROR(HTTPCLIENT, "CurlEasyRequest::Initialize:: curl_easy_init failed"); + return E_FAIL; + } + + http_stl_allocator a{}; + HC_UNIQUE_PTR easyRequest{ new (a.allocate(1)) CurlEasyRequest{ curlEasyHandle, hcCall, async } }; + + // body (first so we can override things curl "helpfully" sets for us) + uint8_t const* body = nullptr; + uint32_t bodySize = 0; + RETURN_IF_FAILED(HCHttpCallRequestGetRequestBodyBytes(hcCall, &body, &bodySize)); + + if (bodySize > 0) + { + // we set both POSTFIELDSIZE and INFILESIZE because curl uses one or the + // other depending on method + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_POSTFIELDSIZE, bodySize)); + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_INFILESIZE, bodySize)); + + // read callback + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_READFUNCTION, &ReadCallback)); + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_READDATA, easyRequest.get())); + } + + // url & method + char const* url = nullptr; + char const* method = nullptr; + RETURN_IF_FAILED(HCHttpCallRequestGetUrl(hcCall, &method, &url)); + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_URL, url)); + + CURLoption opt = CURLOPT_HTTPGET; + RETURN_IF_FAILED(MethodStringToOpt(method, opt)); + if (opt == CURLOPT_CUSTOMREQUEST) + { + RETURN_IF_FAILED(easyRequest->SetOpt(opt, method)); + } + else + { + RETURN_IF_FAILED(easyRequest->SetOpt(opt, 1)); + } + + // headers + uint32_t headerCount{ 0 }; + RETURN_IF_FAILED(HCHttpCallRequestGetNumHeaders(hcCall, &headerCount)); + + bool haveUserAgentHeader = false; + for (auto i = 0u; i < headerCount; ++i) + { + char const* name{ nullptr }; + char const* value{ nullptr }; + RETURN_IF_FAILED(HCHttpCallRequestGetHeaderAtIndex(hcCall, i, &name, &value)); + if (std::strcmp(name, "User-Agent") == 0) + { + haveUserAgentHeader = true; + } + RETURN_IF_FAILED(easyRequest->AddHeader(name, value)); + } + + if (!haveUserAgentHeader) + { + RETURN_IF_FAILED(easyRequest->AddHeader("User-Agent", "libHttpClient/1.0.0.0")); + } + + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_HTTPHEADER, easyRequest->m_headers)); + + // timeout + uint32_t timeoutSeconds{ 0 }; + RETURN_IF_FAILED(HCHttpCallRequestGetTimeout(hcCall, &timeoutSeconds)); + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_TIMEOUT_MS, timeoutSeconds * 1000)); + + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_VERBOSE, 0)); // verbose logging (0 off, 1 on) + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_HEADER, 0)); // do not write headers to the write callback + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_ERRORBUFFER, easyRequest->m_errorBuffer)); + + // write data callback + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_WRITEFUNCTION, &WriteDataCallback)); + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_WRITEDATA, easyRequest.get())); + + // write header callback + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_HEADERFUNCTION, &WriteHeaderCallback)); + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_HEADERDATA, easyRequest.get())); + + // debug callback + RETURN_IF_FAILED(easyRequest->SetOpt(CURLOPT_DEBUGFUNCTION, &DebugCallback)); + + return Result>{ std::move(easyRequest) }; +} + +CURL* CurlEasyRequest::Handle() const noexcept +{ + return m_curlEasyHandle; +} + +void CurlEasyRequest::Complete(CURLcode result) +{ + HC_TRACE_VERBOSE(HTTPCLIENT, "CurlEasyRequest::Complete: CURLCode=%ul", result); + + if (result != CURLE_OK) + { + HC_TRACE_VERBOSE(HTTPCLIENT, "CurlEasyRequest::m_errorBuffer='%s'", m_errorBuffer); + + long platformError = 0; + auto curle = curl_easy_getinfo(m_curlEasyHandle, CURLINFO_OS_ERRNO, &platformError); + if (curle != CURLE_OK) + { + return Fail(HrFromCurle(curle)); + } + + HRESULT hr = HCHttpCallResponseSetNetworkErrorCode(m_hcCallHandle, E_FAIL, static_cast(platformError)); + assert(SUCCEEDED(hr)); + + hr = HCHttpCallResponseSetPlatformNetworkErrorMessage(m_hcCallHandle, curl_easy_strerror(result)); + assert(SUCCEEDED(hr)); + } + else + { + long httpStatus = 0; + auto curle = curl_easy_getinfo(m_curlEasyHandle, CURLINFO_RESPONSE_CODE, &httpStatus); + if (curle != CURLE_OK) + { + return Fail(HrFromCurle(curle)); + } + + HRESULT hr = HCHttpCallResponseSetStatusCode(m_hcCallHandle, httpStatus); + assert(SUCCEEDED(hr)); + UNREFERENCED_PARAMETER(hr); + } + + // At this point, always complete with XAsync success - http/network errors returned via HCCallHandle + XAsyncComplete(m_asyncBlock, S_OK, 0); +} + +void CurlEasyRequest::Fail(HRESULT hr) +{ + HC_TRACE_ERROR_HR(HTTPCLIENT, hr, "CurlEasyRequest::Fail"); + XAsyncComplete(m_asyncBlock, hr, 0); +} + +HRESULT CurlEasyRequest::AddHeader(char const* name, char const* value) noexcept +{ + int required = std::snprintf(nullptr, 0, "%s: %s", name, value); + assert(required > 0); + + m_headersBuffer.emplace_back(); + auto& header = m_headersBuffer.back(); + + header.resize(static_cast(required), '\0'); + int written = std::snprintf(&header[0], header.size() + 1, "%s: %s", name, value); + assert(written == required); + (void)written; + + m_headers = curl_slist_append(m_headers, header.c_str()); + + return S_OK; +} + +HRESULT CurlEasyRequest::CopyNextBodySection(void* buffer, size_t maxSize, size_t& bytesCopied) noexcept +{ + assert(buffer); + + uint8_t const* body = nullptr; + uint32_t bodySize = 0; + RETURN_IF_FAILED(HCHttpCallRequestGetRequestBodyBytes(m_hcCallHandle, &body, &bodySize)); + + size_t toCopy = 0; + + if (m_bodyCopied == bodySize) + { + bytesCopied = 0; + return S_OK; + } + else if (maxSize >= bodySize - m_bodyCopied) + { + // copy everything + toCopy = bodySize - m_bodyCopied; + } + else + { + // copy as much as we can + toCopy = maxSize; + } + + void const* startCopyFrom = body + m_bodyCopied; + assert(startCopyFrom < body + bodySize); + + m_bodyCopied += toCopy; + assert(m_bodyCopied <= bodySize); + + assert(toCopy <= maxSize); + memcpy(buffer, startCopyFrom, toCopy); + + bytesCopied = toCopy; + return S_OK; +} + +size_t CurlEasyRequest::ReadCallback(char* buffer, size_t size, size_t nitems, void* context) noexcept +{ + HC_TRACE_VERBOSE(HTTPCLIENT, "CurlEasyRequest::ReadCallback: reading body data (%llu items of size %llu)", nitems, size); + + auto request = static_cast(context); + + size_t bufferSize = size * nitems; + size_t copied = 0; + HRESULT hr = request->CopyNextBodySection(buffer, bufferSize, copied); + if (FAILED(hr)) + { + return CURL_READFUNC_ABORT; + } + + return copied; +} + +size_t CurlEasyRequest::WriteHeaderCallback(char* buffer, size_t size, size_t nitems, void* context) noexcept +{ + HC_TRACE_VERBOSE(HTTPCLIENT, "CurlEasyRequest::WriteHeaderCallback: received header (%llu items of size %llu)", nitems, size); + + auto request = static_cast(context); + +#if HC_TRACE_INFORMATION_ENABLE + if (size * nitems > 2) + { + HC_TRACE_INFORMATION(HTTPCLIENT, "'%.*s'", size * nitems - 2, buffer); // -2 to avoid printing \r\n + } +#endif + + size_t bufferSize = size * nitems; + char const* current = buffer; + char const* end = buffer + bufferSize; + + // scan for the end of the header name + char const* name = current; + size_t nameSize = 0; + for (; current < end; ++current) + { + if (*current == ':') + { + nameSize = current - buffer; + ++current; + break; + } + } + if (current == end) + { + // not a real header, drop it + return bufferSize; + } + + // skip whitespace + for (; current < end && *current == ' '; ++current) // assume that Curl canonicalizes headers + {} + + // scan for the end of the header value + char const* value = current; + size_t valueSize = 0; + char const* valueStart = current; + for (; current < end; ++current) + { + if (*current == '\r') + { + valueSize = current - valueStart; + break; + } + } + if (current == end) + { + // curl should always gives us the new lines at the end of the header + assert(false); + } + + HRESULT hr = HCHttpCallResponseSetHeaderWithLength(request->m_hcCallHandle, name, nameSize, value, valueSize); + assert(SUCCEEDED(hr)); + + return bufferSize; +} + +size_t CurlEasyRequest::WriteDataCallback(char* buffer, size_t size, size_t nmemb, void* context) noexcept +{ + HC_TRACE_VERBOSE(HTTPCLIENT, "CurlEasyRequest::WriteDataCallback: received data (%llu bytes)", nmemb); + + auto request = static_cast(context); + + HC_TRACE_INFORMATION(HTTPCLIENT, "'%.*s'", nmemb, buffer); + + size_t bufferSize = size * nmemb; + HRESULT hr = HCHttpCallResponseAppendResponseBodyBytes(request->m_hcCallHandle, reinterpret_cast(buffer), bufferSize); + assert(SUCCEEDED(hr)); + + return nmemb; +} + +int CurlEasyRequest::DebugCallback(CURL* /*curlHandle*/, curl_infotype type, char* data, size_t size, void* /*context*/) noexcept +{ + char const* event = ""; + switch (type) + { + case CURLINFO_TEXT: event = "TEXT"; break; + case CURLINFO_HEADER_OUT: event = "HEADER OUT"; break; + case CURLINFO_DATA_OUT: event = "DATA OUT"; break; + case CURLINFO_SSL_DATA_OUT: event = "SSL OUT"; break; + case CURLINFO_HEADER_IN: event = "HEADER IN"; break; + case CURLINFO_DATA_IN: event = "DATA IN"; break; + case CURLINFO_SSL_DATA_IN: event = "SSL IN"; break; + case CURLINFO_END: event = "END"; break; + } + + if (type == CURLINFO_TEXT && data[size - 1] == '\n') + { + size -= 1; + } + + HC_TRACE_INFORMATION(HTTPCLIENT, "CURL %10s - %.*s", event, size, data); + + return CURLE_OK; +} + +HRESULT CurlEasyRequest::MethodStringToOpt(char const* method, CURLoption& opt) noexcept +{ + if (strcmp(method, "GET") == 0) + { + opt = CURLOPT_HTTPGET; + } + else if (strcmp(method, "POST") == 0) + { + opt = CURLOPT_POST; + } + else if (strcmp(method, "PUT") == 0) + { + opt = CURLOPT_UPLOAD; + } + else + { + opt = CURLOPT_CUSTOMREQUEST; + } + + return S_OK; +} + +} +} diff --git a/Source/HTTP/Curl/CurlEasyRequest.h b/Source/HTTP/Curl/CurlEasyRequest.h new file mode 100644 index 00000000..8f9b9f9e --- /dev/null +++ b/Source/HTTP/Curl/CurlEasyRequest.h @@ -0,0 +1,80 @@ +#pragma once + +#if HC_PLATFORM == HC_PLATFORM_GDK +#include +#else +// This path is untested, but this http provider should work with other curl implementations as well. +// The logic in CurlMulti::Perform is optimized for XCurl, but should work on any curl implementation. +#include +#endif +#include "Result.h" + +namespace xbox +{ +namespace http_client +{ + +class CurlEasyRequest +{ +public: + static Result> Initialize(HCCallHandle hcCall, XAsyncBlock* async); + CurlEasyRequest(const CurlEasyRequest&) = delete; + CurlEasyRequest(CurlEasyRequest&&) = delete; + CurlEasyRequest& operator=(const CurlEasyRequest&) = delete; + ~CurlEasyRequest(); + + CURL* Handle() const noexcept; + + void Complete(CURLcode result); + void Fail(HRESULT hr); + +private: + CurlEasyRequest(CURL* curlEasyHandle, HCCallHandle hcCall, XAsyncBlock* async); + + // Wrapper of curl_easy_setopt. Requires explicit template instantiation to ensure the correct arg is passed + template + struct OptType + { + using type = T; + }; + template + HRESULT SetOpt(CURLoption option, typename OptType::type) noexcept; + + HRESULT AddHeader(char const* name, char const* value) noexcept; + HRESULT CopyNextBodySection(void* buffer, size_t maxSize, size_t& bytesCopied) noexcept; + + // Curl callbacks + static size_t ReadCallback(char* buffer, size_t size, size_t nitems, void* context) noexcept; + static size_t WriteHeaderCallback(char* buffer, size_t size, size_t nitems, void* context) noexcept; + static size_t WriteDataCallback(char* buffer, size_t size, size_t nmemb, void* context) noexcept; + static int DebugCallback(CURL* curlHandle, curl_infotype type, char* data, size_t size, void* context) noexcept; + + static HRESULT MethodStringToOpt(char const* method, CURLoption& opt) noexcept; + + CURL* m_curlEasyHandle; + HCCallHandle m_hcCallHandle; // non-owning + XAsyncBlock* m_asyncBlock; // non-owning + + curl_slist* m_headers{ nullptr }; + http_internal_list m_headersBuffer{}; + size_t m_bodyCopied{ 0 }; + char m_errorBuffer[CURL_ERROR_SIZE]{ 0 }; +}; + +//------------------------------------------------------------------------------ +// Template implementations +//------------------------------------------------------------------------------ + +template +HRESULT CurlEasyRequest::SetOpt(CURLoption option, typename OptType::type v) noexcept +{ + CURLcode result = curl_easy_setopt(m_curlEasyHandle, option, v); + if (result != CURLE_OK) + { + HC_TRACE_ERROR(HTTPCLIENT, "curl_easy_setopt(request, %d, value) failed with %d", option, result); + } + return HrFromCurle(result); +} + +} // http_client +} // xbox diff --git a/Source/HTTP/Curl/CurlMulti.cpp b/Source/HTTP/Curl/CurlMulti.cpp new file mode 100644 index 00000000..0f90b042 --- /dev/null +++ b/Source/HTTP/Curl/CurlMulti.cpp @@ -0,0 +1,168 @@ +#include "pch.h" +#include "CurlMulti.h" +#include "CurlProvider.h" + +namespace xbox +{ +namespace http_client +{ + +// XCurl doesn't support curl_multi_timeout, so use a small, fixed delay between calls to curl_multi_perform +#define PERFORM_DELAY_MS 50 +#define POLL_TIMEOUT_MS 0 + +Result> CurlMulti::Initialize(XTaskQueuePortHandle workPort) +{ + assert(workPort); + + http_stl_allocator a{}; + HC_UNIQUE_PTR multi{ new (a.allocate(1)) CurlMulti }; + + multi->m_curlMultiHandle = curl_multi_init(); + if (!multi->m_curlMultiHandle) + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::Initialize: curl_multi_init failed"); + return E_FAIL; + } + + RETURN_IF_FAILED(XTaskQueueCreateComposite(workPort, workPort, &multi->m_queue)); + + return Result>{ std::move(multi) }; +} + +CurlMulti::~CurlMulti() +{ + if (m_queue) + { + XTaskQueueTerminate(m_queue, true, nullptr, nullptr); + XTaskQueueCloseHandle(m_queue); + } + + if (!m_easyRequests.empty()) + { + HC_TRACE_WARNING(HTTPCLIENT, "XCurlMulti::~XCurlMulti: Failing all active requests."); + FailAllRequests(E_UNEXPECTED); + } + + if (m_curlMultiHandle) + { + curl_multi_cleanup(m_curlMultiHandle); + } +} + +HRESULT CurlMulti::AddRequest(HC_UNIQUE_PTR&& easyRequest) +{ + std::unique_lock lock{ m_mutex }; + + auto result = curl_multi_add_handle(m_curlMultiHandle, easyRequest->Handle()); + if (result != CURLM_OK) + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::AddRequest: curl_multi_add_handle failed with CURLCode=%u", result); + return HrFromCurlm(result); + } + + m_easyRequests.emplace(easyRequest->Handle(), std::move(easyRequest)); + + // Release lock before scheduling Perform in case m_queue is an Immediate dispatch queue + lock.unlock(); + RETURN_IF_FAILED(XTaskQueueSubmitCallback(m_queue, XTaskQueuePort::Work, this, CurlMulti::TaskQueueCallback)); + + return S_OK; +} + +void CALLBACK CurlMulti::TaskQueueCallback(_In_opt_ void* context, _In_ bool canceled) noexcept +{ + if (!canceled) + { + auto multi = static_cast(context); + HRESULT hr = multi->Perform(); + if (FAILED(hr)) + { + HC_TRACE_ERROR_HR(HTTPCLIENT, hr, "XCurlMulti::Perform failed. Failing all active requests."); + multi->FailAllRequests(hr); + } + } +} + +HRESULT CurlMulti::Perform() noexcept +{ + std::unique_lock lock{ m_mutex }; + + int runningRequests{ 0 }; + CURLMcode result = curl_multi_perform(m_curlMultiHandle, &runningRequests); + if (result != CURLM_OK) + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::Perform: curl_multi_perform failed with CURLCode=%u", result); + return HrFromCurlm(result); + } + + int remainingMessages{ 1 }; // assume there is at least 1 message so loop is always entered + while (remainingMessages) + { + CURLMsg* message = curl_multi_info_read(m_curlMultiHandle, &remainingMessages); + if (message) + { + switch (message->msg) + { + case CURLMSG_DONE: + { + auto requestIter = m_easyRequests.find(message->easy_handle); + assert(requestIter != m_easyRequests.end()); + + result = curl_multi_remove_handle(m_curlMultiHandle, message->easy_handle); + if (result != CURLM_OK) + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::Perform: curl_multi_remove_handle failed with CURLCode=%u", result); + } + + requestIter->second->Complete(message->data.result); + m_easyRequests.erase(requestIter); + } + break; + case CURLMSG_NONE: + case CURLMSG_LAST: + default: + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::Perform: Unrecognized CURLMsg!"); + assert(false); + } + break; + } + } + } + + if (runningRequests) + { + // Reschedule Perform if there are still running requests + int workAvailable{ 0 }; + result = curl_multi_poll(m_curlMultiHandle, nullptr, 0, POLL_TIMEOUT_MS, &workAvailable); + if (result != CURLM_OK) + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::Perform: curl_multi_poll failed with CURLCode=%u", result); + return HrFromCurlm(result); + } + + RETURN_IF_FAILED(XTaskQueueSubmitDelayedCallback(m_queue, XTaskQueuePort::Work, workAvailable ? 0 : PERFORM_DELAY_MS, this, CurlMulti::TaskQueueCallback)); + } + + return S_OK; +} + +void CurlMulti::FailAllRequests(HRESULT hr) noexcept +{ + std::unique_lock lock{ m_mutex }; + + for (auto& pair : m_easyRequests) + { + auto result = curl_multi_remove_handle(m_curlMultiHandle, pair.first); + if (FAILED(HrFromCurlm(result))) + { + HC_TRACE_ERROR(HTTPCLIENT, "XCurlMulti::FailAllRequests: curl_multi_remove_handle failed with CURLCode=%u", result); + } + pair.second->Fail(hr); + } + m_easyRequests.clear(); +} + +} // http_client +} // xbox diff --git a/Source/HTTP/Curl/CurlMulti.h b/Source/HTTP/Curl/CurlMulti.h new file mode 100644 index 00000000..d1a7c800 --- /dev/null +++ b/Source/HTTP/Curl/CurlMulti.h @@ -0,0 +1,39 @@ +#pragma once + +#include "CurlEasyRequest.h" +#include "Result.h" + +namespace xbox +{ +namespace http_client +{ + +class CurlMulti +{ +public: + static Result> Initialize(XTaskQueuePortHandle workPort); + CurlMulti(const CurlMulti&) = delete; + CurlMulti(CurlMulti&&) = delete; + CurlMulti& operator=(const CurlMulti&) = delete; + ~CurlMulti(); + + // Wrapper around curl_multi_add_handle + HRESULT AddRequest(HC_UNIQUE_PTR&& easyRequest); + +private: + CurlMulti() = default; + + static void CALLBACK TaskQueueCallback(_In_opt_ void* context, _In_ bool canceled) noexcept; + HRESULT Perform() noexcept; + + // Fail all active requests due to unexpected CURLM or platform error + void FailAllRequests(HRESULT hr) noexcept; + + CURLM* m_curlMultiHandle{ nullptr }; + XTaskQueueHandle m_queue{ nullptr }; + std::mutex m_mutex; + http_internal_map> m_easyRequests; +}; + +} // http_client +} // xbox diff --git a/Source/HTTP/Curl/CurlProvider.cpp b/Source/HTTP/Curl/CurlProvider.cpp new file mode 100644 index 00000000..877a0311 --- /dev/null +++ b/Source/HTTP/Curl/CurlProvider.cpp @@ -0,0 +1,126 @@ +#include "pch.h" +#include "CurlProvider.h" +#include "CurlEasyRequest.h" + +using namespace xbox::http_client; + +HRESULT Internal_InitializeHttpPlatform(HCInitArgs* args, PerformEnv& performEnv) noexcept +{ + assert(args == nullptr); + UNREFERENCED_PARAMETER(args); + + auto initResult = HC_PERFORM_ENV::Initialize(); + RETURN_IF_FAILED(initResult.hr); + + performEnv = initResult.ExtractPayload(); + + return S_OK; +} + +void Internal_CleanupHttpPlatform(HC_PERFORM_ENV* performEnv) noexcept +{ + // HC_PERFORM_ENV created with custom deleter - HC_PERFORM_ENV needs to be destroyed and cleaned up explicitly. + http_stl_allocator a{}; + std::allocator_traits>::destroy(a, performEnv); + std::allocator_traits>::deallocate(a, performEnv, 1); +} + +HRESULT Internal_SetGlobalProxy( + _In_ HC_PERFORM_ENV* performEnv, + _In_ const char* proxyUri +) noexcept +{ + UNREFERENCED_PARAMETER(performEnv); + UNREFERENCED_PARAMETER(proxyUri); + return E_NOTIMPL; +} + +void CALLBACK Internal_HCHttpCallPerformAsync( + _In_ HCCallHandle call, + _Inout_ XAsyncBlock* asyncBlock, + _In_opt_ void* context, + _In_ HCPerformEnv env +) noexcept +{ + UNREFERENCED_PARAMETER(context); + assert(env); + + HRESULT hr = env->Perform(call, asyncBlock); + if (FAILED(hr)) + { + // Complete XAsyncBlock if we fail synchronously + XAsyncComplete(asyncBlock, hr, 0); + } +} + +namespace xbox +{ +namespace http_client +{ + +HRESULT HrFromCurle(CURLcode c) noexcept +{ + switch (c) + { + case CURLcode::CURLE_OK: return S_OK; + case CURLcode::CURLE_BAD_FUNCTION_ARGUMENT: assert(false); return E_INVALIDARG; // Indicates bad provider implementation + default: return E_FAIL; + } +} + +HRESULT HrFromCurlm(CURLMcode c) noexcept +{ + switch (c) + { + case CURLMcode::CURLM_OK: return S_OK; + case CURLMcode::CURLM_BAD_FUNCTION_ARGUMENT: assert(false); return E_INVALIDARG; + default: return E_FAIL; + } +} + +} // http_client +} // xbox + +Result HC_PERFORM_ENV::Initialize() +{ + CURLcode initRes = curl_global_init(CURL_GLOBAL_ALL); + RETURN_IF_FAILED(HrFromCurle(initRes)); + + http_stl_allocator a{}; + PerformEnv env{ new (a.allocate(1)) HC_PERFORM_ENV{} }; + + return std::move(env); +} + +HC_PERFORM_ENV::~HC_PERFORM_ENV() +{ + // make sure XCurlMultis are cleaned up before curl_global_cleanup + m_curlMultis.clear(); + + curl_global_cleanup(); +} + +HRESULT HC_PERFORM_ENV::Perform(HCCallHandle hcCall, XAsyncBlock* async) noexcept +{ + XTaskQueuePortHandle workPort{ nullptr }; + RETURN_IF_FAILED(XTaskQueueGetPort(async->queue, XTaskQueuePort::Work, &workPort)); + + HC_TRACE_VERBOSE(HTTPCLIENT, "HC_PERFORM_ENV::Perform: HCCallHandle=%p, workPort=%p", hcCall, workPort); + + auto easyInitResult = CurlEasyRequest::Initialize(hcCall, async); + RETURN_IF_FAILED(easyInitResult.hr); + + auto iter = m_curlMultis.find(workPort); + if (iter == m_curlMultis.end()) + { + auto multiInitResult = CurlMulti::Initialize(workPort); + RETURN_IF_FAILED(multiInitResult.hr); + + iter = m_curlMultis.emplace(workPort, multiInitResult.ExtractPayload()).first; + } + + auto& multi{ iter->second }; + RETURN_IF_FAILED(multi->AddRequest(easyInitResult.ExtractPayload())); + + return S_OK; +} diff --git a/Source/HTTP/Curl/CurlProvider.h b/Source/HTTP/Curl/CurlProvider.h new file mode 100644 index 00000000..45909086 --- /dev/null +++ b/Source/HTTP/Curl/CurlProvider.h @@ -0,0 +1,33 @@ +#pragma once + +#include "CurlMulti.h" +#include "Result.h" + +namespace xbox +{ +namespace http_client +{ + +HRESULT HrFromCurle(CURLcode c) noexcept; +HRESULT HrFromCurlm(CURLMcode c) noexcept; + +} // http_client +} // xbox + +struct HC_PERFORM_ENV +{ +public: + static Result Initialize(); + HC_PERFORM_ENV(const HC_PERFORM_ENV&) = delete; + HC_PERFORM_ENV(HC_PERFORM_ENV&&) = delete; + HC_PERFORM_ENV& operator=(const HC_PERFORM_ENV&) = delete; + virtual ~HC_PERFORM_ENV(); + + HRESULT Perform(HCCallHandle hcCall, XAsyncBlock* async) noexcept; + +private: + HC_PERFORM_ENV() = default; + + // Create an CurlMulti per work port + http_internal_map> m_curlMultis{}; +}; diff --git a/Utilities/CMake/CMakeLists.txt b/Utilities/CMake/CMakeLists.txt index a5d2fe0f..ee61f99d 100644 --- a/Utilities/CMake/CMakeLists.txt +++ b/Utilities/CMake/CMakeLists.txt @@ -130,6 +130,15 @@ set(XMLHttp_HTTP_Source_Files ../../../Source/HTTP/XMLHttp/xmlhttp_http_task.h ) +set(Curl_Source_Files + ../../../Source/HTTP/Curl/CurlEasyRequest.cpp + ../../../Source/HTTP/Curl/CurlEasyRequest.h + ../../../Source/HTTP/Curl/CurlMulti.cpp + ../../../Source/HTTP/Curl/CurlMulti.h + ../../../Source/HTTP/Curl/CurlProvider.cpp + ../../../Source/HTTP/Curl/CurlProvider.h + ) + set(Windows_Logger_Source_Files ../../../Source/Logger/Win/win_logger.cpp ) @@ -279,14 +288,14 @@ endif() if( GDK ) message(STATUS "GDK source group") - source_group("C++ Source\\HTTP\\WinHttp" FILES ${WinHttp_HTTP_Source_Files}) + source_group("C++ Source\\HTTP\\Curl" FILES ${Curl_Source_Files}) source_group("C++ Source\\Common\\Win" FILES ${Common_Windows_Source_Files}) source_group("C++ Source\\WebSocket\\Win" FILES ${GDK_WebSocket_Source_Files}) source_group("C++ Source\\Logger\\Win" FILES ${Windows_Logger_Source_Files}) list(APPEND SOURCE_FILES - ${WinHttp_HTTP_Source_Files} + ${Curl_Source_Files} ${Common_Windows_Source_Files} ${Windows_Logger_Source_Files} ${GDK_WebSocket_Source_Files} diff --git a/Utilities/CMake/GetCommonHCSourceFiles.cmake b/Utilities/CMake/GetCommonHCSourceFiles.cmake index 2f43b2aa..a9f31861 100644 --- a/Utilities/CMake/GetCommonHCSourceFiles.cmake +++ b/Utilities/CMake/GetCommonHCSourceFiles.cmake @@ -33,6 +33,7 @@ function(GET_COMMON_HC_SOURCE_FILES "${PATH_TO_ROOT}/Source/Common/pch.h" "${PATH_TO_ROOT}/Source/Common/pch_common.h" "${PATH_TO_ROOT}/Source/Common/pal_internal.h" + "${PATH_TO_ROOT}/Source/Common/Result.h" "${PATH_TO_ROOT}/Source/Common/ResultMacros.h" "${PATH_TO_ROOT}/Source/Common/uri.cpp" "${PATH_TO_ROOT}/Source/Common/uri.h" diff --git a/libHttpClient.props b/libHttpClient.props index 2cfbad4b..33f3a306 100644 --- a/libHttpClient.props +++ b/libHttpClient.props @@ -87,6 +87,11 @@ + + + + +