1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 * Unit tests for HttpRequest
26 */
27
28 #include "HttpFixture.hpp"
29
30 #include <kfg/properties.h> // KConfig_Set_Report_Cloud_Instance_Identity
31
32 #include <klib/data-buffer.h>
33
34 #include <kns/http.h>
35 #include <kns/http-priv.h>
36 #include <kns/manager.h>
37 #include <kns/kns-mgr-priv.h>
38
39 #include "../libs/klib/base64-priv.h" // BASE64_PAD_ENCODING
40 #include "../libs/kns/http-priv.h"
41 #include "../libs/vfs/resolver-cgi.h" /* SDL_CGI */
42
43 #include <kapp/args.h> // Args
44
45 #include <ktst/unit_test.hpp>
46
47 #define ALL
48
49 static rc_t argsHandler ( int argc, char * argv [] );
50 TEST_SUITE_WITH_ARGS_HANDLER ( HttpRequestVerifyURLSuite, argsHandler );
51
52 using namespace std;
53 using namespace ncbi::NK;
54
55 #define RELEASE(type, obj) do { rc_t rc2 = type##Release(obj); if (rc2 != 0 && rc == 0) { rc = rc2; } obj = NULL; } while (false)
56
57 class HttpRequestFixture : public HttpFixture
58 {
59 public:
MakeRequest(const char * p_urlBase)60 void MakeRequest(const char * p_urlBase)
61 {
62 m_url = MakeURL( p_urlBase );
63 if ( KNSManagerMakeClientRequest ( m_mgr, &m_req, 0x01010000, & m_stream, m_url.c_str() ) != 0 )
64 {
65 throw logic_error( "HttpRequestFixture::MakeRequest(): KNSManagerMakeClientRequest() failed" );
66 }
67 }
68
FormatRequest()69 string FormatRequest()
70 {
71 KDataBuffer buffer;
72 THROW_ON_RC( KDataBufferMake( & buffer, 8, 0 ) );
73 if ( KClientHttpRequestFormatPostMsg(m_req, & buffer) != 0 )
74 {
75 throw logic_error( "HttpRequestFixture::FormatRequest(): KClientHttpRequestFormatPostMsg() failed" );
76 }
77 string ret = string ( (char*)buffer.base, buffer.elem_count );
78 THROW_ON_RC( KDataBufferWhack( &buffer ) );
79 return ret;
80 }
81
82 string m_url;
83 };
84
85 #ifdef ALL
FIXTURE_TEST_CASE(HttpRequest_POST_NoParams,HttpRequestFixture)86 FIXTURE_TEST_CASE(HttpRequest_POST_NoParams, HttpRequestFixture)
87 { // Bug: KClientHttpRequestPOST crashed if request had no parameters
88 MakeRequest( GetName() );
89
90 KClientHttpResult *rslt;
91 TestStream::AddResponse("HTTP/1.1 200 OK\r\n");
92 REQUIRE_RC ( KClientHttpRequestPOST ( m_req, & rslt ) );
93 REQUIRE_RC ( KClientHttpResultRelease ( rslt ) );
94 }
95 #endif
96
FIXTURE_TEST_CASE(HttpRequest_head_as_get,HttpRequestFixture)97 FIXTURE_TEST_CASE(HttpRequest_head_as_get, HttpRequestFixture)
98 {
99 MakeRequest( GetName() );
100 m_req->payRequired = true; // triggers GET for HEAD
101
102 TestStream::AddResponse(
103 "HTTP/1.1 206 Partial Content\r\n"
104 "Content-Range: bytes 0-6/7\r\n"
105 "Content-Length: 7\r\n"
106 "\r\n"
107 "1234567"
108 "\r\n");
109 KClientHttpResult *rslt;
110 REQUIRE_RC ( KClientHttpRequestHEAD ( m_req, & rslt ) );
111 REQUIRE_RC ( KClientHttpResultRelease ( rslt ) );
112
113 string req = TestStream::m_requests.front();
114 // the request is a GET
115 REQUIRE_NE( string::npos, req.find("GET ") );
116 // -head is temporarily appended to the (thread-local) UserAgent string
117 REQUIRE_NE( string::npos, req.find("-head") );
118 // and then removed
119 const char * agent;
120 REQUIRE_RC( KNSManagerGetUserAgent( & agent ) );
121 REQUIRE_EQ( string::npos, string(agent).find("-head") );
122 }
123
FIXTURE_TEST_CASE(HttpRequest_head_as_post,HttpRequestFixture)124 FIXTURE_TEST_CASE(HttpRequest_head_as_post, HttpRequestFixture)
125 {
126 MakeRequest( GetName() );
127 m_req->ceRequired = true; // triggers POST for HEAD
128
129 TestStream::AddResponse(
130 "HTTP/1.1 206 Partial Content\r\n"
131 "Content-Range: bytes 0-6/7\r\n"
132 "Content-Length: 7\r\n"
133 "\r\n"
134 "1234567"
135 "\r\n");
136 KClientHttpResult *rslt;
137 REQUIRE_RC ( KClientHttpRequestHEAD ( m_req, & rslt ) );
138 REQUIRE_RC ( KClientHttpResultRelease ( rslt ) );
139
140 string req = TestStream::m_requests.front();
141 // the request is a POST
142 REQUIRE_NE( string::npos, req.find("POST ") );
143 // -head is temporarily appended to the (thread-local) UserAgent string
144 REQUIRE_NE( string::npos, req.find("-head") );
145 // and then removed
146 const char * agent;
147 REQUIRE_RC( KNSManagerGetUserAgent( & agent ) );
148 REQUIRE_EQ( string::npos, string(agent).find("-head") );
149 }
150
FIXTURE_TEST_CASE(HttpRequest_HEAD_as_POST_preserveUAsuffix,HttpRequestFixture)151 FIXTURE_TEST_CASE(HttpRequest_HEAD_as_POST_preserveUAsuffix, HttpRequestFixture)
152 {
153 KNSManagerSetUserAgentSuffix("suffix"); // has to survive KClientHttpRequestHEAD
154
155 MakeRequest( GetName() );
156 m_req->ceRequired = true; // triggers POST for HEAD
157
158 TestStream::AddResponse(
159 "HTTP/1.1 206 Partial Content\r\n"
160 "Content-Range: bytes 0-6/7\r\n"
161 "Content-Length: 7\r\n"
162 "\r\n"
163 "1234567"
164 "\r\n");
165 KClientHttpResult *rslt;
166 REQUIRE_RC ( KClientHttpRequestHEAD ( m_req, & rslt ) );
167 REQUIRE_RC ( KClientHttpResultRelease ( rslt ) );
168
169 const char * agent;
170 REQUIRE_RC( KNSManagerGetUserAgent( & agent ) );
171 // the original suffix is still there
172 REQUIRE_NE( string::npos, string(agent).find("suffix") );
173
174 string req = TestStream::m_requests.front();
175 // the request is a POST
176 REQUIRE_NE(string::npos, req.find("POST "));
177 // -head is appended to the UserAgent string with original suffix
178 REQUIRE_NE(string::npos, req.find("suffix-head"));
179 }
180
181 // KClientHttpRequestAddQueryParam
182
183 class HttpRequestVerifyURL : public SharedTest
184 {
185 public:
HttpRequestVerifyURL(TestCase * dad,KClientHttpRequest * req,string expectedUrl)186 HttpRequestVerifyURL( TestCase * dad, KClientHttpRequest * req, string expectedUrl )
187 : SharedTest ( dad, "" )
188 {
189 KDataBuffer rslt;
190 REQUIRE_RC ( KDataBufferMakeBytes( & rslt, 0 ) );
191 REQUIRE_RC ( KClientHttpRequestURL ( req, & rslt ) );
192 string s2 = string ( (const char*)rslt.base, (size_t)rslt.elem_count - 1); // 0 terminator is included in elem_count
193 REQUIRE_EQ ( expectedUrl, s2 );
194 KDataBufferWhack( & rslt );
195 }
196 };
197
198 #ifdef ALL
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_SelfNull,HttpRequestFixture)199 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_SelfNull, HttpRequestFixture)
200 {
201 MakeRequest( GetName() );
202 REQUIRE_RC_FAIL ( KClientHttpRequestAddQueryParam ( NULL, "name", "fmt" ) );
203 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_FmtNull,HttpRequestFixture)204 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_FmtNull, HttpRequestFixture)
205 {
206 MakeRequest( GetName() );
207 REQUIRE_RC_FAIL ( KClientHttpRequestAddQueryParam ( m_req, "name", NULL ) );
208 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_FmtEmpty,HttpRequestFixture)209 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_FmtEmpty, HttpRequestFixture)
210 {
211 MakeRequest( GetName() );
212 REQUIRE_RC_FAIL ( KClientHttpRequestAddQueryParam ( m_req, "name", "" ) );
213 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_First,HttpRequestFixture)214 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_First, HttpRequestFixture)
215 {
216 MakeRequest( GetName() );
217 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "name", "value" ) );
218
219 HttpRequestVerifyURL ( this, m_req, m_url + "?name=value" );
220 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_Second,HttpRequestFixture)221 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_Second, HttpRequestFixture)
222 {
223 MakeRequest( GetName() );
224 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "name1", "value1" ) );
225 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "name2", "value2" ) );
226
227 HttpRequestVerifyURL ( this, m_req, m_url + "?name1=value1&name2=value2" );
228 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_NameNull,HttpRequestFixture)229 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_NameNull, HttpRequestFixture)
230 {
231 MakeRequest( GetName() );
232 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, NULL, "value" ) );
233
234 HttpRequestVerifyURL ( this, m_req, m_url + "?value" );
235 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_NameEmpty,HttpRequestFixture)236 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_NameEmpty, HttpRequestFixture)
237 {
238 MakeRequest( GetName() );
239 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "", "value" ) );
240
241 HttpRequestVerifyURL ( this, m_req, m_url + "?value" );
242 }
FIXTURE_TEST_CASE(HttpRequestAddQueryParam_URL_encoding,HttpRequestFixture)243 FIXTURE_TEST_CASE(HttpRequestAddQueryParam_URL_encoding, HttpRequestFixture)
244 {
245 MakeRequest( GetName() );
246 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "", "value & \x1f" "a" "\x7f space \x81" ) );
247
248 HttpRequestVerifyURL ( this, m_req, m_url + "?value%20%26%20%1fa%7f%20space%20%81" );
249 }
250
FIXTURE_TEST_CASE(HttpRequestAddHeader,HttpRequestFixture)251 FIXTURE_TEST_CASE(HttpRequestAddHeader, HttpRequestFixture)
252 {
253 MakeRequest( GetName() );
254 REQUIRE_RC( KClientHttpRequestAddHeader(m_req, "Accept", "text/html") );
255 KDataBuffer buffer;
256 THROW_ON_RC( KDataBufferMake( & buffer, 8, 0 ) );
257 REQUIRE_RC( KClientHttpRequestFormatMsg(m_req, & buffer, "HEAD") );
258 REQUIRE( strstr((char*)buffer.base, "Accept: */*") == NULL) ;
259 REQUIRE_RC ( KDataBufferWhack( &buffer ) );
260 }
261
262 // KClientHttpRequestAddPostParam
FIXTURE_TEST_CASE(RequestAddPostParam,HttpRequestFixture)263 FIXTURE_TEST_CASE(RequestAddPostParam, HttpRequestFixture)
264 {
265 MakeRequest( GetName() );
266 REQUIRE_RC ( KClientHttpRequestAddPostParam ( m_req, "acc=%s", "SRR2043623" ) );
267 REQUIRE_EQ ( string ("acc=SRR2043623"), string ( KClientHttpRequestGetBody( m_req ) ) );
268 }
269
270 // KClientHttpRequestAddPostFileParam
271
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_SelfNull,HttpRequestFixture)272 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_SelfNull, HttpRequestFixture)
273 {
274 REQUIRE_RC_FAIL ( KClientHttpRequestAddPostFileParam ( nullptr, "name", "data/fileToPost" ) );
275 }
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_NameParamNull,HttpRequestFixture)276 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_NameParamNull, HttpRequestFixture)
277 {
278 MakeRequest( GetName() );
279 REQUIRE_RC_FAIL ( KClientHttpRequestAddPostFileParam ( m_req, nullptr, "data/fileToPost" ) );
280 }
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_PathParamNull,HttpRequestFixture)281 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_PathParamNull, HttpRequestFixture)
282 {
283 MakeRequest( GetName() );
284 REQUIRE_RC_FAIL ( KClientHttpRequestAddPostFileParam ( m_req, "name", nullptr ) );
285 }
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_PathParamEmpty,HttpRequestFixture)286 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_PathParamEmpty, HttpRequestFixture)
287 {
288 MakeRequest( GetName() );
289 REQUIRE_RC_FAIL ( KClientHttpRequestAddPostFileParam ( m_req, "name", "" ) );
290 }
291
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_FileMissing,HttpRequestFixture)292 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_FileMissing, HttpRequestFixture)
293 {
294 MakeRequest( GetName() );
295 REQUIRE_RC_FAIL ( KClientHttpRequestAddPostFileParam ( m_req, "name", "not-there.txt" ) );
296 }
297
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_EmptyFile,HttpRequestFixture)298 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_EmptyFile, HttpRequestFixture)
299 {
300 MakeRequest( GetName() );
301 REQUIRE_RC_FAIL ( KClientHttpRequestAddPostFileParam ( m_req, "name", "data/empty-file-to-post.txt" ) );
302 }
303
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_NonEmptyFile,HttpRequestFixture)304 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_NonEmptyFile, HttpRequestFixture)
305 {
306 MakeRequest( GetName() );
307 REQUIRE_RC ( KClientHttpRequestAddPostFileParam ( m_req, "name", "data/file-to-post.txt" ) );
308
309 #if BASE64_PAD_ENCODING
310 string expected ("name=Y29udGVudHMgb2YgdGhlIGZpbGUKCg==");
311 #else
312 string expected ("name=Y29udGVudHMgb2YgdGhlIGZpbGUKCg");
313 #endif
314 REQUIRE_EQ (
315 expected,
316 string ( KClientHttpRequestGetBody( m_req ) ) );
317 }
318
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_SendReceive,HttpRequestFixture)319 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_SendReceive, HttpRequestFixture)
320 {
321 const char * Server = SDL_CGI;
322
323 REQUIRE_RC ( KNSManagerMakeClientRequest ( m_mgr, &m_req, 0x01010000, NULL, Server ) );
324
325 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "acc", "SRR2043623" ) );
326 REQUIRE_RC ( KClientHttpRequestAddQueryParam ( m_req, "filetype", "run" ) );
327 REQUIRE_RC ( KClientHttpRequestAddPostFileParam ( m_req, "ngc", "data/prj_phs710EA_test.ngc" ) );
328
329 //cout << "req=\"" << FormatRequest() << "\"" << endl;
330
331 KClientHttpResult *rslt;
332 REQUIRE_RC ( KClientHttpRequestPOST ( m_req, & rslt ) );
333 uint32_t code;
334 char buf[1024];
335 size_t msg_size;
336 REQUIRE_RC ( KClientHttpResultStatus ( rslt, & code, buf, sizeof buf, & msg_size ) );
337 REQUIRE_EQ ( 200u, code );
338 REQUIRE_RC ( KClientHttpResultRelease ( rslt ) );
339 }
340
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_MixedPOSTparams,HttpRequestFixture)341 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_MixedPOSTparams, HttpRequestFixture)
342 {
343 MakeRequest( GetName() );
344
345 REQUIRE_RC ( KClientHttpRequestAddPostParam ( m_req, "acc=%s", "SRR2043623" ) );
346 REQUIRE_RC ( KClientHttpRequestAddPostFileParam ( m_req, "name", "data/file-to-post.txt" ) );
347 // the file goes into the body
348
349 #if BASE64_PAD_ENCODING
350 string expected ("acc=SRR2043623&name=Y29udGVudHMgb2YgdGhlIGZpbGUKCg==");
351 #else
352 string expected ("acc=SRR2043623&name=Y29udGVudHMgb2YgdGhlIGZpbGUKCg");
353 #endif
354 REQUIRE_EQ (
355 expected,
356 string ( KClientHttpRequestGetBody( m_req ) ) );
357 }
358
FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_POSTmultipleFiles,HttpRequestFixture)359 FIXTURE_TEST_CASE(HttpRequestAddPostFileParam_POSTmultipleFiles, HttpRequestFixture)
360 {
361 MakeRequest( GetName() );
362
363 REQUIRE_RC ( KClientHttpRequestAddPostFileParam ( m_req, "name1", "data/file-to-post.txt" ) );
364 REQUIRE_RC ( KClientHttpRequestAddPostFileParam ( m_req, "name2", "data/prj_phs710EA_test.ngc" ) );
365 //TODO: verify body
366 }
367
368 //////////////////////////
369 // Reliable HTTP request
FIXTURE_TEST_CASE(HttpReliableRequest_Make,HttpFixture)370 FIXTURE_TEST_CASE(HttpReliableRequest_Make, HttpFixture)
371 {
372 KNSManagerMakeReliableClientRequest ( m_mgr, &m_req, 0x01010000, & m_stream, MakeURL(GetName()).c_str() );
373 REQUIRE_NOT_NULL ( m_req ) ;
374 }
375
FIXTURE_TEST_CASE(HttpReliableRequest_POST_5xx_retry,HttpFixture)376 FIXTURE_TEST_CASE(HttpReliableRequest_POST_5xx_retry, HttpFixture)
377 { // use default configuration for 5xx to be retried
378 KNSManagerMakeReliableClientRequest ( m_mgr, &m_req, 0x01010000, & m_stream, MakeURL(GetName()).c_str() );
379
380 TestStream::AddResponse("HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n"); // response to GET
381 TestStream::AddResponse("HTTP/1.1 200 OK\r\n");
382
383 KClientHttpResult *rslt;
384 REQUIRE_RC ( KClientHttpRequestPOST ( m_req, & rslt ) );
385
386 REQUIRE_RC ( KClientHttpResultRelease ( rslt ) );
387 }
388
389 /* VDB-3059: KHttpRequestPOST generates incorrect Content-Length after retry :
390 it makes web server to return 400 Bad Request */
FIXTURE_TEST_CASE(HttpReliableRequest_ContentLength,HttpFixture)391 FIXTURE_TEST_CASE(HttpReliableRequest_ContentLength, HttpFixture)
392 {
393 /* calling good cgi returns 200 and resolved path */
394 REQUIRE_RC ( KNSManagerMakeReliableClientRequest ( m_mgr, &m_req, 0x01010000, NULL,
395 "https://trace.ncbi.nlm.nih.gov/Traces/names/names.fcgi" ) );
396 REQUIRE_RC ( KHttpRequestAddPostParam ( m_req, "acc=AAAB01" ) );
397 REQUIRE_RC ( KHttpRequestAddPostParam ( m_req, "accept-proto=https" ) );
398 REQUIRE_RC ( KHttpRequestAddPostParam ( m_req, "version=1.2" ) );
399
400 KHttpResult * rslt;
401 REQUIRE_RC ( KHttpRequestPOST ( m_req, & rslt ) );
402 uint32_t code = 0;
403 REQUIRE_RC ( KClientHttpResultStatus ( rslt, & code, NULL, 0, NULL ) );
404 REQUIRE_EQ ( code, 200u );
405
406 KStream * response;
407 REQUIRE_RC ( KHttpResultGetInputStream ( rslt, & response ) );
408 char buffer [ 512 ] = "";
409 size_t num_read = 0;
410 REQUIRE_RC (KStreamRead( response, buffer, sizeof buffer - 1, &num_read ));
411 REQUIRE_LT ( num_read, sizeof buffer );
412 buffer [ num_read ] = '\0';
413 REQUIRE_EQ ( string ( buffer + num_read - 7 ), string ( "200|ok\n" ) );
414 REQUIRE_RC ( KStreamRelease ( response ) );
415
416 REQUIRE_RC ( KHttpResultRelease( rslt ) );
417 }
418
FIXTURE_TEST_CASE(HttpReliableRequest_BadCgi,HttpFixture)419 FIXTURE_TEST_CASE(HttpReliableRequest_BadCgi, HttpFixture)
420 {
421 /* calling non-existing cgi returns 404 */
422 REQUIRE_RC ( KNSManagerMakeReliableClientRequest ( m_mgr, & m_req, 0x01000000,
423 NULL, "https://trace.ncbi.nlm.nih.gov/Traces/names/bad.cgi" ) );
424 REQUIRE_RC ( KHttpRequestAddPostParam ( m_req, "acc=AAAB01" ) );
425
426 KHttpResult * rslt;
427 REQUIRE_RC ( KHttpRequestPOST ( m_req, & rslt ) );
428 uint32_t code = 0;
429 REQUIRE_RC ( KClientHttpResultStatus ( rslt, & code, NULL, 0, NULL ) );
430 REQUIRE_EQ ( code, 404u );
431 REQUIRE_RC ( KHttpResultRelease( rslt ) );
432 }
433 #endif
434
TEST_CASE(Test_urlEncodePluses)435 TEST_CASE(Test_urlEncodePluses) {
436 REQUIRE_RC(KClientHttpRequestUrlEncodeBase64(NULL));
437
438 const String * encoding = NULL;
439 REQUIRE_RC(KClientHttpRequestUrlEncodeBase64(&encoding));
440
441 encoding = (String*) calloc(1, sizeof *encoding);
442 REQUIRE_RC(KClientHttpRequestUrlEncodeBase64(&encoding));
443 free((void*)encoding);
444
445 String s, d;
446
447 CONST_STRING(&s, "");
448 StringCopy(&encoding, &s);
449 REQUIRE_RC(KClientHttpRequestUrlEncodeBase64(&encoding));
450 REQUIRE_EQ(StringCompare(encoding, &s), 0);
451 StringWhack(encoding);
452
453 CONST_STRING(&s, "a");
454 StringCopy(&encoding, &s);
455 REQUIRE_RC(KClientHttpRequestUrlEncodeBase64(&encoding));
456 REQUIRE_EQ(StringCompare(encoding, &s), 0);
457 StringWhack(encoding);
458
459 CONST_STRING(&s, "+/");
460 StringCopy(&encoding, &s);
461 REQUIRE_RC(KClientHttpRequestUrlEncodeBase64(&encoding));
462 CONST_STRING(&d, "%2b%2f");
463 REQUIRE_EQ(StringCompare(encoding, &d), 0);
464 StringWhack(encoding);
465 }
466
467 //////////////////////////////////////////// Main
468
argsHandler(int argc,char * argv[])469 static rc_t argsHandler ( int argc, char * argv [] ) {
470 Args * args = NULL;
471 rc_t rc = ArgsMakeAndHandle ( & args, argc, argv, 0, NULL, 0 );
472 ArgsWhack ( args );
473 return rc;
474 }
475
476 extern "C"
477 {
478
479 #include <kapp/args.h>
480 #include <kfg/config.h>
481 #include <klib/debug.h>
482
KAppVersion(void)483 ver_t CC KAppVersion ( void )
484 {
485 return 0x1000000;
486 }
UsageSummary(const char * progname)487 rc_t CC UsageSummary (const char * progname)
488 {
489 return 0;
490 }
491
Usage(const Args * args)492 rc_t CC Usage ( const Args * args )
493 {
494 return 0;
495 }
496 const char UsageDefaultName[] = "test-http";
497
KMain(int argc,char * argv[])498 rc_t CC KMain ( int argc, char *argv [] )
499 {
500 KConfig * kfg = NULL;
501 rc_t rc = KConfigMake(&kfg, NULL);
502
503 if (rc == 0) // needed to use ceRequired on cloud
504 rc = KConfig_Set_Report_Cloud_Instance_Identity(kfg, true);
505
506 if ( 0 ) assert ( ! KDbgSetString ( "KNS" ) );
507 if ( 0 ) assert ( ! KDbgSetString ( "VFS" ) );
508
509 KConfigDisableUserSettings();
510
511 // this makes messages from the test code appear
512 // (same as running the executable with "-l=message")
513 // TestEnv::verbosity = LogLevel::e_message;
514
515 if (rc == 0)
516 rc = HttpRequestVerifyURLSuite(argc, argv);
517
518 rc_t r2 = KConfigRelease(kfg);
519 if (rc == 0 && r2 != 0)
520 rc = r2;
521
522 return rc;
523 }
524
525 }
526