Browse code

c-rest-engine - Adding upstream version as changes as patch to version 1.0.3

Change-Id: Ida55663d8f63dbce1f5cd0dc73e3d6b2c55abf16
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/3613
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Kumar Kaushik <kaushikk@vmware.com>

Kumar Kaushik authored on 2017/08/23 09:37:47
Showing 2 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 Name:          c-rest-engine
2 2
 Summary:       minimal http(s) server library
3 3
 Version:       1.0.3
4
-Release:       1%{?dist}
4
+Release:       2%{?dist}
5 5
 Group:         Applications/System
6 6
 Vendor:        VMware, Inc.
7 7
 License:       Apache 2.0
... ...
@@ -13,6 +13,7 @@ BuildRequires: coreutils >= 8.22
13 13
 BuildRequires: openssl-devel >= 1.0.1
14 14
 Source0:       %{name}-%{version}.tar.gz
15 15
 %define sha1   c-rest-engine=b4ad447d34e44f989eef18d924d5d1a8c3a4b528
16
+Patch0:        version-1.0.4-changes.patch
16 17
 
17 18
 %description
18 19
 c-rest-engine is a minimal embedded http(s) server written in C.
... ...
@@ -30,6 +31,7 @@ development libs and header files for c-rest-engine
30 30
 
31 31
 %prep
32 32
 %setup -q
33
+%patch0 -p1
33 34
 
34 35
 %build
35 36
 cd build
... ...
@@ -62,6 +64,8 @@ find %{buildroot} -name '*.la' -delete
62 62
 # %doc ChangeLog README COPYING
63 63
 
64 64
 %changelog
65
+*  Tue Aug 22 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.3-2
66
+-  Upstream version 1.0.4 patch for 1.0.3.
65 67
 *  Fri Jul 21 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.3-1
66 68
 -  Updating version to 1.0.3, API for setting SSL info.
67 69
 *  Tue Jun 20 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.2-1
68 70
new file mode 100644
... ...
@@ -0,0 +1,2819 @@
0
+diff -ru c-rest-engine-1.0.3/build/package/rpm/c-rest-engine.spec c-rest-engine-1.0.4/build/package/rpm/c-rest-engine.spec
1
+--- c-rest-engine-1.0.3/build/package/rpm/c-rest-engine.spec	2017-07-20 19:57:03.000000000 -0700
2
+@@ -1,7 +1,7 @@
3
+ Name:          c-rest-engine
4
+ Summary:       Minimal http(s) server library
5
+-Version:       1.0.2
6
+-Release:       2%{?dist}
7
++Version:       1.0.3
8
++Release:       5%{?dist}
9
+ Group:         Applications/System
10
+ Vendor:        VMware, Inc.
11
+ License:       Apache 2.0
12
+@@ -65,11 +65,19 @@
13
+ %{_lib64dir}/*.so
14
+ 
15
+ %changelog
16
++*   Thu Aug 17 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.3-5
17
++-   Adding new and cleaner parsing for all packets.
18
++*   Mon Aug 14 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.3-4
19
++-   Fixing bug # 1938177
20
++*   Fri Aug 11 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.3-3
21
++-   Fixing all known coverity bugs.
22
++*   Fri Aug 04 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.3-2
23
++-   Applying security fixes for set SSL info.
24
+ *   Thu Jul 20 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.2-2
25
+ -   Providing API for set SSL info, Bug#1864924
26
+ *   Mon Jun 19 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.2-1
27
+ -   Updating to version 1.0.2
28
+-*   Thu Jun 16 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.1-4
29
++*   Fri Jun 16 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.1-4
30
+ -   Relaxing maximum URI length.
31
+ *   Thu Jun 08 2017 Kumar Kaushik <kaushikk@vmware.com> 1.0.1-3
32
+ -   Fixing file upload.
33
+diff -ru c-rest-engine-1.0.3/common/logging.c c-rest-engine-1.0.4/common/logging.c
34
+--- c-rest-engine-1.0.3/common/logging.c	2017-07-20 19:57:03.000000000 -0700
35
+@@ -56,8 +56,8 @@
36
+     if (pRESTHandle && pRESTHandle->logFile != NULL)
37
+     {
38
+        fclose(pRESTHandle->logFile);
39
++       pRESTHandle->logFile = NULL;
40
+     }
41
+-    pRESTHandle->logFile = NULL;
42
+ }
43
+ 
44
+ void
45
+diff -ru c-rest-engine-1.0.3/common/sockinterface.c c-rest-engine-1.0.4/common/sockinterface.c
46
+--- c-rest-engine-1.0.3/common/sockinterface.c	2017-07-20 19:57:03.000000000 -0700
47
+@@ -1,908 +1,919 @@
48
+-/* C-REST-Engine
49
+-*
50
+-* Copyright (c) 2017 VMware, Inc. All Rights Reserved. 
51
+-*
52
+-* This product is licensed to you under the Apache 2.0 license (the "License").
53
+-* You may not use this product except in compliance with the Apache 2.0 License.  
54
+-*
55
+-* This product may include a number of subcomponents with separate copyright 
56
+-* notices and license terms. Your use of these subcomponents is subject to the 
57
+-* terms and conditions of the subcomponent's license, as noted in the LICENSE file. 
58
+-*
59
+-*/
60
+-
61
+-#include "includes.h"
62
+-
63
+-static
64
+-VOID
65
+-VmRESTSockContextFree(
66
+-    PVMREST_HANDLE                   pRESTHandle,
67
+-    PVMREST_SOCK_CONTEXT             pSockInterface
68
+-    );
69
+-
70
+-static
71
+-DWORD
72
+-VmRESTHandleSocketEvent(
73
+-    PVMREST_HANDLE                   pRESTHandle,
74
+-    PVM_SOCKET                       pSocket,
75
+-    VM_SOCK_EVENT_TYPE               sockEvent,
76
+-    PVM_SOCK_IO_BUFFER               pIoBuffer,
77
+-    DWORD                            dwError
78
+-    );
79
+-
80
+-static
81
+-DWORD
82
+-VmRESTOnNewConnection(
83
+-    PVMREST_HANDLE                   pRESTHandle,
84
+-    PVM_SOCKET                       pSocket,
85
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
86
+-    );
87
+-
88
+-static
89
+-VOID
90
+-VmRESTOnDisconnect(
91
+-    PVMREST_HANDLE                   pRESTHandle,
92
+-    PVM_SOCKET                       pSocket,
93
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
94
+-    );
95
+-
96
+-static
97
+-DWORD
98
+-VmRESTOnDataAvailable(
99
+-    PVMREST_HANDLE                   pRESTHandle,
100
+-    PVM_SOCKET                       pSocket,
101
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
102
+-    );
103
+-
104
+-static
105
+-PVOID
106
+-VmRESTSockWorkerThreadProc(
107
+-    PVOID                            pData
108
+-    );
109
+-
110
+-static
111
+-DWORD
112
+-VmRESTTcpReceiveNewData(
113
+-    PVMREST_HANDLE                   pRESTHandle,
114
+-    PVM_SOCKET                       pSocket
115
+-    );
116
+-
117
+-static
118
+-DWORD
119
+-VmRESTReceiveData(
120
+-    PVMREST_HANDLE                   pRESTHandle,
121
+-    PVM_SOCKET                       pSocket,
122
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
123
+-    );
124
+-
125
+-static
126
+-DWORD
127
+-VmRESTTcpReceiveData(
128
+-    PVMREST_HANDLE                   pRESTHandle,
129
+-    PVM_SOCKET                       pSocket,
130
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
131
+-    );
132
+-
133
+-static
134
+-DWORD
135
+-VmRESTDisconnectClient(
136
+-    PVMREST_HANDLE                   pRESTHandle,
137
+-    PVM_SOCKET                       pSocket
138
+-    );
139
+-
140
+-static
141
+-PVOID
142
+-VmRESTSockWorkerThreadProc(
143
+-    PVOID                            pData
144
+-    );
145
+-
146
+-DWORD
147
+-VmRESTInitProtocolServer(
148
+-    PVMREST_HANDLE                   pRESTHandle
149
+-    )
150
+-{
151
+-    DWORD                            dwError = REST_ENGINE_SUCCESS;
152
+-    PVMREST_SOCK_CONTEXT             pSockContext = NULL;
153
+-    DWORD                            dwFlags = VM_SOCK_CREATE_FLAGS_REUSE_ADDR |
154
+-                                               VM_SOCK_CREATE_FLAGS_NON_BLOCK;
155
+-    DWORD                            iThr = 0;
156
+-    char                             lastPortChar = '\0';
157
+-    char*                            sslCert = NULL;
158
+-    char*                            sslKey = NULL;
159
+-    char*                            temp = NULL;
160
+-    PVM_WORKER_THREAD_DATA           pThreadData = NULL;
161
+-
162
+-    if (! pRESTHandle || !( pRESTHandle->pRESTConfig))
163
+-    {
164
+-        VMREST_LOG_ERROR(pRESTHandle,"%s","Invalid REST config");
165
+-        dwError = REST_ERROR_INVALID_HANDLER;
166
+-    }
167
+-    BAIL_ON_VMREST_ERROR(dwError);
168
+-
169
+-    pSockContext =  pRESTHandle->pSockContext;
170
+-
171
+-    dwError = VmRESTAllocateMutex(&pSockContext->pMutex);
172
+-    BAIL_ON_VMREST_ERROR(dwError);
173
+-
174
+-    /**** Init SSL if configured ****/
175
+-    if (( pRESTHandle->pRESTConfig->server_port != NULL) && (strlen( pRESTHandle->pRESTConfig->server_port) == 0))
176
+-    {
177
+-        VMREST_LOG_ERROR(pRESTHandle,"%s","REST Engine config server port missing");
178
+-        dwError = 111;  /** Fix this **/
179
+-    }
180
+-    BAIL_ON_VMREST_ERROR(dwError);
181
+-
182
+-    lastPortChar = VmRESTUtilsGetLastChar(
183
+-                        pRESTHandle->pRESTConfig->server_port
184
+-                       );
185
+-
186
+-    if (lastPortChar == 'p' || lastPortChar == 'P')
187
+-    {
188
+-        VMREST_LOG_DEBUG(pRESTHandle,"%s","Server initing in plain text wire connection mode");
189
+-        temp =  pRESTHandle->pRESTConfig->server_port;
190
+-        while(temp != NULL)
191
+-        {
192
+-            if (*temp == 'p' || *temp == 'P')
193
+-            {
194
+-                *temp = '\0';
195
+-                break;
196
+-            }
197
+-            temp++;
198
+-        }
199
+-    }
200
+-    else
201
+-    {
202
+-        VMREST_LOG_DEBUG(pRESTHandle,"%s","Server initing in encrypted wire connection mode");
203
+-        if (strlen( pRESTHandle->pRESTConfig->ssl_certificate) == 0 || strlen( pRESTHandle->pRESTConfig->ssl_key) == 0)
204
+-        {
205
+-            VMREST_LOG_ERROR(pRESTHandle,"%s", "Invalid SSL params");
206
+-            dwError =  112; /** Fix this **/
207
+-        }
208
+-        BAIL_ON_VMREST_ERROR(dwError);
209
+-        dwFlags = dwFlags | VM_SOCK_IS_SSL;
210
+-        sslCert =  pRESTHandle->pRESTConfig->ssl_certificate;
211
+-        sslKey =   pRESTHandle->pRESTConfig->ssl_key;
212
+-    }
213
+-
214
+-    /**** Handle IPv4 case ****/
215
+-
216
+-    dwError = VmwSockOpenServer(
217
+-                         pRESTHandle,
218
+-                        ((unsigned short)atoi( pRESTHandle->pRESTConfig->server_port)),
219
+-                        ((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count)),
220
+-                        dwFlags | VM_SOCK_CREATE_FLAGS_TCP |
221
+-                                  VM_SOCK_CREATE_FLAGS_IPV4,
222
+-                        &pSockContext->pListenerTCP,
223
+-                        sslCert,
224
+-                        sslKey
225
+-                        );
226
+-    BAIL_ON_VMREST_ERROR(dwError);
227
+-
228
+-#ifdef AF_INET6
229
+-    /**** Handle IPv6 case ****/
230
+-
231
+-    dwError = VmwSockOpenServer(
232
+-                   pRESTHandle,
233
+-                  ((unsigned short)atoi( pRESTHandle->pRESTConfig->server_port)),
234
+-                  ((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count)),
235
+-                  dwFlags | VM_SOCK_CREATE_FLAGS_TCP |
236
+-                          VM_SOCK_CREATE_FLAGS_IPV6,
237
+-                  &pSockContext->pListenerTCP6,
238
+-                  sslCert,
239
+-                  sslKey
240
+-                  );
241
+-    BAIL_ON_VMREST_ERROR(dwError);
242
+-#endif
243
+-
244
+-    dwError = VmwSockCreateEventQueue(
245
+-                   pRESTHandle,
246
+-                  -1, 
247
+-                  &pSockContext->pEventQueue
248
+-                  );
249
+-    BAIL_ON_VMREST_ERROR(dwError);
250
+-
251
+-    dwError = VmwSockEventQueueAdd(
252
+-                   pRESTHandle,
253
+-                  pSockContext->pEventQueue,
254
+-                  pSockContext->pListenerTCP
255
+-                  );
256
+-    BAIL_ON_VMREST_ERROR(dwError);
257
+-
258
+-#ifdef AF_INET6
259
+-    dwError = VmwSockEventQueueAdd(
260
+-                   pRESTHandle,
261
+-                  pSockContext->pEventQueue,
262
+-                  pSockContext->pListenerTCP6
263
+-                  );
264
+-    BAIL_ON_VMREST_ERROR(dwError);
265
+-#endif
266
+-
267
+-    dwError = VmRESTAllocateMemory(
268
+-                  sizeof(PVMREST_THREAD) * (((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count))) ,
269
+-                  (PVOID*)&pSockContext->pWorkerThreads
270
+-                  );
271
+-    BAIL_ON_VMREST_ERROR(dwError);
272
+-
273
+-    pSockContext->dwNumThreads = ((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count));
274
+-
275
+-    for (; iThr < pSockContext->dwNumThreads; iThr++)
276
+-    {
277
+-        dwError = VmRESTAllocateMemory(
278
+-                  sizeof(VM_WORKER_THREAD_DATA) ,
279
+-                  (PVOID*)&pThreadData
280
+-                  );
281
+-        BAIL_ON_VMREST_ERROR(dwError);
282
+-        pThreadData->pSockContext = pSockContext;
283
+-        pThreadData-> pRESTHandle =  pRESTHandle;
284
+-
285
+-        dwError = VmRESTAllocateMemory(
286
+-                      sizeof(VMREST_THREAD),
287
+-                      (void **)&pSockContext->pWorkerThreads[iThr]
288
+-                      );
289
+-        BAIL_ON_VMREST_ERROR(dwError);
290
+-
291
+-        dwError = VmRESTCreateThread(
292
+-                      pSockContext->pWorkerThreads[iThr],
293
+-                      TRUE,
294
+-                      (PVMREST_START_ROUTINE)&VmRESTSockWorkerThreadProc,
295
+-                      pThreadData
296
+-                      );
297
+-        BAIL_ON_VMREST_ERROR(dwError);
298
+-
299
+-        pThreadData = NULL;
300
+-    }
301
+-
302
+-     pRESTHandle->pSockContext = pSockContext;
303
+-
304
+-cleanup:
305
+-
306
+-    return dwError;
307
+-
308
+-error:
309
+-
310
+-    goto cleanup;
311
+-}
312
+-
313
+-VOID
314
+-VmRESTShutdownProtocolServer(
315
+-    PVMREST_HANDLE                   pRESTHandle
316
+-    )
317
+-{
318
+-    if (pRESTHandle && pRESTHandle->pSockContext)
319
+-    {
320
+-         VmRESTSockContextFree( pRESTHandle,  pRESTHandle->pSockContext);
321
+-    }
322
+-}
323
+-
324
+-static
325
+-PVOID
326
+-VmRESTSockWorkerThreadProc(
327
+-    PVOID                            pData
328
+-    )
329
+-{
330
+-    DWORD                            dwError = 0;
331
+-    PVM_WORKER_THREAD_DATA           pWorkerData = (PVM_WORKER_THREAD_DATA)pData;
332
+-    PVMREST_HANDLE                   pRESTHandle = pWorkerData-> pRESTHandle;
333
+-    PVMREST_SOCK_CONTEXT             pSockContext = pWorkerData->pSockContext;
334
+-    PVM_SOCKET                       pSocket = NULL;
335
+-    PVM_SOCK_IO_BUFFER               pIoBuffer = NULL;
336
+-
337
+-    if (pWorkerData != NULL)
338
+-    {
339
+-        VmRESTFreeMemory(pWorkerData);
340
+-        pWorkerData = NULL;
341
+-    }
342
+-
343
+-    for(;;)
344
+-    {
345
+-        VM_SOCK_EVENT_TYPE eventType = VM_SOCK_EVENT_TYPE_UNKNOWN;
346
+-
347
+-        dwError = VmwSockWaitForEvent(
348
+-                         pRESTHandle,
349
+-                        pSockContext->pEventQueue,
350
+-                        -1,
351
+-                        &pSocket,
352
+-                        &eventType,
353
+-                        &pIoBuffer);
354
+-
355
+-        if (dwError == ERROR_SHUTDOWN_IN_PROGRESS)
356
+-        {
357
+-            break;
358
+-        }
359
+-        dwError = VmRESTHandleSocketEvent(
360
+-                         pRESTHandle,
361
+-                        pSocket,
362
+-                        eventType,
363
+-                        pIoBuffer,
364
+-                        dwError);
365
+-
366
+-        if (dwError == ERROR_SUCCESS ||
367
+-            dwError == ERROR_IO_PENDING)
368
+-        { 
369
+-            dwError = ERROR_SUCCESS;
370
+-        }
371
+-        else
372
+-        {
373
+-            pSocket = NULL;
374
+-            pIoBuffer = NULL;
375
+-            dwError = 0;
376
+-        }
377
+-        BAIL_ON_VMREST_ERROR(dwError);
378
+-   
379
+-    }
380
+-error:
381
+-#ifndef WIN32
382
+-    if (pSocket)
383
+-    {
384
+-        VmwSockRelease( pRESTHandle, pSocket);
385
+-    }
386
+-#endif
387
+-
388
+-    return NULL;
389
+-}
390
+-
391
+-
392
+-
393
+-static
394
+-DWORD
395
+-VmRESTHandleSocketEvent(
396
+-    PVMREST_HANDLE                   pRESTHandle,
397
+-    PVM_SOCKET                       pSocket,
398
+-    VM_SOCK_EVENT_TYPE               sockEvent,
399
+-    PVM_SOCK_IO_BUFFER               pIoBuffer,
400
+-    DWORD                            dwError
401
+-    )
402
+-{
403
+-    if (dwError == ERROR_SUCCESS)
404
+-    {
405
+-        switch (sockEvent)
406
+-        {
407
+-        case VM_SOCK_EVENT_TYPE_TCP_NEW_CONNECTION:
408
+-
409
+-            dwError = VmRESTOnNewConnection( pRESTHandle, pSocket, pIoBuffer);
410
+-            BAIL_ON_VMREST_ERROR(dwError);
411
+-            break;
412
+-#ifndef WIN32
413
+-        case VM_SOCK_EVENT_TYPE_DATA_AVAILABLE:
414
+-            dwError = VmRESTOnDataAvailable( pRESTHandle,pSocket, pIoBuffer);
415
+-            BAIL_ON_VMREST_ERROR(dwError);
416
+-            break;
417
+-
418
+-        case VM_SOCK_EVENT_TYPE_CONNECTION_CLOSED:
419
+-            VmRESTOnDisconnect( pRESTHandle, pSocket, pIoBuffer);
420
+-            break;
421
+-
422
+-        case VM_SOCK_EVENT_TYPE_UNKNOWN:
423
+-             dwError = ERROR_INVALID_STATE;
424
+-             break;
425
+-
426
+-        default:
427
+-            dwError = ERROR_INVALID_MESSAGE;
428
+-            break;
429
+-#endif
430
+-        }
431
+-    }
432
+-
433
+-cleanup:
434
+-
435
+-    return dwError;
436
+-
437
+-error :
438
+-    goto cleanup;
439
+-}
440
+-
441
+-static
442
+-DWORD
443
+-VmRESTOnNewConnection(
444
+-    PVMREST_HANDLE                   pRESTHandle,
445
+-    PVM_SOCKET                       pSocket,
446
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
447
+-    )
448
+-{
449
+-    DWORD                            dwError = REST_ENGINE_SUCCESS;
450
+-    if (!pSocket)
451
+-    {
452
+-        dwError = ERROR_INVALID_PARAMETER;
453
+-        BAIL_ON_VMREST_ERROR(dwError);
454
+-    }
455
+-
456
+-#ifdef WIN32
457
+-    dwError = VmRESTTcpReceiveNewData( pRESTHandle, pSocket);
458
+-    BAIL_ON_VMREST_ERROR(dwError);
459
+-#endif
460
+-cleanup:
461
+-
462
+-    return dwError;
463
+-
464
+-error:
465
+-
466
+-    goto cleanup;
467
+-}
468
+-
469
+-static
470
+-VOID
471
+-VmRESTOnDisconnect(
472
+-    PVMREST_HANDLE                   pRESTHandle,
473
+-    PVM_SOCKET                       pSocket,
474
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
475
+-    )
476
+-{
477
+-    if (pSocket)
478
+-    {
479
+-        VmwSockClose( pRESTHandle, pSocket);
480
+-    }
481
+-
482
+-    if (pIoBuffer)
483
+-    {
484
+-        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
485
+-    }
486
+-}
487
+-
488
+-static
489
+-DWORD
490
+-VmRESTOnDataAvailable(
491
+-    PVMREST_HANDLE                   pRESTHandle,
492
+-    PVM_SOCKET                       pSocket,
493
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
494
+-    )
495
+-{
496
+-    DWORD dwError = REST_ENGINE_SUCCESS;
497
+-
498
+-    if (!pSocket)
499
+-    {
500
+-        dwError = ERROR_INVALID_PARAMETER;
501
+-        BAIL_ON_VMREST_ERROR(dwError);
502
+-    }
503
+-
504
+-    dwError = VmRESTReceiveData( pRESTHandle,pSocket, pIoBuffer);
505
+-    BAIL_ON_VMREST_ERROR(dwError);
506
+-
507
+-cleanup:
508
+-    if (pIoBuffer)
509
+-    {
510
+-        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
511
+-    }
512
+-
513
+-    return dwError;
514
+-
515
+-error:
516
+-
517
+-    goto cleanup;
518
+-}
519
+-
520
+-static
521
+-DWORD
522
+-VmRESTReceiveData(
523
+-    PVMREST_HANDLE                   pRESTHandle,
524
+-    PVM_SOCKET                       pSocket,
525
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
526
+-    )
527
+-{
528
+-    DWORD                            dwError = REST_ENGINE_SUCCESS;
529
+-
530
+-    if (!pSocket)
531
+-    {
532
+-        dwError = ERROR_INVALID_PARAMETER;
533
+-        BAIL_ON_VMREST_ERROR(dwError);
534
+-    }
535
+-
536
+-    dwError = VmRESTTcpReceiveData( pRESTHandle,pSocket, pIoBuffer);
537
+-    BAIL_ON_VMREST_ERROR(dwError);
538
+-
539
+-cleanup:
540
+-    if (pIoBuffer)
541
+-    {
542
+-        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
543
+-    }
544
+-
545
+-    return dwError;
546
+-
547
+-error:
548
+-
549
+-    goto cleanup;
550
+-
551
+-}
552
+-
553
+-static
554
+-DWORD
555
+-VmRESTTcpReceiveData(
556
+-    PVMREST_HANDLE                   pRESTHandle,
557
+-    PVM_SOCKET                       pSocket,
558
+-    PVM_SOCK_IO_BUFFER               pIoBuffer
559
+-    )
560
+-{
561
+-    DWORD                            dwError = REST_ENGINE_SUCCESS;
562
+-
563
+-    if (!pSocket)
564
+-    {
565
+-        dwError = ERROR_INVALID_PARAMETER;
566
+-        BAIL_ON_VMREST_ERROR(dwError);
567
+-    }
568
+-
569
+-    if (!pIoBuffer)
570
+-    {
571
+-        dwError = VmRESTTcpReceiveNewData( pRESTHandle,pSocket);
572
+-        BAIL_ON_VMREST_ERROR(dwError);
573
+-    }
574
+-
575
+-cleanup:
576
+-    if (pIoBuffer)
577
+-    {
578
+-        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
579
+-    }
580
+-
581
+-    return dwError;
582
+-
583
+-error:
584
+-
585
+-    goto cleanup;
586
+-}
587
+-
588
+-static
589
+-DWORD
590
+-VmRESTTcpReceiveNewData(
591
+-    PVMREST_HANDLE                   pRESTHandle,
592
+-    PVM_SOCKET                       pSocket
593
+-    )
594
+-{
595
+-    DWORD                            dwError = REST_ENGINE_SUCCESS;
596
+-    char                             appBuffer[MAX_DATA_BUFFER_LEN] = {0};
597
+-    uint32_t                         bytesRead = 0;
598
+-
599
+-    dwError = VmsockPosixGetXBytes(
600
+-                   pRESTHandle,
601
+-                  MAX_DATA_BUFFER_LEN,
602
+-                  appBuffer,
603
+-                  pSocket,
604
+-                  &bytesRead,
605
+-                  0
606
+-                  );
607
+-     BAIL_ON_VMREST_ERROR(dwError);
608
+-
609
+-
610
+-     if (bytesRead > 0)
611
+-     {
612
+-         VMREST_LOG_DEBUG(pRESTHandle,"%s","Starting HTTP Parsing.");
613
+-         dwError = VmRESTProcessIncomingData(
614
+-                        pRESTHandle,
615
+-                       appBuffer,
616
+-                       bytesRead,
617
+-                       pSocket
618
+-                       );
619
+-         BAIL_ON_VMREST_ERROR(dwError);
620
+-     }
621
+-
622
+-
623
+-cleanup:
624
+-    VMREST_LOG_DEBUG(pRESTHandle,"%s","Calling closed connection....");
625
+-    VmRESTDisconnectClient( pRESTHandle, pSocket);
626
+-
627
+-    return dwError;
628
+-
629
+-error:
630
+-
631
+-    goto cleanup;
632
+-}
633
+-
634
+-static
635
+-VOID
636
+-VmRESTSockContextFree(
637
+-    PVMREST_HANDLE                   pRESTHandle,
638
+-    PVMREST_SOCK_CONTEXT             pSockContext
639
+-    )
640
+-{
641
+-    if (pSockContext->pEventQueue)
642
+-    {
643
+-        VmwSockCloseEventQueue( pRESTHandle, pSockContext->pEventQueue);
644
+-    }
645
+-    if (pSockContext->pListenerTCP)
646
+-    {
647
+-        VmwSockRelease( pRESTHandle, pSockContext->pListenerTCP);
648
+-    }
649
+-    if (pSockContext->pListenerTCP6)
650
+-    {
651
+-        VmwSockRelease( pRESTHandle, pSockContext->pListenerTCP6);
652
+-    }
653
+-    if (pSockContext->pWorkerThreads)
654
+-    {
655
+-        DWORD iThr = 0;
656
+-
657
+-        for (; iThr < pSockContext->dwNumThreads; iThr++)
658
+-        {
659
+-            PVMREST_THREAD pThread = pSockContext->pWorkerThreads[iThr];
660
+-
661
+-            if (pThread)
662
+-            {
663
+-                VmRESTFreeThread(pThread);
664
+-            }
665
+-        }
666
+-
667
+-        VmRESTFreeMemory(pSockContext->pWorkerThreads);
668
+-    }
669
+-    if (pSockContext->pMutex)
670
+-    {
671
+-        VmRESTFreeMutex(pSockContext->pMutex);
672
+-    }
673
+-}
674
+-
675
+-static
676
+-DWORD
677
+-VmRESTDisconnectClient(
678
+-    PVMREST_HANDLE                   pRESTHandle,
679
+-    PVM_SOCKET                       pSocket
680
+-    )
681
+-{
682
+-    DWORD                            dwError = REST_ENGINE_SUCCESS;
683
+-
684
+-    if (!pSocket)
685
+-    {
686
+-        dwError = ERROR_INVALID_PARAMETER;
687
+-        BAIL_ON_VMREST_ERROR(dwError);
688
+-    }
689
+-
690
+-    VmwSockClose( pRESTHandle, pSocket);
691
+-    VmwSockRelease( pRESTHandle, pSocket);
692
+-
693
+-cleanup:
694
+-
695
+-    return dwError;
696
+-
697
+-error:
698
+-
699
+-    goto cleanup;
700
+-}
701
+-
702
+-uint32_t
703
+-VmsockPosixGetXBytes(
704
+-    PVMREST_HANDLE                   pRESTHandle,
705
+-    uint32_t                         bytesRequested,
706
+-    char*                            appBuffer,
707
+-    PVM_SOCKET                       pSocket,
708
+-    uint32_t*                        bytesRead,
709
+-    uint8_t                          shouldBlock
710
+-    )
711
+-{
712
+-    uint32_t                         dwError = REST_ENGINE_SUCCESS;
713
+-    uint32_t                         dataIndex = 0;
714
+-    uint32_t                         remainingBytes = 0;
715
+-    uint32_t                         dataAvailableInCache = 0;
716
+-    PVM_SOCK_IO_BUFFER               pIoBuffer = NULL;
717
+-    PVM_STREAM_BUFFER                pStreamBuffer = NULL;
718
+-
719
+-    if (bytesRequested > MAX_DATA_BUFFER_LEN || appBuffer == NULL || bytesRead == NULL)
720
+-    {
721
+-       VMREST_LOG_DEBUG(pRESTHandle,"%s","Bytes to be read %u Large or appBuffer: %s",
722
+-                         bytesRequested, appBuffer);
723
+-        dwError = VMREST_TRANSPORT_INVALID_PARAM;
724
+-    }
725
+-    BAIL_ON_VMREST_ERROR(dwError);
726
+-
727
+-    if (sizeof(appBuffer) > MAX_DATA_BUFFER_LEN)
728
+-    {
729
+-        VMREST_LOG_DEBUG(pRESTHandle,"%s","ERROR: Application buffer size too large");
730
+-        dwError = VMREST_TRANSPORT_INVALID_PARAM;
731
+-    }
732
+-    BAIL_ON_VMREST_ERROR(dwError);
733
+-
734
+-    VmwSockGetStreamBuffer( pRESTHandle, pSocket, &pStreamBuffer);
735
+-
736
+-    if (!pStreamBuffer)
737
+-    {
738
+-        dwError = 500;
739
+-    }
740
+-    BAIL_ON_VMREST_ERROR(dwError);
741
+-
742
+-    dataIndex = pStreamBuffer->dataProcessed;
743
+-
744
+-    dataAvailableInCache = pStreamBuffer->dataRead - pStreamBuffer->dataProcessed;
745
+-
746
+-    if (dataAvailableInCache >= bytesRequested)
747
+-    {
748
+-        /**** Enough data available in stream cache buffer ****/
749
+-        memcpy(appBuffer,
750
+-               &(pStreamBuffer->pData[dataIndex]),
751
+-               bytesRequested
752
+-               );
753
+-        pStreamBuffer->dataProcessed += bytesRequested;
754
+-        *bytesRead = bytesRequested;
755
+-    }
756
+-    else if(dataAvailableInCache < bytesRequested)
757
+-    {
758
+-        /**** Copy all remaining client Stream bytes and perform read ****/
759
+-        if (dataAvailableInCache > 0)
760
+-        {
761
+-            memcpy(appBuffer,
762
+-                   &(pStreamBuffer->pData[dataIndex]),
763
+-                   dataAvailableInCache
764
+-                   );
765
+-            pStreamBuffer->dataProcessed += dataAvailableInCache;
766
+-            /**** This will be overwritten in case of success ****/
767
+-            *bytesRead = dataAvailableInCache;
768
+-        }
769
+-
770
+-        dwError = VmwSockAllocateIoBuffer(
771
+-                         pRESTHandle,
772
+-                        VM_SOCK_EVENT_TYPE_TCP_REQUEST_DATA_READ,
773
+-                        MAX_DATA_BUFFER_LEN,
774
+-                        &pIoBuffer
775
+-                        );
776
+-        BAIL_ON_VMREST_ERROR(dwError);
777
+-        dwError = VmwSockRead(
778
+-                             pRESTHandle,
779
+-                            pSocket,
780
+-                            pIoBuffer);
781
+-	//VMREST_LOG_DEBUG(pRESTHandle,"SockRead(), dwError = %u, dataRead %u", dwError, pIoBuffer->dwBytesTransferred);
782
+-        if (dwError == ERROR_SUCCESS)
783
+-        {
784
+-            memset(pStreamBuffer->pData, '\0', MAX_DATA_BUFFER_LEN);
785
+-            memcpy(pStreamBuffer->pData, pIoBuffer->pData,pIoBuffer->dwBytesTransferred);
786
+-			pStreamBuffer->dataProcessed = 0;
787
+-			pStreamBuffer->dataRead = pIoBuffer->dwBytesTransferred;
788
+-			BAIL_ON_VMREST_ERROR(dwError);
789
+-        }
790
+-        else if (dwError == ERROR_IO_PENDING)
791
+-        {
792
+-            // fail for linux?
793
+-#ifndef WIN32
794
+-            pIoBuffer = NULL;
795
+-#endif 
796
+-        }
797
+-        else
798
+-        {
799
+-            BAIL_ON_VMREST_ERROR(dwError);
800
+-        }
801
+-
802
+-        remainingBytes = bytesRequested - dataAvailableInCache;
803
+-        dataIndex = 0;
804
+-
805
+-        if (remainingBytes > pStreamBuffer->dataRead)
806
+-        {
807
+-            remainingBytes = pStreamBuffer->dataRead;
808
+-            VMREST_LOG_DEBUG(pRESTHandle,"WARNING: Requested %u bytes, available only %u bytes", bytesRequested,(dataAvailableInCache + remainingBytes));
809
+-        }
810
+-
811
+-        memcpy((appBuffer + dataAvailableInCache),
812
+-              &(pStreamBuffer->pData[dataIndex]),
813
+-              remainingBytes);
814
+-        pStreamBuffer->dataProcessed = remainingBytes;
815
+-        *bytesRead = dataAvailableInCache + remainingBytes;
816
+-
817
+-        //VMREST_LOG_DEBUG(pRESTHandle,"dataAvailableInCache %u, remainingBytes %u, appBuffersize %u", dataAvailableInCache, remainingBytes, strlen(appBuffer));
818
+-    }
819
+-
820
+-    VmwSockSetStreamBuffer( pRESTHandle, pSocket, pStreamBuffer);
821
+-
822
+-cleanup:
823
+-    if (pIoBuffer)
824
+-    {
825
+-        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
826
+-    }
827
+-
828
+-    return dwError;
829
+-
830
+-error:
831
+-
832
+-    goto cleanup;
833
+-
834
+-}
835
+-
836
+-uint32_t
837
+-VmSockPosixAdjustProcessedBytes(
838
+-    PVMREST_HANDLE                   pRESTHandle,
839
+-    PVM_SOCKET                       pSocket,
840
+-    uint32_t                         dataSeen
841
+-)
842
+-{
843
+-    uint32_t                         dwError = REST_ENGINE_SUCCESS;
844
+-    PVM_STREAM_BUFFER                pStreamBuffer = NULL;
845
+-
846
+-    if (dataSeen > MAX_DATA_BUFFER_LEN)
847
+-    {
848
+-       VMREST_LOG_DEBUG(pRESTHandle,"%s","Invalid new Processed Data Index %u", dataSeen);
849
+-        dwError = VMREST_TRANSPORT_INVALID_PARAM;
850
+-    }
851
+-    BAIL_ON_VMREST_ERROR(dwError);
852
+-
853
+-    VmwSockGetStreamBuffer( pRESTHandle, pSocket, &pStreamBuffer);
854
+-
855
+-    if (!pStreamBuffer)
856
+-    {
857
+-        dwError = 500;
858
+-    }
859
+-    BAIL_ON_VMREST_ERROR(dwError);
860
+-
861
+-    pStreamBuffer->dataProcessed = dataSeen;
862
+-
863
+-    VmwSockSetStreamBuffer( pRESTHandle, pSocket, pStreamBuffer);
864
+-
865
+-cleanup:
866
+-    return dwError;
867
+-error:
868
+-    goto cleanup;
869
+-}
870
+-
871
+-uint32_t
872
+-VmSockPosixDecrementProcessedBytes(
873
+-    PVMREST_HANDLE                   pRESTHandle,
874
+-    PVM_SOCKET                       pSocket,
875
+-    uint32_t                         offset
876
+-)
877
+-{
878
+-    uint32_t                         dwError = REST_ENGINE_SUCCESS;
879
+-    PVM_STREAM_BUFFER                pStreamBuffer = NULL;
880
+-
881
+-    if (offset > MAX_DATA_BUFFER_LEN)
882
+-    {
883
+-       VMREST_LOG_DEBUG(pRESTHandle,"%s","Invalid new Processed Data Index %u", offset);
884
+-        dwError = VMREST_TRANSPORT_INVALID_PARAM;
885
+-    }
886
+-    BAIL_ON_VMREST_ERROR(dwError);
887
+-
888
+-    VmwSockGetStreamBuffer( pRESTHandle, pSocket, &pStreamBuffer);
889
+-
890
+-    if (!pStreamBuffer)
891
+-    {
892
+-        dwError = 500;
893
+-    }
894
+-    BAIL_ON_VMREST_ERROR(dwError);
895
+-
896
+-    if (pStreamBuffer->dataProcessed >= offset)
897
+-    {
898
+-        pStreamBuffer->dataProcessed = pStreamBuffer->dataProcessed - offset;
899
+-    }
900
+-    VmwSockSetStreamBuffer( pRESTHandle, pSocket, pStreamBuffer);
901
+-
902
+-cleanup:
903
+-    return dwError;
904
+-error:
905
+-    goto cleanup;
906
+-}
907
+-
908
+-
909
+-uint32_t
910
+-VmsockPosixWriteDataAtOnce(
911
+-    PVMREST_HANDLE                   pRESTHandle,
912
+-    PVM_SOCKET                       pSocket,
913
+-    char*                            buffer,
914
+-    uint32_t                         bytes
915
+-    )
916
+-{
917
+-    uint32_t                         dwError = REST_ENGINE_SUCCESS;
918
+-    PVM_SOCK_IO_BUFFER               pIoNewBuffer = NULL;
919
+-    
920
+-    dwError = VmwSockAllocateIoBuffer(
921
+-                   pRESTHandle,
922
+-                  VM_SOCK_EVENT_TYPE_TCP_RESPONSE_DATA_WRITE,
923
+-                  bytes,
924
+-                  &pIoNewBuffer);
925
+-    BAIL_ON_VMREST_ERROR(dwError);
926
+-
927
+-    memcpy(pIoNewBuffer->pData, buffer, bytes);
928
+-
929
+-    dwError = VmwSockWrite(
930
+-                   pRESTHandle,
931
+-                  pSocket,
932
+-                  NULL,
933
+-                  0,
934
+-                  pIoNewBuffer
935
+-                  );
936
+-    if (dwError == ERROR_SUCCESS)
937
+-    {
938
+-        dwError = REST_ENGINE_SUCCESS;
939
+-        BAIL_ON_VMREST_ERROR(dwError);
940
+-    }
941
+-    else if (dwError == ERROR_IO_PENDING)
942
+-    {
943
+-        pIoNewBuffer = NULL;
944
+-        BAIL_ON_VMREST_ERROR(dwError);
945
+-    }
946
+-
947
+-cleanup:
948
+-    if (pIoNewBuffer)
949
+-    {
950
+-        VmwSockReleaseIoBuffer( pRESTHandle, pIoNewBuffer);
951
+-    }
952
+-    return dwError;
953
+-error:
954
+-    goto cleanup;
955
+-}
956
++/* C-REST-Engine
957
++*
958
++* Copyright (c) 2017 VMware, Inc. All Rights Reserved. 
959
++*
960
++* This product is licensed to you under the Apache 2.0 license (the "License").
961
++* You may not use this product except in compliance with the Apache 2.0 License.  
962
++*
963
++* This product may include a number of subcomponents with separate copyright 
964
++* notices and license terms. Your use of these subcomponents is subject to the 
965
++* terms and conditions of the subcomponent's license, as noted in the LICENSE file. 
966
++*
967
++*/
968
++
969
++#include "includes.h"
970
++
971
++static
972
++VOID
973
++VmRESTSockContextFree(
974
++    PVMREST_HANDLE                   pRESTHandle,
975
++    PVMREST_SOCK_CONTEXT             pSockInterface
976
++    );
977
++
978
++static
979
++DWORD
980
++VmRESTHandleSocketEvent(
981
++    PVMREST_HANDLE                   pRESTHandle,
982
++    PVM_SOCKET                       pSocket,
983
++    VM_SOCK_EVENT_TYPE               sockEvent,
984
++    PVM_SOCK_IO_BUFFER               pIoBuffer,
985
++    DWORD                            dwError
986
++    );
987
++
988
++static
989
++DWORD
990
++VmRESTOnNewConnection(
991
++    PVMREST_HANDLE                   pRESTHandle,
992
++    PVM_SOCKET                       pSocket,
993
++    PVM_SOCK_IO_BUFFER               pIoBuffer
994
++    );
995
++
996
++static
997
++VOID
998
++VmRESTOnDisconnect(
999
++    PVMREST_HANDLE                   pRESTHandle,
1000
++    PVM_SOCKET                       pSocket,
1001
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1002
++    );
1003
++
1004
++static
1005
++DWORD
1006
++VmRESTOnDataAvailable(
1007
++    PVMREST_HANDLE                   pRESTHandle,
1008
++    PVM_SOCKET                       pSocket,
1009
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1010
++    );
1011
++
1012
++static
1013
++PVOID
1014
++VmRESTSockWorkerThreadProc(
1015
++    PVOID                            pData
1016
++    );
1017
++
1018
++static
1019
++DWORD
1020
++VmRESTTcpReceiveNewData(
1021
++    PVMREST_HANDLE                   pRESTHandle,
1022
++    PVM_SOCKET                       pSocket
1023
++    );
1024
++
1025
++static
1026
++DWORD
1027
++VmRESTReceiveData(
1028
++    PVMREST_HANDLE                   pRESTHandle,
1029
++    PVM_SOCKET                       pSocket,
1030
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1031
++    );
1032
++
1033
++static
1034
++DWORD
1035
++VmRESTTcpReceiveData(
1036
++    PVMREST_HANDLE                   pRESTHandle,
1037
++    PVM_SOCKET                       pSocket,
1038
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1039
++    );
1040
++
1041
++static
1042
++DWORD
1043
++VmRESTDisconnectClient(
1044
++    PVMREST_HANDLE                   pRESTHandle,
1045
++    PVM_SOCKET                       pSocket
1046
++    );
1047
++
1048
++static
1049
++PVOID
1050
++VmRESTSockWorkerThreadProc(
1051
++    PVOID                            pData
1052
++    );
1053
++
1054
++DWORD
1055
++VmRESTInitProtocolServer(
1056
++    PVMREST_HANDLE                   pRESTHandle
1057
++    )
1058
++{
1059
++    DWORD                            dwError = REST_ENGINE_SUCCESS;
1060
++    PVMREST_SOCK_CONTEXT             pSockContext = NULL;
1061
++    DWORD                            dwFlags = VM_SOCK_CREATE_FLAGS_REUSE_ADDR |
1062
++                                               VM_SOCK_CREATE_FLAGS_NON_BLOCK;
1063
++    DWORD                            iThr = 0;
1064
++    char                             lastPortChar = '\0';
1065
++    char*                            sslCert = NULL;
1066
++    char*                            sslKey = NULL;
1067
++    char*                            temp = NULL;
1068
++    PVM_WORKER_THREAD_DATA           pThreadData = NULL;
1069
++
1070
++    if (! pRESTHandle || !( pRESTHandle->pRESTConfig))
1071
++    {
1072
++        VMREST_LOG_ERROR(pRESTHandle,"%s","Invalid REST config");
1073
++        dwError = REST_ERROR_INVALID_HANDLER;
1074
++    }
1075
++    BAIL_ON_VMREST_ERROR(dwError);
1076
++
1077
++    pSockContext =  pRESTHandle->pSockContext;
1078
++
1079
++    dwError = VmRESTAllocateMutex(&pSockContext->pMutex);
1080
++    BAIL_ON_VMREST_ERROR(dwError);
1081
++
1082
++    /**** Init SSL if configured ****/
1083
++    if (strlen( pRESTHandle->pRESTConfig->server_port) == 0)
1084
++    {
1085
++        VMREST_LOG_ERROR(pRESTHandle,"%s","REST Engine config server port missing");
1086
++        dwError = REST_ERROR_INVALID_CONFIG_PORT;
1087
++    }
1088
++    BAIL_ON_VMREST_ERROR(dwError);
1089
++
1090
++    lastPortChar = VmRESTUtilsGetLastChar(
1091
++                        pRESTHandle->pRESTConfig->server_port
1092
++                       );
1093
++
1094
++    if (lastPortChar == 'p' || lastPortChar == 'P')
1095
++    {
1096
++        VMREST_LOG_DEBUG(pRESTHandle,"%s","Server initing in plain text wire connection mode");
1097
++        temp =  pRESTHandle->pRESTConfig->server_port;
1098
++        while(temp != NULL)
1099
++        {
1100
++            if (*temp == 'p' || *temp == 'P')
1101
++            {
1102
++                *temp = '\0';
1103
++                break;
1104
++            }
1105
++            temp++;
1106
++        }
1107
++    }
1108
++    else
1109
++    {
1110
++        VMREST_LOG_DEBUG(pRESTHandle,"%s","Server initing in encrypted wire connection mode");
1111
++        if (strlen( pRESTHandle->pRESTConfig->ssl_certificate) == 0 || strlen( pRESTHandle->pRESTConfig->ssl_key) == 0)
1112
++        {
1113
++            VMREST_LOG_ERROR(pRESTHandle,"%s", "Invalid SSL params");
1114
++            dwError =  REST_ERROR_INVALID_CONFIG;
1115
++        }
1116
++        BAIL_ON_VMREST_ERROR(dwError);
1117
++        dwFlags = dwFlags | VM_SOCK_IS_SSL;
1118
++        sslCert =  pRESTHandle->pRESTConfig->ssl_certificate;
1119
++        sslKey =   pRESTHandle->pRESTConfig->ssl_key;
1120
++    }
1121
++
1122
++    /**** Handle IPv4 case ****/
1123
++
1124
++    dwError = VmwSockOpenServer(
1125
++                         pRESTHandle,
1126
++                        ((unsigned short)atoi( pRESTHandle->pRESTConfig->server_port)),
1127
++                        ((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count)),
1128
++                        dwFlags | VM_SOCK_CREATE_FLAGS_TCP |
1129
++                                  VM_SOCK_CREATE_FLAGS_IPV4,
1130
++                        &pSockContext->pListenerTCP,
1131
++                        sslCert,
1132
++                        sslKey
1133
++                        );
1134
++    BAIL_ON_VMREST_ERROR(dwError);
1135
++
1136
++#ifdef AF_INET6
1137
++    /**** Handle IPv6 case ****/
1138
++
1139
++    dwError = VmwSockOpenServer(
1140
++                   pRESTHandle,
1141
++                  ((unsigned short)atoi( pRESTHandle->pRESTConfig->server_port)),
1142
++                  ((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count)),
1143
++                  dwFlags | VM_SOCK_CREATE_FLAGS_TCP |
1144
++                          VM_SOCK_CREATE_FLAGS_IPV6,
1145
++                  &pSockContext->pListenerTCP6,
1146
++                  sslCert,
1147
++                  sslKey
1148
++                  );
1149
++    BAIL_ON_VMREST_ERROR(dwError);
1150
++#endif
1151
++
1152
++    dwError = VmwSockCreateEventQueue(
1153
++                   pRESTHandle,
1154
++                  -1,
1155
++                  &pSockContext->pEventQueue
1156
++                  );
1157
++    BAIL_ON_VMREST_ERROR(dwError);
1158
++
1159
++    dwError = VmwSockEventQueueAdd(
1160
++                   pRESTHandle,
1161
++                  pSockContext->pEventQueue,
1162
++                  pSockContext->pListenerTCP
1163
++                  );
1164
++    BAIL_ON_VMREST_ERROR(dwError);
1165
++
1166
++#ifdef AF_INET6
1167
++    dwError = VmwSockEventQueueAdd(
1168
++                   pRESTHandle,
1169
++                  pSockContext->pEventQueue,
1170
++                  pSockContext->pListenerTCP6
1171
++                  );
1172
++    BAIL_ON_VMREST_ERROR(dwError);
1173
++#endif
1174
++
1175
++    dwError = VmRESTAllocateMemory(
1176
++                  sizeof(PVMREST_THREAD) * (((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count))) ,
1177
++                  (PVOID*)&pSockContext->pWorkerThreads
1178
++                  );
1179
++    BAIL_ON_VMREST_ERROR(dwError);
1180
++
1181
++    pSockContext->dwNumThreads = ((int)atoi( pRESTHandle->pRESTConfig->worker_thread_count));
1182
++
1183
++    for (; iThr < pSockContext->dwNumThreads; iThr++)
1184
++    {
1185
++        dwError = VmRESTAllocateMemory(
1186
++                  sizeof(VM_WORKER_THREAD_DATA) ,
1187
++                  (PVOID*)&pThreadData
1188
++                  );
1189
++        BAIL_ON_VMREST_ERROR(dwError);
1190
++        pThreadData->pSockContext = pSockContext;
1191
++        pThreadData-> pRESTHandle =  pRESTHandle;
1192
++
1193
++        dwError = VmRESTAllocateMemory(
1194
++                      sizeof(VMREST_THREAD),
1195
++                      (void **)&pSockContext->pWorkerThreads[iThr]
1196
++                      );
1197
++        BAIL_ON_VMREST_ERROR(dwError);
1198
++
1199
++        dwError = VmRESTCreateThread(
1200
++                      pSockContext->pWorkerThreads[iThr],
1201
++                      TRUE,
1202
++                      (PVMREST_START_ROUTINE)&VmRESTSockWorkerThreadProc,
1203
++                      pThreadData
1204
++                      );
1205
++        BAIL_ON_VMREST_ERROR(dwError);
1206
++
1207
++        pThreadData = NULL;
1208
++    }
1209
++
1210
++     pRESTHandle->pSockContext = pSockContext;
1211
++
1212
++cleanup:
1213
++
1214
++    return dwError;
1215
++
1216
++error:
1217
++    if (pThreadData != NULL)
1218
++    {
1219
++        VmRESTFreeMemory(pThreadData);
1220
++        pThreadData = NULL;
1221
++    }
1222
++
1223
++    goto cleanup;
1224
++}
1225
++
1226
++VOID
1227
++VmRESTShutdownProtocolServer(
1228
++    PVMREST_HANDLE                   pRESTHandle
1229
++    )
1230
++{
1231
++    if (pRESTHandle && pRESTHandle->pSockContext)
1232
++    {
1233
++         VmRESTSockContextFree( pRESTHandle,  pRESTHandle->pSockContext);
1234
++    }
1235
++}
1236
++
1237
++static
1238
++PVOID
1239
++VmRESTSockWorkerThreadProc(
1240
++    PVOID                            pData
1241
++    )
1242
++{
1243
++    DWORD                            dwError = 0;
1244
++    PVM_WORKER_THREAD_DATA           pWorkerData = (PVM_WORKER_THREAD_DATA)pData;
1245
++    PVMREST_HANDLE                   pRESTHandle = NULL;
1246
++    PVMREST_SOCK_CONTEXT             pSockContext = NULL;
1247
++    PVM_SOCKET                       pSocket = NULL;
1248
++    PVM_SOCK_IO_BUFFER               pIoBuffer = NULL;
1249
++
1250
++    if (pWorkerData != NULL)
1251
++    {
1252
++        pRESTHandle = pWorkerData-> pRESTHandle;
1253
++        pSockContext = pWorkerData->pSockContext;
1254
++        VmRESTFreeMemory(pWorkerData);
1255
++        pWorkerData = NULL;
1256
++    }
1257
++    else
1258
++    {
1259
++        return NULL;
1260
++    }
1261
++
1262
++    for(;;)
1263
++    {
1264
++        VM_SOCK_EVENT_TYPE eventType = VM_SOCK_EVENT_TYPE_UNKNOWN;
1265
++
1266
++        dwError = VmwSockWaitForEvent(
1267
++                        pRESTHandle,
1268
++                        pSockContext->pEventQueue,
1269
++                        -1,
1270
++                        &pSocket,
1271
++                        &eventType,
1272
++                        &pIoBuffer);
1273
++
1274
++        if (dwError == ERROR_SHUTDOWN_IN_PROGRESS)
1275
++        {
1276
++            break;
1277
++        }
1278
++        dwError = VmRESTHandleSocketEvent(
1279
++                         pRESTHandle,
1280
++                        pSocket,
1281
++                        eventType,
1282
++                        pIoBuffer,
1283
++                        dwError);
1284
++
1285
++        if (dwError == ERROR_SUCCESS ||
1286
++            dwError == ERROR_IO_PENDING)
1287
++        { 
1288
++            dwError = ERROR_SUCCESS;
1289
++        }
1290
++        else
1291
++        {
1292
++            pSocket = NULL;
1293
++            pIoBuffer = NULL;
1294
++            dwError = 0;
1295
++        }
1296
++        BAIL_ON_VMREST_ERROR(dwError);
1297
++   
1298
++    }
1299
++error:
1300
++#ifndef WIN32
1301
++    if (pSocket)
1302
++    {
1303
++        VmwSockRelease( pRESTHandle, pSocket);
1304
++    }
1305
++#endif
1306
++
1307
++    return NULL;
1308
++}
1309
++
1310
++
1311
++
1312
++static
1313
++DWORD
1314
++VmRESTHandleSocketEvent(
1315
++    PVMREST_HANDLE                   pRESTHandle,
1316
++    PVM_SOCKET                       pSocket,
1317
++    VM_SOCK_EVENT_TYPE               sockEvent,
1318
++    PVM_SOCK_IO_BUFFER               pIoBuffer,
1319
++    DWORD                            dwError
1320
++    )
1321
++{
1322
++    if (dwError == ERROR_SUCCESS)
1323
++    {
1324
++        switch (sockEvent)
1325
++        {
1326
++        case VM_SOCK_EVENT_TYPE_TCP_NEW_CONNECTION:
1327
++
1328
++            dwError = VmRESTOnNewConnection( pRESTHandle, pSocket, pIoBuffer);
1329
++            BAIL_ON_VMREST_ERROR(dwError);
1330
++            break;
1331
++#ifndef WIN32
1332
++        case VM_SOCK_EVENT_TYPE_DATA_AVAILABLE:
1333
++            dwError = VmRESTOnDataAvailable( pRESTHandle,pSocket, pIoBuffer);
1334
++            BAIL_ON_VMREST_ERROR(dwError);
1335
++            break;
1336
++
1337
++        case VM_SOCK_EVENT_TYPE_CONNECTION_CLOSED:
1338
++            VmRESTOnDisconnect( pRESTHandle, pSocket, pIoBuffer);
1339
++            break;
1340
++
1341
++        case VM_SOCK_EVENT_TYPE_UNKNOWN:
1342
++             dwError = ERROR_INVALID_STATE;
1343
++             break;
1344
++
1345
++        default:
1346
++            dwError = ERROR_INVALID_MESSAGE;
1347
++            break;
1348
++#endif
1349
++        }
1350
++    }
1351
++
1352
++cleanup:
1353
++
1354
++    return dwError;
1355
++
1356
++error :
1357
++    goto cleanup;
1358
++}
1359
++
1360
++static
1361
++DWORD
1362
++VmRESTOnNewConnection(
1363
++    PVMREST_HANDLE                   pRESTHandle,
1364
++    PVM_SOCKET                       pSocket,
1365
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1366
++    )
1367
++{
1368
++    DWORD                            dwError = REST_ENGINE_SUCCESS;
1369
++    if (!pSocket)
1370
++    {
1371
++        dwError = ERROR_INVALID_PARAMETER;
1372
++        BAIL_ON_VMREST_ERROR(dwError);
1373
++    }
1374
++
1375
++#ifdef WIN32
1376
++    dwError = VmRESTTcpReceiveNewData( pRESTHandle, pSocket);
1377
++    BAIL_ON_VMREST_ERROR(dwError);
1378
++#endif
1379
++cleanup:
1380
++
1381
++    return dwError;
1382
++
1383
++error:
1384
++
1385
++    goto cleanup;
1386
++}
1387
++
1388
++static
1389
++VOID
1390
++VmRESTOnDisconnect(
1391
++    PVMREST_HANDLE                   pRESTHandle,
1392
++    PVM_SOCKET                       pSocket,
1393
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1394
++    )
1395
++{
1396
++    if (pSocket)
1397
++    {
1398
++        VmwSockClose( pRESTHandle, pSocket);
1399
++    }
1400
++
1401
++    if (pIoBuffer)
1402
++    {
1403
++        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
1404
++    }
1405
++}
1406
++
1407
++static
1408
++DWORD
1409
++VmRESTOnDataAvailable(
1410
++    PVMREST_HANDLE                   pRESTHandle,
1411
++    PVM_SOCKET                       pSocket,
1412
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1413
++    )
1414
++{
1415
++    DWORD dwError = REST_ENGINE_SUCCESS;
1416
++
1417
++    if (!pSocket)
1418
++    {
1419
++        dwError = ERROR_INVALID_PARAMETER;
1420
++        BAIL_ON_VMREST_ERROR(dwError);
1421
++    }
1422
++
1423
++    dwError = VmRESTReceiveData( pRESTHandle,pSocket, pIoBuffer);
1424
++    BAIL_ON_VMREST_ERROR(dwError);
1425
++
1426
++cleanup:
1427
++    if (pIoBuffer)
1428
++    {
1429
++        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
1430
++    }
1431
++
1432
++    return dwError;
1433
++
1434
++error:
1435
++
1436
++    goto cleanup;
1437
++}
1438
++
1439
++static
1440
++DWORD
1441
++VmRESTReceiveData(
1442
++    PVMREST_HANDLE                   pRESTHandle,
1443
++    PVM_SOCKET                       pSocket,
1444
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1445
++    )
1446
++{
1447
++    DWORD                            dwError = REST_ENGINE_SUCCESS;
1448
++
1449
++    if (!pSocket)
1450
++    {
1451
++        dwError = ERROR_INVALID_PARAMETER;
1452
++        BAIL_ON_VMREST_ERROR(dwError);
1453
++    }
1454
++
1455
++    dwError = VmRESTTcpReceiveData( pRESTHandle,pSocket, pIoBuffer);
1456
++    BAIL_ON_VMREST_ERROR(dwError);
1457
++
1458
++cleanup:
1459
++    if (pIoBuffer)
1460
++    {
1461
++        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
1462
++    }
1463
++
1464
++    return dwError;
1465
++
1466
++error:
1467
++
1468
++    goto cleanup;
1469
++
1470
++}
1471
++
1472
++static
1473
++DWORD
1474
++VmRESTTcpReceiveData(
1475
++    PVMREST_HANDLE                   pRESTHandle,
1476
++    PVM_SOCKET                       pSocket,
1477
++    PVM_SOCK_IO_BUFFER               pIoBuffer
1478
++    )
1479
++{
1480
++    DWORD                            dwError = REST_ENGINE_SUCCESS;
1481
++
1482
++    if (!pSocket)
1483
++    {
1484
++        dwError = ERROR_INVALID_PARAMETER;
1485
++        BAIL_ON_VMREST_ERROR(dwError);
1486
++    }
1487
++
1488
++    if (!pIoBuffer)
1489
++    {
1490
++        dwError = VmRESTTcpReceiveNewData( pRESTHandle,pSocket);
1491
++        BAIL_ON_VMREST_ERROR(dwError);
1492
++    }
1493
++
1494
++cleanup:
1495
++    if (pIoBuffer)
1496
++    {
1497
++        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
1498
++    }
1499
++
1500
++    return dwError;
1501
++
1502
++error:
1503
++
1504
++    goto cleanup;
1505
++}
1506
++
1507
++static
1508
++DWORD
1509
++VmRESTTcpReceiveNewData(
1510
++    PVMREST_HANDLE                   pRESTHandle,
1511
++    PVM_SOCKET                       pSocket
1512
++    )
1513
++{
1514
++    DWORD                            dwError = REST_ENGINE_SUCCESS;
1515
++    char                             appBuffer[MAX_DATA_BUFFER_LEN] = {0};
1516
++    uint32_t                         bytesRead = 0;
1517
++
1518
++    dwError = VmsockPosixGetXBytes(
1519
++                   pRESTHandle,
1520
++                  MAX_DATA_BUFFER_LEN,
1521
++                  appBuffer,
1522
++                  pSocket,
1523
++                  &bytesRead,
1524
++                  0
1525
++                  );
1526
++     BAIL_ON_VMREST_ERROR(dwError);
1527
++
1528
++
1529
++     if (bytesRead > 0)
1530
++     {
1531
++         VMREST_LOG_DEBUG(pRESTHandle,"%s","Starting HTTP Parsing.");
1532
++         dwError = VmRESTProcessIncomingData(
1533
++                        pRESTHandle,
1534
++                       appBuffer,
1535
++                       bytesRead,
1536
++                       pSocket
1537
++                       );
1538
++         BAIL_ON_VMREST_ERROR(dwError);
1539
++     }
1540
++
1541
++
1542
++cleanup:
1543
++    VMREST_LOG_DEBUG(pRESTHandle,"%s","Calling closed connection....");
1544
++    VmRESTDisconnectClient( pRESTHandle, pSocket);
1545
++
1546
++    return dwError;
1547
++
1548
++error:
1549
++
1550
++    goto cleanup;
1551
++}
1552
++
1553
++static
1554
++VOID
1555
++VmRESTSockContextFree(
1556
++    PVMREST_HANDLE                   pRESTHandle,
1557
++    PVMREST_SOCK_CONTEXT             pSockContext
1558
++    )
1559
++{
1560
++    if (pSockContext->pEventQueue)
1561
++    {
1562
++        VmwSockCloseEventQueue( pRESTHandle, pSockContext->pEventQueue);
1563
++    }
1564
++    if (pSockContext->pListenerTCP)
1565
++    {
1566
++        VmwSockRelease( pRESTHandle, pSockContext->pListenerTCP);
1567
++    }
1568
++    if (pSockContext->pListenerTCP6)
1569
++    {
1570
++        VmwSockRelease( pRESTHandle, pSockContext->pListenerTCP6);
1571
++    }
1572
++    if (pSockContext->pWorkerThreads)
1573
++    {
1574
++        DWORD iThr = 0;
1575
++
1576
++        for (; iThr < pSockContext->dwNumThreads; iThr++)
1577
++        {
1578
++            PVMREST_THREAD pThread = pSockContext->pWorkerThreads[iThr];
1579
++
1580
++            if (pThread)
1581
++            {
1582
++                VmRESTFreeThread(pThread);
1583
++            }
1584
++        }
1585
++
1586
++        VmRESTFreeMemory(pSockContext->pWorkerThreads);
1587
++    }
1588
++    if (pSockContext->pMutex)
1589
++    {
1590
++        VmRESTFreeMutex(pSockContext->pMutex);
1591
++    }
1592
++}
1593
++
1594
++static
1595
++DWORD
1596
++VmRESTDisconnectClient(
1597
++    PVMREST_HANDLE                   pRESTHandle,
1598
++    PVM_SOCKET                       pSocket
1599
++    )
1600
++{
1601
++    DWORD                            dwError = REST_ENGINE_SUCCESS;
1602
++
1603
++    if (!pSocket)
1604
++    {
1605
++        dwError = ERROR_INVALID_PARAMETER;
1606
++        BAIL_ON_VMREST_ERROR(dwError);
1607
++    }
1608
++
1609
++    VmwSockClose( pRESTHandle, pSocket);
1610
++    VmwSockRelease( pRESTHandle, pSocket);
1611
++
1612
++cleanup:
1613
++
1614
++    return dwError;
1615
++
1616
++error:
1617
++
1618
++    goto cleanup;
1619
++}
1620
++
1621
++uint32_t
1622
++VmsockPosixGetXBytes(
1623
++    PVMREST_HANDLE                   pRESTHandle,
1624
++    uint32_t                         bytesRequested,
1625
++    char*                            appBuffer,
1626
++    PVM_SOCKET                       pSocket,
1627
++    uint32_t*                        bytesRead,
1628
++    uint8_t                          shouldBlock
1629
++    )
1630
++{
1631
++    uint32_t                         dwError = REST_ENGINE_SUCCESS;
1632
++    uint32_t                         dataIndex = 0;
1633
++    uint32_t                         remainingBytes = 0;
1634
++    uint32_t                         dataAvailableInCache = 0;
1635
++    PVM_SOCK_IO_BUFFER               pIoBuffer = NULL;
1636
++    PVM_STREAM_BUFFER                pStreamBuffer = NULL;
1637
++
1638
++    if (bytesRequested > MAX_DATA_BUFFER_LEN || appBuffer == NULL || bytesRead == NULL)
1639
++    {
1640
++       VMREST_LOG_DEBUG(pRESTHandle,"%s","Bytes to be read %u Large or appBuffer: %s",
1641
++                         bytesRequested, appBuffer);
1642
++        dwError = VMREST_TRANSPORT_INVALID_PARAM;
1643
++    }
1644
++    BAIL_ON_VMREST_ERROR(dwError);
1645
++
1646
++    if (sizeof(appBuffer) > MAX_DATA_BUFFER_LEN)
1647
++    {
1648
++        VMREST_LOG_DEBUG(pRESTHandle,"%s","ERROR: Application buffer size too large");
1649
++        dwError = VMREST_TRANSPORT_INVALID_PARAM;
1650
++    }
1651
++    BAIL_ON_VMREST_ERROR(dwError);
1652
++
1653
++    VmwSockGetStreamBuffer( pRESTHandle, pSocket, &pStreamBuffer);
1654
++
1655
++    if (!pStreamBuffer)
1656
++    {
1657
++        dwError = 500;
1658
++    }
1659
++    BAIL_ON_VMREST_ERROR(dwError);
1660
++
1661
++    dataIndex = pStreamBuffer->dataProcessed;
1662
++
1663
++    dataAvailableInCache = pStreamBuffer->dataRead - pStreamBuffer->dataProcessed;
1664
++
1665
++    if (dataAvailableInCache >= bytesRequested)
1666
++    {
1667
++        /**** Enough data available in stream cache buffer ****/
1668
++        memcpy(appBuffer,
1669
++               &(pStreamBuffer->pData[dataIndex]),
1670
++               bytesRequested
1671
++               );
1672
++        pStreamBuffer->dataProcessed += bytesRequested;
1673
++        *bytesRead = bytesRequested;
1674
++    }
1675
++    else if(dataAvailableInCache < bytesRequested)
1676
++    {
1677
++        /**** Copy all remaining client Stream bytes and perform read ****/
1678
++        if (dataAvailableInCache > 0)
1679
++        {
1680
++            memcpy(appBuffer,
1681
++                   &(pStreamBuffer->pData[dataIndex]),
1682
++                   dataAvailableInCache
1683
++                   );
1684
++            pStreamBuffer->dataProcessed += dataAvailableInCache;
1685
++            /**** This will be overwritten in case of success ****/
1686
++            *bytesRead = dataAvailableInCache;
1687
++        }
1688
++
1689
++        dwError = VmwSockAllocateIoBuffer(
1690
++                         pRESTHandle,
1691
++                        VM_SOCK_EVENT_TYPE_TCP_REQUEST_DATA_READ,
1692
++                        MAX_DATA_BUFFER_LEN,
1693
++                        &pIoBuffer
1694
++                        );
1695
++        BAIL_ON_VMREST_ERROR(dwError);
1696
++        dwError = VmwSockRead(
1697
++                             pRESTHandle,
1698
++                            pSocket,
1699
++                            pIoBuffer);
1700
++	//VMREST_LOG_DEBUG(pRESTHandle,"SockRead(), dwError = %u, dataRead %u", dwError, pIoBuffer->dwBytesTransferred);
1701
++        if (dwError == ERROR_SUCCESS)
1702
++        {
1703
++            memset(pStreamBuffer->pData, '\0', MAX_DATA_BUFFER_LEN);
1704
++            memcpy(pStreamBuffer->pData, pIoBuffer->pData,pIoBuffer->dwBytesTransferred);
1705
++			pStreamBuffer->dataProcessed = 0;
1706
++			pStreamBuffer->dataRead = pIoBuffer->dwBytesTransferred;
1707
++			BAIL_ON_VMREST_ERROR(dwError);
1708
++        }
1709
++        else if (dwError == ERROR_IO_PENDING)
1710
++        {
1711
++            // fail for linux?
1712
++#ifndef WIN32
1713
++            pIoBuffer = NULL;
1714
++#endif 
1715
++        }
1716
++        else
1717
++        {
1718
++            BAIL_ON_VMREST_ERROR(dwError);
1719
++        }
1720
++
1721
++        remainingBytes = bytesRequested - dataAvailableInCache;
1722
++        dataIndex = 0;
1723
++
1724
++        if (remainingBytes > pStreamBuffer->dataRead)
1725
++        {
1726
++            remainingBytes = pStreamBuffer->dataRead;
1727
++            VMREST_LOG_DEBUG(pRESTHandle,"WARNING: Requested %u bytes, available only %u bytes", bytesRequested,(dataAvailableInCache + remainingBytes));
1728
++        }
1729
++
1730
++        memcpy((appBuffer + dataAvailableInCache),
1731
++              &(pStreamBuffer->pData[dataIndex]),
1732
++              remainingBytes);
1733
++        pStreamBuffer->dataProcessed = remainingBytes;
1734
++        *bytesRead = dataAvailableInCache + remainingBytes;
1735
++
1736
++        //VMREST_LOG_DEBUG(pRESTHandle,"dataAvailableInCache %u, remainingBytes %u, appBuffersize %u", dataAvailableInCache, remainingBytes, strlen(appBuffer));
1737
++    }
1738
++
1739
++    VmwSockSetStreamBuffer( pRESTHandle, pSocket, pStreamBuffer);
1740
++
1741
++cleanup:
1742
++    if (pIoBuffer)
1743
++    {
1744
++        VmwSockReleaseIoBuffer( pRESTHandle, pIoBuffer);
1745
++    }
1746
++
1747
++    return dwError;
1748
++
1749
++error:
1750
++
1751
++    goto cleanup;
1752
++
1753
++}
1754
++
1755
++uint32_t
1756
++VmSockPosixAdjustProcessedBytes(
1757
++    PVMREST_HANDLE                   pRESTHandle,
1758
++    PVM_SOCKET                       pSocket,
1759
++    uint32_t                         dataSeen
1760
++)
1761
++{
1762
++    uint32_t                         dwError = REST_ENGINE_SUCCESS;
1763
++    PVM_STREAM_BUFFER                pStreamBuffer = NULL;
1764
++
1765
++    if (dataSeen > MAX_DATA_BUFFER_LEN)
1766
++    {
1767
++       VMREST_LOG_DEBUG(pRESTHandle,"%s","Invalid new Processed Data Index %u", dataSeen);
1768
++        dwError = VMREST_TRANSPORT_INVALID_PARAM;
1769
++    }
1770
++    BAIL_ON_VMREST_ERROR(dwError);
1771
++
1772
++    VmwSockGetStreamBuffer( pRESTHandle, pSocket, &pStreamBuffer);
1773
++
1774
++    if (!pStreamBuffer)
1775
++    {
1776
++        dwError = 500;
1777
++    }
1778
++    BAIL_ON_VMREST_ERROR(dwError);
1779
++
1780
++    pStreamBuffer->dataProcessed = dataSeen;
1781
++
1782
++    VmwSockSetStreamBuffer( pRESTHandle, pSocket, pStreamBuffer);
1783
++
1784
++cleanup:
1785
++    return dwError;
1786
++error:
1787
++    goto cleanup;
1788
++}
1789
++
1790
++uint32_t
1791
++VmSockPosixDecrementProcessedBytes(
1792
++    PVMREST_HANDLE                   pRESTHandle,
1793
++    PVM_SOCKET                       pSocket,
1794
++    uint32_t                         offset
1795
++)
1796
++{
1797
++    uint32_t                         dwError = REST_ENGINE_SUCCESS;
1798
++    PVM_STREAM_BUFFER                pStreamBuffer = NULL;
1799
++
1800
++    if (offset > MAX_DATA_BUFFER_LEN)
1801
++    {
1802
++       VMREST_LOG_DEBUG(pRESTHandle,"%s","Invalid new Processed Data Index %u", offset);
1803
++        dwError = VMREST_TRANSPORT_INVALID_PARAM;
1804
++    }
1805
++    BAIL_ON_VMREST_ERROR(dwError);
1806
++
1807
++    VmwSockGetStreamBuffer( pRESTHandle, pSocket, &pStreamBuffer);
1808
++
1809
++    if (!pStreamBuffer)
1810
++    {
1811
++        dwError = 500;
1812
++    }
1813
++    BAIL_ON_VMREST_ERROR(dwError);
1814
++
1815
++    if (pStreamBuffer->dataProcessed >= offset)
1816
++    {
1817
++        pStreamBuffer->dataProcessed = pStreamBuffer->dataProcessed - offset;
1818
++    }
1819
++    VmwSockSetStreamBuffer( pRESTHandle, pSocket, pStreamBuffer);
1820
++
1821
++cleanup:
1822
++    return dwError;
1823
++error:
1824
++    goto cleanup;
1825
++}
1826
++
1827
++
1828
++uint32_t
1829
++VmsockPosixWriteDataAtOnce(
1830
++    PVMREST_HANDLE                   pRESTHandle,
1831
++    PVM_SOCKET                       pSocket,
1832
++    char*                            buffer,
1833
++    uint32_t                         bytes
1834
++    )
1835
++{
1836
++    uint32_t                         dwError = REST_ENGINE_SUCCESS;
1837
++    PVM_SOCK_IO_BUFFER               pIoNewBuffer = NULL;
1838
++    
1839
++    dwError = VmwSockAllocateIoBuffer(
1840
++                   pRESTHandle,
1841
++                  VM_SOCK_EVENT_TYPE_TCP_RESPONSE_DATA_WRITE,
1842
++                  bytes,
1843
++                  &pIoNewBuffer);
1844
++    BAIL_ON_VMREST_ERROR(dwError);
1845
++
1846
++    memcpy(pIoNewBuffer->pData, buffer, bytes);
1847
++
1848
++    dwError = VmwSockWrite(
1849
++                   pRESTHandle,
1850
++                  pSocket,
1851
++                  NULL,
1852
++                  0,
1853
++                  pIoNewBuffer
1854
++                  );
1855
++    if (dwError == ERROR_SUCCESS)
1856
++    {
1857
++        dwError = REST_ENGINE_SUCCESS;
1858
++        BAIL_ON_VMREST_ERROR(dwError);
1859
++    }
1860
++    else if (dwError == ERROR_IO_PENDING)
1861
++    {
1862
++        pIoNewBuffer = NULL;
1863
++        BAIL_ON_VMREST_ERROR(dwError);
1864
++    }
1865
++
1866
++cleanup:
1867
++    if (pIoNewBuffer)
1868
++    {
1869
++        VmwSockReleaseIoBuffer( pRESTHandle, pIoNewBuffer);
1870
++    }
1871
++    return dwError;
1872
++error:
1873
++    goto cleanup;
1874
++}
1875
+diff -ru c-rest-engine-1.0.3/include/public/vmrest.h c-rest-engine-1.0.4/include/public/vmrest.h
1876
+--- c-rest-engine-1.0.3/include/public/vmrest.h	2017-07-20 19:57:03.000000000 -0700
1877
+@@ -41,6 +41,7 @@
1878
+ #define     REST_ERROR_BAD_CONFIG_FILE_PATH                110
1879
+ #define     REST_ERROR_PREV_INSTANCE_NOT_CLEAN             111
1880
+ #define     REST_ERROR_INVALID_HANDLER                     112
1881
++#define     REST_ENGINE_SSL_CONFIG_FILE                    113
1882
+ #define     REST_ENGINE_MORE_IO_REQUIRED                   7001
1883
+ #define     REST_ENGINE_IO_COMPLETED                       0
1884
+ 
1885
+diff -ru c-rest-engine-1.0.3/server/restengine/defines.h c-rest-engine-1.0.4/server/restengine/defines.h
1886
+--- c-rest-engine-1.0.3/server/restengine/defines.h	2017-07-20 19:57:03.000000000 -0700
1887
+@@ -25,6 +25,7 @@
1888
+ #define HTTP_VER_LEN                8
1889
+ #define HTTP_CHUNKED_DATA_LEN       7
1890
+ #define HTTP_MIN_CHUNK_DATA_LEN     3
1891
++#define HTTP_CRLF_LEN               2
1892
+ 
1893
+ #define MAX_KEY_VAL_PARAM_LEN      1024
1894
+ #define MAX_URL_PARAMS_ARR_SIZE    5
1895
+diff -ru c-rest-engine-1.0.3/server/restengine/httpProtocolHead.c c-rest-engine-1.0.4/server/restengine/httpProtocolHead.c
1896
+--- c-rest-engine-1.0.3/server/restengine/httpProtocolHead.c	2017-07-20 19:57:03.000000000 -0700
1897
+@@ -234,7 +234,7 @@
1898
+ {
1899
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
1900
+     char*                            buffer = NULL;
1901
+-    char                             local[MAX_REQ_LIN_LEN] = {0};
1902
++    char*                            local = NULL;
1903
+     char                             attribute[MAX_HTTP_HEADER_ATTR_LEN] = {0};
1904
+     char                             value[MAX_HTTP_HEADER_VAL_LEN] = {0};
1905
+     char*                            temp = NULL;
1906
+@@ -242,6 +242,12 @@
1907
+     size_t                           attrLen = 0;
1908
+     size_t                           valLen  = 0;
1909
+ 
1910
++    dwError = VmRESTAllocateMemory(
1911
++                  MAX_REQ_LIN_LEN,
1912
++                  (void**)&local
1913
++                  );
1914
++    BAIL_ON_VMREST_ERROR(dwError);
1915
++
1916
+     buffer = line;
1917
+     temp = local;
1918
+ 
1919
+@@ -263,7 +269,7 @@
1920
+             *temp = '\0';
1921
+             strncpy(attribute,local,(MAX_HTTP_HEADER_ATTR_LEN - 1));
1922
+             attrLen = strlen(attribute);
1923
+-            memset(local,'\0', sizeof(local));
1924
++            memset(local,'\0', MAX_REQ_LIN_LEN);
1925
+             temp = local;
1926
+             continue;
1927
+         }
1928
+@@ -293,6 +299,12 @@
1929
+     BAIL_ON_VMREST_ERROR(dwError);
1930
+ 
1931
+ cleanup:
1932
++    if (local != NULL)
1933
++    {
1934
++        VmRESTFreeMemory(local);
1935
++        local = NULL;
1936
++    }
1937
++
1938
+     return dwError;
1939
+ error:
1940
+     goto cleanup;
1941
+@@ -310,7 +322,7 @@
1942
+ {
1943
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
1944
+     char                             method[MAX_METHOD_LEN] = {0};
1945
+-    char                             URI[MAX_URI_LEN]={0};
1946
++    char*                            URI = NULL;
1947
+     char                             version[MAX_VERSION_LEN] = {0};
1948
+ 
1949
+     if (!line  || !pReqPacket || (*resStatus != OK) || lineNo == 0)
1950
+@@ -320,6 +332,12 @@
1951
+     }
1952
+     BAIL_ON_VMREST_ERROR(dwError);
1953
+ 
1954
++    dwError = VmRESTAllocateMemory(
1955
++                  MAX_URI_LEN,
1956
++                  (PVOID*)&URI
1957
++                  );
1958
++    BAIL_ON_VMREST_ERROR(dwError);
1959
++
1960
+     if (lineLen > MAX_REQ_LIN_LEN)
1961
+     {
1962
+         dwError = REQUEST_URI_TOO_LARGE;
1963
+@@ -337,7 +355,7 @@
1964
+                       resStatus
1965
+                       );
1966
+         BAIL_ON_VMREST_ERROR(dwError);
1967
+-        strcpy(pReqPacket->requestLine->method, method);
1968
++        strncpy(pReqPacket->requestLine->method, method, (MAX_METHOD_LEN - 1));
1969
+ 
1970
+         dwError = VmRESTHTTPGetReqURI(
1971
+                       line,
1972
+@@ -346,7 +364,7 @@
1973
+                       resStatus
1974
+                       );
1975
+         BAIL_ON_VMREST_ERROR(dwError);
1976
+-        strcpy(pReqPacket->requestLine->uri, URI);
1977
++        strncpy(pReqPacket->requestLine->uri, URI, (MAX_URI_LEN - 1));
1978
+ 
1979
+         dwError = VmRESTHTTPGetReqVersion(
1980
+                       line,
1981
+@@ -355,7 +373,7 @@
1982
+                       resStatus
1983
+                       );
1984
+         BAIL_ON_VMREST_ERROR(dwError);
1985
+-        strcpy(pReqPacket->requestLine->version, version);
1986
++        strncpy(pReqPacket->requestLine->version, version, (MAX_VERSION_LEN - 1));
1987
+     }
1988
+     else
1989
+     {
1990
+@@ -370,6 +388,11 @@
1991
+     }
1992
+ 
1993
+ cleanup:
1994
++    if (URI != NULL)
1995
++    {
1996
++        VmRESTFreeMemory(URI);
1997
++        URI = NULL;
1998
++    }
1999
+     return dwError;
2000
+ error:
2001
+     goto cleanup;
2002
+@@ -384,123 +407,161 @@
2003
+     uint32_t*                        resStatus
2004
+     )
2005
+ {
2006
++    int                              nDataStart = 0;
2007
++    char                             sockBuffer[MAX_DATA_BUFFER_LEN]={0};
2008
++    char*                            local = NULL;
2009
++    char*                            pszStartNewLine = buffer;
2010
++    char*                            pszEndNewLine = NULL;
2011
++    char*                            newBuf = NULL;
2012
++    char*                            prevBuffer = NULL;
2013
++    char*                            prevBufferTemp = NULL;
2014
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
2015
+-    uint32_t                         bytesRead = 0;
2016
++    uint32_t                         nProcessed = 0;
2017
+     uint32_t                         lineNo = 0;
2018
+-    size_t                           lineLen = 0;
2019
+-    char                             local[MAX_REQ_LIN_LEN]={0};
2020
+-    char*                            temp = buffer;
2021
+-    char*                            line = local;
2022
+-    char                             appBuffer[MAX_DATA_BUFFER_LEN]={0};
2023
+-    uint32_t                         bytesReadInBuffer = 0;
2024
+-    uint32_t                         skipRead = 0;
2025
+-    uint32_t                         extraBytes = 0;
2026
++    uint32_t                         nPrevBuf = 0;
2027
++    uint32_t                         nLineLen = 0;
2028
++    uint32_t                         nBufLen = packetLen;
2029
++    uint32_t                         nEmptyPrevBuf = 0;
2030
++    uint32_t                         nSockReadRequest = 0;
2031
++    uint32_t                         nSockReadActual = 0;
2032
++
2033
+ 
2034
+-    if (!buffer || !pReqPacket || (*resStatus != OK) || (packetLen <= 4))
2035
++    if (!buffer || !pReqPacket || (*resStatus != OK))
2036
+     {
2037
+        VMREST_LOG_ERROR(pRESTHandle,"%s","Invalid params");
2038
+        dwError =  BAD_REQUEST;
2039
+        *resStatus = BAD_REQUEST;
2040
+     }
2041
+     BAIL_ON_VMREST_ERROR(dwError);
2042
+-    
2043
+-    while(1)
2044
+-    {
2045
+-        if (bytesRead >= (packetLen - 4))
2046
+-        {
2047
+ 
2048
+-            if (temp && (strcmp(temp,"\r\n\r\n") == 0))
2049
+-            {
2050
+-                skipRead = 1;
2051
+-            }
2052
+-            /**** More socket read required to process the headers ****/
2053
++    /**** Allocate all memory for buffers ****/
2054
++    dwError = VmRESTAllocateMemory(
2055
++                  MAX_REQ_LIN_LEN,
2056
++                  (PVOID*)&local
2057
++                  );
2058
++    BAIL_ON_VMREST_ERROR(dwError);
2059
++
2060
++    dwError = VmRESTAllocateMemory(
2061
++                  MAX_REQ_LIN_LEN,
2062
++                  (PVOID*)&prevBuffer
2063
++                  );
2064
++    BAIL_ON_VMREST_ERROR(dwError);
2065
++
2066
++    dwError = VmRESTAllocateMemory(
2067
++                  MAX_REQ_LIN_LEN,
2068
++                  (PVOID*)&prevBufferTemp
2069
++                  );
2070
++    BAIL_ON_VMREST_ERROR(dwError);
2071
+ 
2072
+-            if (!skipRead)
2073
++    while(pszStartNewLine != NULL)
2074
++    {
2075
++        pszEndNewLine = strstr(pszStartNewLine, "\r\n");
2076
++        if (pszEndNewLine != NULL)
2077
++        {
2078
++            nLineLen = pszEndNewLine - pszStartNewLine;
2079
++            VMREST_LOG_DEBUG(pRESTHandle,"Line length is: %u",nLineLen);
2080
++            if( nLineLen == 0 )
2081
+             {
2082
+-                extraBytes = packetLen - bytesRead;
2083
+-                dwError = VmSockPosixAdjustProcessedBytes(
2084
+-                              pRESTHandle,
2085
+-                              pReqPacket->pSocket,
2086
+-                              bytesRead
2087
+-                              );
2088
++                /**** This is the end of all HTTP headers ****/
2089
++                nDataStart = nProcessed - nPrevBuf + HTTP_CRLF_LEN;
2090
++                if ( nDataStart < 0 )
2091
++                {
2092
++                    VMREST_LOG_ERROR(pRESTHandle,"Bad request detected, Negative data start postion: %d", nDataStart);
2093
++                    dwError = BAD_REQUEST;
2094
++                }
2095
+                 BAIL_ON_VMREST_ERROR(dwError);
2096
+-                memset(appBuffer, '\0', MAX_DATA_BUFFER_LEN);
2097
+ 
2098
+-                dwError = VmsockPosixGetXBytes(
2099
++                dwError = VmSockPosixAdjustProcessedBytes(
2100
+                               pRESTHandle,
2101
+-                              MAX_DATA_BUFFER_LEN,
2102
+-                              appBuffer,
2103
+                               pReqPacket->pSocket,
2104
+-                              &bytesReadInBuffer,
2105
+-                              1
2106
++                              (uint32_t)nDataStart
2107
+                               );
2108
+                 BAIL_ON_VMREST_ERROR(dwError);
2109
+-                temp = appBuffer;
2110
+-                bytesRead = 0;
2111
+-                packetLen = bytesReadInBuffer;
2112
+-
2113
+-                if ((packetLen <= 4) && (strcmp(appBuffer, "\r\n\r\n") != 0))
2114
+-                {
2115
+-                    skipRead = 1;
2116
+-                    VMREST_LOG_ERROR(pRESTHandle,"%s","Bad HTTP request detected");
2117
+-                    dwError =  VMREST_HTTP_VALIDATION_FAILED;
2118
+-                    *resStatus = BAD_REQUEST;
2119
+-                }
2120
+-                BAIL_ON_VMREST_ERROR(dwError);
2121
++                VMREST_LOG_DEBUG(pRESTHandle,"Finished headers parsing with nProcessed %u", nProcessed);
2122
++                break;
2123
+             }
2124
+-        }
2125
+-        if((*temp == '\r') && (*(temp+1) == '\n'))
2126
+-        {
2127
++            strncpy(local, pszStartNewLine, nLineLen);
2128
+             lineNo++;
2129
+-            *line = '\0';
2130
+-            lineLen = strlen(local);
2131
+-            /* call handler function with reqLine */
2132
++
2133
++            /**** Found a new line, process it and store in HTTP request pcaket ****/
2134
+             dwError = VmRESTParseHTTPReqLine(
2135
+                           lineNo,
2136
+                           local,
2137
+-                          (uint32_t)lineLen,
2138
++                          nLineLen,
2139
+                           pReqPacket,
2140
+                           resStatus
2141
+                           );
2142
+             BAIL_ON_VMREST_ERROR(dwError);
2143
+-            bytesRead = bytesRead + 2;
2144
+-            if((*(temp+2) == '\r') && (*(temp+3) == '\n'))
2145
+-            {
2146
+-                bytesRead = bytesRead + 2;
2147
+-                VMREST_LOG_DEBUG(pRESTHandle,"Finished headers parsing with bytesRead %u", bytesRead);
2148
+-                /**** All headers processed : data starts from here ***/
2149
+-                dwError = VmSockPosixAdjustProcessedBytes(
2150
+-                              pRESTHandle,
2151
+-                              pReqPacket->pSocket,
2152
+-                              (bytesRead - extraBytes)
2153
+-                              );
2154
+-                BAIL_ON_VMREST_ERROR(dwError);
2155
+-                break;
2156
+-            }
2157
+-            temp = temp + 2;
2158
+             memset(local, '\0', MAX_REQ_LIN_LEN);
2159
+-            line = local;
2160
+-            continue;
2161
+-        }
2162
+-        if ((line - local) < MAX_REQ_LIN_LEN )
2163
+-        {
2164
+-            *line = *temp;
2165
+-            temp++;
2166
+-            line++;
2167
+-            bytesRead++;
2168
++            nProcessed = nProcessed + nLineLen + HTTP_CRLF_LEN;
2169
++            pszStartNewLine = pszEndNewLine + HTTP_CRLF_LEN;
2170
++            pszEndNewLine = NULL;
2171
+         }
2172
+-        else
2173
++        else /**** pszEndNewLine == NULL ****/
2174
+         {
2175
+-            dwError = REQUEST_HEADER_FIELD_TOO_LARGE;
2176
++            /**** more socket reads will be required to process the headers ****/
2177
++            nPrevBuf = nBufLen - nProcessed;
2178
++            if (nPrevBuf >= MAX_REQ_LIN_LEN)
2179
++            {
2180
++                dwError = REQUEST_URI_TOO_LARGE;
2181
++                VMREST_LOG_ERROR(pRESTHandle,"%s","Too large URI");
2182
++            }
2183
+             BAIL_ON_VMREST_ERROR(dwError);
2184
++
2185
++            if (nProcessed != 0)
2186
++            {
2187
++                /**** Last socket read had CRLF, so adjust the remaining bytes only ****/
2188
++                memset(prevBufferTemp, '\0', MAX_REQ_LIN_LEN);
2189
++                strncpy(prevBufferTemp, pszStartNewLine, nPrevBuf);
2190
++                pszStartNewLine  = prevBufferTemp;
2191
++                memset(prevBuffer, '\0', MAX_REQ_LIN_LEN);
2192
++            }
2193
++
2194
++            strncpy(prevBuffer, pszStartNewLine, nPrevBuf);
2195
++            VMREST_LOG_DEBUG(pRESTHandle,"Requesting read from socket layer, still processing headers .....");
2196
++            memset(sockBuffer, '\0', MAX_DATA_BUFFER_LEN);
2197
++
2198
++            nEmptyPrevBuf = MAX_REQ_LIN_LEN - nPrevBuf;
2199
++            nSockReadRequest = ((nEmptyPrevBuf > MAX_DATA_BUFFER_LEN) ? MAX_DATA_BUFFER_LEN : nEmptyPrevBuf);
2200
++
2201
++            dwError = VmsockPosixGetXBytes(
2202
++                          pRESTHandle,
2203
++                          nSockReadRequest,
2204
++                          sockBuffer,
2205
++                          pReqPacket->pSocket,
2206
++                          &nSockReadActual,
2207
++                          1
2208
++                          );
2209
++            BAIL_ON_VMREST_ERROR(dwError);
2210
++
2211
++            newBuf = strncat(prevBuffer, sockBuffer, nSockReadActual);
2212
++            pszStartNewLine = newBuf;
2213
++            nBufLen = nSockReadActual + nPrevBuf;
2214
++            nProcessed = 0;
2215
+         }
2216
+     }
2217
++
2218
+ cleanup:
2219
++    if (local != NULL)
2220
++    {
2221
++        VmRESTFreeMemory(local);
2222
++        local = NULL;
2223
++    }
2224
++    if (prevBuffer != NULL)
2225
++    {
2226
++        VmRESTFreeMemory(prevBuffer);
2227
++        prevBuffer = NULL;
2228
++    }
2229
++    if (prevBufferTemp != NULL)
2230
++    {
2231
++        VmRESTFreeMemory(prevBufferTemp);
2232
++        prevBufferTemp = NULL;
2233
++    }
2234
++
2235
+     return dwError;
2236
+ error:
2237
+     goto cleanup;
2238
+ }
2239
+-
2240
+ uint32_t
2241
+ VMRESTWriteChunkedMessageInResponseStream(
2242
+     char*                            src,
2243
+@@ -1087,8 +1148,8 @@
2244
+     char*                            transferEncoding = NULL;
2245
+     char*                            expect = NULL;
2246
+     uint32_t                         done = 0;
2247
+-    char                             httpURI[MAX_URI_LEN] = {0};
2248
+-    char                             endPointURI[MAX_URI_LEN] = {0};
2249
++    char*                            httpURI = NULL;
2250
++    char*                            endPointURI = NULL;
2251
+     char*                            ptr = NULL;
2252
+     PREST_ENDPOINT                   pEndPoint = NULL;
2253
+ 
2254
+@@ -1111,6 +1172,18 @@
2255
+                   );
2256
+     BAIL_ON_VMREST_ERROR(dwError);
2257
+ 
2258
++    dwError = VmRESTAllocateMemory(
2259
++                  MAX_URI_LEN,
2260
++                  (PVOID*)&httpURI
2261
++                  );
2262
++    BAIL_ON_VMREST_ERROR(dwError);
2263
++
2264
++    dwError = VmRESTAllocateMemory(
2265
++                  MAX_URI_LEN,
2266
++                  (PVOID*)&endPointURI
2267
++                  );
2268
++    BAIL_ON_VMREST_ERROR(dwError);
2269
++
2270
+     pReqPacket->miscHeader->head = NULL;
2271
+     pResPacket->miscHeader->head = NULL;
2272
+     pReqPacket->pSocket = pSocket;
2273
+@@ -1308,6 +1381,19 @@
2274
+         /**** Error response is already sent to client, return success ****/
2275
+         dwError = REST_ENGINE_SUCCESS;
2276
+     }
2277
++
2278
++    if (httpURI != NULL)
2279
++    {
2280
++        VmRESTFreeMemory(httpURI);
2281
++        httpURI = NULL;
2282
++    }
2283
++
2284
++    if (endPointURI != NULL)
2285
++    {
2286
++        VmRESTFreeMemory(endPointURI);
2287
++        endPointURI = NULL;
2288
++    }
2289
++
2290
+     return dwError;
2291
+ error:
2292
+     VMREST_LOG_ERROR(pRESTHandle,"Something failed, dwError = %u", dwError);
2293
+diff -ru c-rest-engine-1.0.3/server/restengine/httpUtilsInternal.c c-rest-engine-1.0.4/server/restengine/httpUtilsInternal.c
2294
+--- c-rest-engine-1.0.3/server/restengine/httpUtilsInternal.c	2017-07-20 19:57:03.000000000 -0700
2295
+@@ -484,7 +484,7 @@
2296
+     }
2297
+     BAIL_ON_VMREST_ERROR(dwError);
2298
+ 
2299
+-    strncpy(portNo, pRESTConfig->server_port,MAX_SERVER_PORT_LEN);
2300
++    strncpy(portNo, pRESTConfig->server_port,(MAX_SERVER_PORT_LEN -1));
2301
+ 
2302
+     lastPortChar = VmRESTUtilsGetLastChar(
2303
+                        pRESTConfig->server_port
2304
+diff -ru c-rest-engine-1.0.3/server/restengine/libmain.c c-rest-engine-1.0.4/server/restengine/libmain.c
2305
+--- c-rest-engine-1.0.3/server/restengine/libmain.c	2017-07-20 19:57:03.000000000 -0700
2306
+@@ -100,7 +100,7 @@
2307
+      uint32_t                         dwError = REST_ENGINE_SUCCESS;
2308
+      char                             fileName[MAX_PATH_LEN] = {0};
2309
+      FILE*                            fp = NULL;
2310
+-     int                              writtenBytes = 0;
2311
++     uint32_t                         writtenBytes = 0;
2312
+ 
2313
+     if (!pRESTHandle || !pDataBuffer || (bufferSize == 0) || (bufferSize > MAX_SSL_DATA_BUF_LEN) || (sslDataType < SSL_DATA_TYPE_KEY) || (sslDataType > SSL_DATA_TYPE_CERT))
2314
+     {
2315
+@@ -110,42 +110,42 @@
2316
+ 
2317
+     if (((pRESTHandle->pSSLInfo->isCertSet != SSL_INFO_NOT_SET) && (sslDataType == SSL_DATA_TYPE_CERT)))
2318
+     {
2319
+-        goto cleanup;
2320
++        dwError = REST_ENGINE_SSL_CONFIG_FILE;
2321
+     }
2322
++    BAIL_ON_VMREST_ERROR(dwError);
2323
+ 
2324
+     if (((pRESTHandle->pSSLInfo->isKeySet != SSL_INFO_NOT_SET) && (sslDataType == SSL_DATA_TYPE_KEY)))
2325
+     {
2326
+-        goto cleanup;
2327
++        dwError = REST_ENGINE_SSL_CONFIG_FILE;
2328
+     }
2329
+-    memset(fileName, '\0', MAX_PATH_LEN);
2330
++    BAIL_ON_VMREST_ERROR(dwError);
2331
+ 
2332
+     if (sslDataType == SSL_DATA_TYPE_KEY)
2333
+     {
2334
+-        sprintf(fileName, "%s%p.pem","/tmp/key-", pRESTHandle);
2335
++        snprintf(fileName, (MAX_PATH_LEN - 1),"%s%s.pem", "/tmp/key-port-", pRESTHandle->pRESTConfig->server_port);
2336
+ 
2337
+     }
2338
+     else if (sslDataType == SSL_DATA_TYPE_CERT)
2339
+     {
2340
+-        sprintf(fileName, "%s%p.pem","/tmp/cert-", pRESTHandle);
2341
++        snprintf(fileName, (MAX_PATH_LEN - 1), "%s%s.pem", "/tmp/cert-port-", pRESTHandle->pRESTConfig->server_port);
2342
+     }
2343
+ 
2344
+     fp = fopen(fileName, "w+");
2345
+-
2346
+     if (fp == NULL)
2347
+     {
2348
+         VMREST_LOG_ERROR(pRESTHandle,"Unable to Open SSL file %s", fileName);
2349
+         dwError = REST_ENGINE_FAILURE;
2350
+     }
2351
++    BAIL_ON_VMREST_ERROR(dwError);
2352
+ 
2353
+     writtenBytes = fwrite(pDataBuffer, 1, bufferSize, fp);
2354
++    fclose(fp);
2355
+     
2356
+     if (writtenBytes != bufferSize)
2357
+     {
2358
+-        VMREST_LOG_WARNING(pRESTHandle,"Not all buffer bytes written to file, requested %u, written %d", bufferSize, writtenBytes);
2359
++        VMREST_LOG_WARNING(pRESTHandle,"Not all buffer bytes written to file, requested %u, written %u", bufferSize, writtenBytes);
2360
+     }
2361
+ 
2362
+-    fclose(fp);
2363
+-
2364
+     if (sslDataType == SSL_DATA_TYPE_KEY)
2365
+     {
2366
+         memset(pRESTHandle->pRESTConfig->ssl_key, '\0', MAX_PATH_LEN);
2367
+@@ -177,6 +177,7 @@
2368
+     )
2369
+ {
2370
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
2371
++    int                              ret = 0;
2372
+ 
2373
+     if (!pRESTHandle)
2374
+     {
2375
+@@ -200,11 +201,23 @@
2376
+ 
2377
+     if (pRESTHandle->pSSLInfo->isCertSet == SSL_INFO_FROM_BUFFER_API)
2378
+     {
2379
+-        remove(pRESTHandle->pRESTConfig->ssl_certificate);
2380
++        if ((ret = remove(pRESTHandle->pRESTConfig->ssl_certificate)) == -1)
2381
++        {
2382
++            VMREST_LOG_ERROR(pRESTHandle, "remove() syscall failed for temp certificate file ()");
2383
++            dwError = REST_ENGINE_FAILURE;
2384
++        }
2385
++        BAIL_ON_VMREST_ERROR(dwError);
2386
+     }
2387
++    ret = 0;
2388
++
2389
+     if (pRESTHandle->pSSLInfo->isKeySet == SSL_INFO_FROM_BUFFER_API)
2390
+     {
2391
+-        remove(pRESTHandle->pRESTConfig->ssl_key);
2392
++        if ((ret = remove(pRESTHandle->pRESTConfig->ssl_key)) == -1)
2393
++        {
2394
++            VMREST_LOG_ERROR(pRESTHandle, "remove temp file failed ()");
2395
++            dwError = REST_ENGINE_FAILURE;
2396
++        }
2397
++        BAIL_ON_VMREST_ERROR(dwError);
2398
+     }
2399
+ 
2400
+ cleanup:
2401
+diff -ru c-rest-engine-1.0.3/server/restengine/restProtocolHead.c c-rest-engine-1.0.4/server/restengine/restProtocolHead.c
2402
+--- c-rest-engine-1.0.3/server/restengine/restProtocolHead.c	2017-07-20 19:57:03.000000000 -0700
2403
+@@ -20,10 +20,9 @@
2404
+     PREST_RESPONSE*                  ppResponse
2405
+     )
2406
+ {
2407
+-    char                             httpPayload[MAX_DATA_BUFFER_LEN] = {0};
2408
+     char                             httpMethod[MAX_METHOD_LEN] = {0};
2409
+-    char                             httpURI[MAX_URI_LEN] = {0};
2410
+-    char                             endPointURI[MAX_URI_LEN] = {0};
2411
++    char*                            httpURI = NULL;
2412
++    char*                            endPointURI = NULL;
2413
+     char*                            ptr = NULL;
2414
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
2415
+     uint32_t                         paramsCount = 0;
2416
+@@ -31,12 +30,19 @@
2417
+ 
2418
+     VMREST_LOG_DEBUG(pRESTHandle,"%s","Internal Handler called");
2419
+ 
2420
+-    /**** 1. Init all the funcition variables *****/
2421
++    /**** 1. Allocate the memory of holding URI *****/
2422
+ 
2423
+-    memset(httpPayload, '\0', MAX_DATA_BUFFER_LEN);
2424
+-    memset(httpMethod, '\0', MAX_METHOD_LEN);
2425
+-    memset(httpURI, '\0', MAX_URI_LEN);
2426
+-    memset(endPointURI, '\0', MAX_URI_LEN);
2427
++    dwError = VmRESTAllocateMemory(
2428
++                  MAX_URI_LEN,
2429
++                  (void**)&endPointURI
2430
++                  );
2431
++    BAIL_ON_VMREST_ERROR(dwError);
2432
++
2433
++    dwError = VmRESTAllocateMemory(
2434
++                  MAX_URI_LEN,
2435
++                  (void**)&httpURI
2436
++                  );
2437
++    BAIL_ON_VMREST_ERROR(dwError);
2438
+ 
2439
+     /**** 2. Get the method name ****/
2440
+ 
2441
+@@ -191,6 +197,16 @@
2442
+     BAIL_ON_VMREST_ERROR(dwError);
2443
+ 
2444
+ cleanup:
2445
++    if (endPointURI != NULL)
2446
++    {
2447
++        VmRESTFreeMemory(endPointURI);
2448
++        endPointURI = NULL;
2449
++    }
2450
++    if (httpURI != NULL)
2451
++    {
2452
++        VmRESTFreeMemory(httpURI);
2453
++        httpURI = NULL;
2454
++    }
2455
+     return dwError;
2456
+ error:
2457
+     goto cleanup;
2458
+@@ -645,11 +661,17 @@
2459
+                     {
2460
+                         strncpy(res, (value +1), (MAX_KEY_VAL_PARAM_LEN -1));
2461
+                     }
2462
++                    else if ((*(value +1) == '\0'))
2463
++                    {
2464
++                        VMREST_LOG_DEBUG(pRESTHandle, "Missing value in key-value pair");
2465
++                        memset(res, '\0', MAX_KEY_VAL_PARAM_LEN);
2466
++                    }
2467
+                     else
2468
+                     {
2469
++                        VMREST_LOG_ERROR(pRESTHandle, "Value too large");
2470
+                         dwError = REQUEST_ENTITY_TOO_LARGE;
2471
+                     }
2472
+-                }    
2473
++                } 
2474
+             }
2475
+             else
2476
+             {
2477
+@@ -926,8 +948,8 @@
2478
+     uint32_t*                        wildCardCount
2479
+     )
2480
+ {
2481
+-    char                             httpURI[MAX_URI_LEN] = {0};
2482
+-    char                             endPointURI[MAX_URI_LEN] = {0};
2483
++    char*                            httpURI = NULL;
2484
++    char*                            endPointURI = NULL;
2485
+     char*                            ptr = NULL;
2486
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
2487
+     uint32_t                         count = 0;
2488
+@@ -941,8 +963,17 @@
2489
+     BAIL_ON_VMREST_ERROR(dwError);
2490
+     *wildCardCount = 0;
2491
+ 
2492
+-    memset(httpURI, '\0', MAX_URI_LEN);
2493
+-    memset(endPointURI, '\0', MAX_URI_LEN);
2494
++    dwError = VmRESTAllocateMemory(
2495
++                  MAX_URI_LEN,
2496
++                  (void**)&endPointURI
2497
++                  );
2498
++    BAIL_ON_VMREST_ERROR(dwError);
2499
++
2500
++    dwError = VmRESTAllocateMemory(
2501
++                  MAX_URI_LEN,
2502
++                  (void**)&httpURI
2503
++                  );
2504
++    BAIL_ON_VMREST_ERROR(dwError);
2505
+ 
2506
+     dwError = VmRESTGetHttpURI(
2507
+                   pRequest,
2508
+@@ -989,6 +1020,17 @@
2509
+     *wildCardCount = count;
2510
+ 
2511
+ cleanup:
2512
++    if (endPointURI != NULL)
2513
++    {
2514
++        VmRESTFreeMemory(endPointURI);
2515
++        endPointURI = NULL;
2516
++    }
2517
++    if (httpURI != NULL)
2518
++    {
2519
++        VmRESTFreeMemory(httpURI);
2520
++        httpURI = NULL;
2521
++    }
2522
++
2523
+     return dwError;
2524
+ error:
2525
+     if (wildCardCount != NULL)
2526
+@@ -1010,8 +1052,8 @@
2527
+     uint32_t                         dwError = REST_ENGINE_SUCCESS;
2528
+     uint32_t                         count = 0;
2529
+     uint32_t                         preSlashIndex = 0;
2530
+-    char                             httpURI[MAX_URI_LEN] = {0};
2531
+-    char                             endPointURI[MAX_URI_LEN] = {0};
2532
++    char*                            httpURI = NULL;
2533
++    char*                            endPointURI = NULL;
2534
+     char*                            ptr = NULL;
2535
+     char*                            pszWildCard = NULL;
2536
+     PREST_ENDPOINT                   pEndPoint = NULL;
2537
+@@ -1023,6 +1065,18 @@
2538
+     }
2539
+     BAIL_ON_VMREST_ERROR(dwError);
2540
+ 
2541
++    dwError = VmRESTAllocateMemory(
2542
++                  MAX_URI_LEN,
2543
++                  (void**)&endPointURI
2544
++                  );
2545
++    BAIL_ON_VMREST_ERROR(dwError);
2546
++
2547
++    dwError = VmRESTAllocateMemory(
2548
++                  MAX_URI_LEN,
2549
++                  (void**)&httpURI
2550
++                  );
2551
++    BAIL_ON_VMREST_ERROR(dwError);
2552
++
2553
+     dwError = VmRESTGetWildCardCount(
2554
+                   pRESTHandle,
2555
+                   pRequest,
2556
+@@ -1097,6 +1151,16 @@
2557
+ 
2558
+ 
2559
+ cleanup:
2560
++    if (endPointURI != NULL)
2561
++    {
2562
++        VmRESTFreeMemory(endPointURI);
2563
++        endPointURI = NULL;
2564
++    }
2565
++    if (httpURI != NULL)
2566
++    {
2567
++        VmRESTFreeMemory(httpURI);
2568
++        httpURI = NULL;
2569
++    }
2570
+     return dwError;
2571
+ error:
2572
+     if (pszWildCard)
2573
+diff -ru c-rest-engine-1.0.3/server/vmrestd/main.c c-rest-engine-1.0.4/server/vmrestd/main.c
2574
+--- c-rest-engine-1.0.3/server/vmrestd/main.c	2017-07-20 19:57:03.000000000 -0700
2575
+@@ -81,6 +81,18 @@
2576
+     dwError = VmRESTInit(NULL,configPath, &gpRESTHandle);
2577
+     dwError = VmRESTInit(NULL,configPath1, &gpRESTHandle1);
2578
+ 
2579
++// test set SSL info API
2580
++#if 0 
2581
++   char buffer[8092]= {0};
2582
++   FILE *fp = fopen("/root/mycert.pem","r");
2583
++
2584
++   dwError = fread(buffer, 1, 8092, fp);
2585
++   VmRESTSetSSLInfo(gpRESTHandle, buffer, dwError, SSL_DATA_TYPE_KEY);
2586
++   VmRESTSetSSLInfo(gpRESTHandle, buffer, dwError, SSL_DATA_TYPE_CERT);
2587
++
2588
++
2589
++#endif
2590
++
2591
+     VmRESTRegisterHandler(gpRESTHandle, "/v1/pkg", &gVmRestHandlers, NULL);
2592
+     VmRESTRegisterHandler(gpRESTHandle1, "/v1/blah", &gVmRestHandlers1, NULL);
2593
+ 
2594
+@@ -121,7 +133,7 @@
2595
+     )
2596
+ {
2597
+     uint32_t                         dwError = REST_ENGINE_MORE_IO_REQUIRED;
2598
+-    char                             AllData[MAX_IN_MEM_PAYLOAD_LEN] = {0};
2599
++    char*                            AllData = NULL;
2600
+     char                             buffer[4097] = {0};
2601
+     int                              nRead = 0;
2602
+     int                              nWrite = 0;
2603
+@@ -131,9 +143,11 @@
2604
+     int                              resLength = 0;
2605
+     uint32_t                         index = 0;
2606
+     
2607
+-    memset(AllData, '\0', MAX_IN_MEM_PAYLOAD_LEN);
2608
+     memset(size, '\0', 10);
2609
+ 
2610
++    AllData = malloc(MAX_IN_MEM_PAYLOAD_LEN);
2611
++    memset(AllData, '\0', MAX_IN_MEM_PAYLOAD_LEN);
2612
++
2613
+     bytesRW = 0;
2614
+     
2615
+     while(dwError == REST_ENGINE_MORE_IO_REQUIRED)
2616
+@@ -230,6 +244,12 @@
2617
+     BAIL_ON_VMREST_ERROR(dwError);
2618
+ 
2619
+ cleanup:
2620
++    if (AllData != NULL)
2621
++    {
2622
++        free(AllData);
2623
++        AllData = NULL;
2624
++    }
2625
++
2626
+     return dwError;
2627
+ error:
2628
+     goto cleanup;
2629
+@@ -247,7 +267,7 @@
2630
+     )
2631
+ {
2632
+     uint32_t                         dwError = 0;
2633
+-    char                             AllData[MAX_IN_MEM_PAYLOAD_LEN] = {0};
2634
++    char*                            AllData = NULL;
2635
+     char                             buffer[4097] = {0};
2636
+     int                              nRead = 0;
2637
+     int                              nWrite = 0;
2638
+@@ -259,9 +279,11 @@
2639
+     FILE*                            fp = NULL;
2640
+ 
2641
+     memset(buffer, '\0', 4097);
2642
+-    memset(AllData, '\0', MAX_IN_MEM_PAYLOAD_LEN);
2643
+     memset(size, '\0', 10);
2644
+ 
2645
++    AllData = malloc(MAX_IN_MEM_PAYLOAD_LEN);
2646
++    memset(AllData, '\0', MAX_IN_MEM_PAYLOAD_LEN);
2647
++
2648
+     dwError = REST_ENGINE_MORE_IO_REQUIRED;
2649
+ 
2650
+     fp = fopen("/tmp/image.vmdk","wb+");
2651
+@@ -303,6 +325,7 @@
2652
+     BAIL_ON_VMREST_ERROR(dwError);
2653
+ 
2654
+     fclose(fp);
2655
++    fp = NULL;
2656
+ 
2657
+     dwError = VmRESTSetSuccessResponse(
2658
+                   pRequest,
2659
+@@ -368,8 +391,20 @@
2660
+     BAIL_ON_VMREST_ERROR(dwError);
2661
+ 
2662
+ cleanup:
2663
++    if (AllData != NULL)
2664
++    {
2665
++        free(AllData);
2666
++        AllData = NULL;
2667
++    }
2668
++
2669
+     return dwError;
2670
+ error:
2671
++
2672
++    if (fp != NULL)
2673
++    {
2674
++        fclose(fp);
2675
++        fp = NULL;
2676
++    }
2677
+     goto cleanup;
2678
+ }
2679
+ 
2680
+diff -ru c-rest-engine-1.0.3/transport/posix/global.c c-rest-engine-1.0.4/transport/posix/global.c
2681
+--- c-rest-engine-1.0.3/transport/posix/global.c	2017-07-20 19:57:03.000000000 -0700
2682
+@@ -15,6 +15,6 @@
2683
+ 
2684
+ int                                  gSSLisedInstaceCount = INVALID;
2685
+ pthread_mutex_t*                     gSSLThreadLock = NULL;
2686
+-pthread_mutex_t                      gGlobalMutex;
2687
++pthread_mutex_t                      gGlobalMutex = PTHREAD_MUTEX_INITIALIZER;
2688
+ 
2689
+ 
2690
+diff -ru c-rest-engine-1.0.3/transport/posix/socket.c c-rest-engine-1.0.4/transport/posix/socket.c
2691
+--- c-rest-engine-1.0.3/transport/posix/socket.c	2017-07-20 19:57:03.000000000 -0700
2692
+@@ -266,15 +266,6 @@
2693
+     )
2694
+ {
2695
+     DWORD                            dwError = REST_ENGINE_SUCCESS;
2696
+-
2697
+-    if (!pRESTHandle)
2698
+-    {
2699
+-        VMREST_LOG_DEBUG(pRESTHandle,"Invalid REST Handler");
2700
+-        dwError = REST_ERROR_INVALID_HANDLER;
2701
+-    }
2702
+-    BAIL_ON_VMREST_ERROR(dwError);
2703
+-
2704
+-
2705
+     union
2706
+     {
2707
+ #ifdef AF_INET6
2708
+@@ -294,6 +285,12 @@
2709
+     PVM_SOCKET                       pSocket = NULL;
2710
+     PVM_SOCK_SSL_INFO                pSSLInfo = NULL;
2711
+ 
2712
++    if (!pRESTHandle)
2713
++    {
2714
++        dwError = REST_ERROR_INVALID_HANDLER;
2715
++    }
2716
++    BAIL_ON_VMREST_ERROR(dwError);
2717
++
2718
+     if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6)
2719
+     {
2720
+ #ifdef AF_INET6
2721
+@@ -324,11 +321,6 @@
2722
+     /**** Check if connection is over SSL ****/
2723
+     if(dwFlags & VM_SOCK_IS_SSL)
2724
+     {
2725
+-        if (gSSLisedInstaceCount == INVALID)
2726
+-        {
2727
+-            pthread_mutex_init(&gGlobalMutex, NULL);
2728
+-            gSSLisedInstaceCount = 0;
2729
+-        }
2730
+         SSL_library_init();
2731
+         dwError = VmRESTSecureSocket(
2732
+                       pRESTHandle,
2733
+@@ -337,15 +329,16 @@
2734
+                       );
2735
+         BAIL_ON_POSIX_SOCK_ERROR(dwError);
2736
+         pSSLInfo->isSecure = 1;
2737
++        
2738
+         pthread_mutex_lock(&gGlobalMutex);
2739
+-        if (gSSLisedInstaceCount == 0)
2740
++        if (gSSLisedInstaceCount == INVALID)
2741
+         {
2742
++            gSSLisedInstaceCount = 0;
2743
+             dwError = VmRESTSSLThreadLockInit();
2744
+-            gSSLisedInstaceCount++;
2745
+         }
2746
++        gSSLisedInstaceCount++;
2747
+         pthread_mutex_unlock(&gGlobalMutex);
2748
+         BAIL_ON_VMREST_ERROR(dwError);
2749
+-        
2750
+     }
2751
+     else
2752
+     {
2753
+@@ -727,34 +720,33 @@
2754
+                              ssl = SSL_new(pRESTHandle->pSSLInfo->sslContext);
2755
+                              SSL_set_fd(ssl,pSocket->fd);
2756
+ retry:
2757
+-                             if ((SSL_accept(ssl) == -1) && (timeOutSec >= 0))
2758
++                             if ( SSL_accept(ssl) == -1 )
2759
+                              {
2760
+                                  if (timeOutSec >= 0)
2761
+                                  {
2762
+-                                 cntRty++;
2763
++                                     cntRty++;
2764
+ #ifdef WIN32
2765
+-                                 Sleep(timerMs);
2766
++                                     Sleep(timerMs);
2767
+ #else
2768
+-                                 usleep((timerMs * 1000));
2769
++                                     usleep((timerMs * 1000));
2770
+ #endif
2771
+-                                 if (cntRty >= maxTry)
2772
+-                                 {
2773
+-                                     timerMs = ((timerMs >= 1000) ? 1000 : (timerMs*10));
2774
+-                                     maxTry = ((maxTry <= 1) ? 1 : (maxTry/10));
2775
+-                                     timeOutSec--;
2776
+-                                     cntRty = 0;
2777
+-                                 }
2778
+-                                 goto retry;
2779
++                                     if (cntRty >= maxTry)
2780
++                                     {
2781
++                                         timerMs = ((timerMs >= 1000) ? 1000 : (timerMs*10));
2782
++                                         maxTry = ((maxTry <= 1) ? 1 : (maxTry/10));
2783
++                                         timeOutSec--;
2784
++                                         cntRty = 0;
2785
++                                     }
2786
++                                     goto retry;
2787
+                                  }
2788
+- 
2789
+-                                 else if(timeOutSec <= 0)
2790
++                                 else
2791
+                                  {
2792
+-                                 VMREST_LOG_ERROR(pRESTHandle,"SSL accept failed");
2793
+-                                  SSL_shutdown(ssl);
2794
+-                                  SSL_free(ssl);
2795
+-                                  close(pSocket->fd);
2796
+-                                  dwError = VMREST_TRANSPORT_SSL_ACCEPT_FAILED;
2797
+-                                  BAIL_ON_VMREST_ERROR(dwError);
2798
++                                     VMREST_LOG_ERROR(pRESTHandle,"SSL accept failed");
2799
++                                     SSL_shutdown(ssl);
2800
++                                     SSL_free(ssl);
2801
++                                     close(pSocket->fd);
2802
++                                     dwError = VMREST_TRANSPORT_SSL_ACCEPT_FAILED;
2803
++                                     BAIL_ON_VMREST_ERROR(dwError);
2804
+                                  }
2805
+                              }
2806
+                              pSocket->ssl = ssl;