@@ -107,17 +107,17 @@ async function createPostRequest(
107
107
}
108
108
109
109
function createRequestBodyForFilepaths (
110
- filepaths : string [ ]
110
+ filepaths : string [ ] ,
111
+ basePath : string
111
112
) : Array < string | ReadStream > {
112
113
const requestBody = [ ]
113
- for ( const p of filepaths ) {
114
- // Multipart header for each file.
114
+ for ( const absPath of filepaths ) {
115
+ const relPath = path . relative ( basePath , absPath )
116
+ const filename = path . basename ( absPath )
115
117
requestBody . push (
116
- `Content-Disposition: form-data; name="file"; filename="${ path . basename ( p ) } "\n` ,
117
- `Content-Type: application/octet-stream\n\n` ,
118
- createReadStream ( p ) ,
119
- // New line after file content.
120
- '\n'
118
+ `Content-Disposition: form-data; name="${ relPath } "; filename="${ filename } "\r\n` ,
119
+ `Content-Type: application/octet-stream\r\n\r\n` ,
120
+ createReadStream ( absPath )
121
121
)
122
122
}
123
123
return requestBody
@@ -130,29 +130,32 @@ function createRequestBodyForJson(
130
130
const ext = path . extname ( basename )
131
131
const name = path . basename ( basename , ext )
132
132
return [
133
- `Content-Disposition: form-data; name="${ name } "; filename="${ basename } "\n` ,
134
- 'Content-Type: application/json\n \n' ,
133
+ `Content-Disposition: form-data; name="${ name } "; filename="${ basename } "\r\ n` ,
134
+ 'Content-Type: application/json\r\n\r \n' ,
135
135
JSON . stringify ( jsonData ) ,
136
136
// New line after file content.
137
- '\n'
137
+ '\r\ n'
138
138
]
139
139
}
140
140
141
141
async function createUploadRequest (
142
142
baseUrl : string ,
143
143
urlPath : string ,
144
- requestBodyNoBoundaries : Array < string | ReadStream > ,
144
+ requestBodyNoBoundaries : Array <
145
+ string | ReadStream | Array < string | ReadStream >
146
+ > ,
145
147
options : RequestOptions
146
148
) : Promise < IncomingMessage > {
147
149
// Generate a unique boundary for multipart encoding.
148
- const boundary = `---- NodeMultipartBoundary${ Date . now ( ) } `
149
- const boundarySep = `--${ boundary } \n`
150
- // Create request body as a stream.
150
+ const boundary = `NodeMultipartBoundary${ Date . now ( ) } `
151
+ const boundarySep = `--${ boundary } \r\ n`
152
+ const finalBoundary = `-- ${ boundary } --\r\n`
151
153
const requestBody = [
152
- ...( requestBodyNoBoundaries . length
153
- ? requestBodyNoBoundaries . flatMap ( e => [ boundarySep , e ] )
154
- : [ boundarySep ] ) ,
155
- `--${ boundary } --\n`
154
+ ...requestBodyNoBoundaries . flatMap ( part => [
155
+ boundarySep ,
156
+ ...( Array . isArray ( part ) ? part : [ part ] )
157
+ ] ) ,
158
+ finalBoundary
156
159
]
157
160
const req = getHttpModule ( baseUrl ) . request ( `${ baseUrl } ${ urlPath } ` , {
158
161
method : 'POST' ,
@@ -167,13 +170,15 @@ async function createUploadRequest(
167
170
for ( const part of requestBody ) {
168
171
if ( typeof part === 'string' ) {
169
172
req . write ( part )
170
- } else {
173
+ } else if ( typeof part ?. pipe === 'function' ) {
171
174
part . pipe ( req , { end : false } )
172
175
// Wait for file streaming to complete.
173
176
// eslint-disable-next-line no-await-in-loop
174
177
await events . once ( part , 'end' )
175
178
// Ensure a new line after file content.
176
- req . write ( '\n' )
179
+ req . write ( '\r\n' )
180
+ } else {
181
+ throw new TypeError ( 'Invalid multipart part: expected string or stream' )
177
182
}
178
183
}
179
184
} finally {
@@ -224,15 +229,26 @@ function isResponseOk(response: IncomingMessage): boolean {
224
229
)
225
230
}
226
231
227
- function resolveAbsPaths ( filepaths : string [ ] , pathsRelativeTo = '.' ) : string [ ] {
232
+ function resolveAbsPaths (
233
+ filepaths : string [ ] ,
234
+ pathsRelativeTo ?: string
235
+ ) : string [ ] {
236
+ const basePath = resolveBasePath ( pathsRelativeTo )
228
237
// Node's path.resolve will process path segments from right to left until
229
238
// it creates a valid absolute path. So if `pathsRelativeTo` is an absolute
230
239
// path, process.cwd() is not used, which is the common expectation. If none
231
240
// of the paths resolve then it defaults to process.cwd().
232
- const basePath = path . resolve ( process . cwd ( ) , pathsRelativeTo )
233
241
return filepaths . map ( p => path . resolve ( basePath , p ) )
234
242
}
235
243
244
+ function resolveBasePath ( pathsRelativeTo = '.' ) : string {
245
+ // Node's path.resolve will process path segments from right to left until
246
+ // it creates a valid absolute path. So if `pathsRelativeTo` is an absolute
247
+ // path, process.cwd() is not used, which is the common expectation. If none
248
+ // of the paths resolve then it defaults to process.cwd().
249
+ return path . resolve ( process . cwd ( ) , pathsRelativeTo )
250
+ }
251
+
236
252
/**
237
253
* Package.json data to base the User-Agent on
238
254
*/
@@ -460,13 +476,14 @@ export class SocketSdk {
460
476
filepaths : string [ ] ,
461
477
pathsRelativeTo = '.'
462
478
) : Promise < SocketSdkResultType < 'createDependenciesSnapshot' > > {
463
- const absFilepaths = resolveAbsPaths ( filepaths , pathsRelativeTo )
479
+ const basePath = resolveBasePath ( pathsRelativeTo )
480
+ const absFilepaths = resolveAbsPaths ( filepaths , basePath )
464
481
try {
465
482
const data = await getResponseJson (
466
483
await createUploadRequest (
467
484
this . #baseUrl,
468
485
`dependencies/upload?${ new URLSearchParams ( params ) } ` ,
469
- createRequestBodyForFilepaths ( absFilepaths ) ,
486
+ createRequestBodyForFilepaths ( absFilepaths , basePath ) ,
470
487
this . #reqOptions
471
488
)
472
489
)
@@ -482,13 +499,14 @@ export class SocketSdk {
482
499
filepaths : string [ ] ,
483
500
pathsRelativeTo : string = '.'
484
501
) : Promise < SocketSdkResultType < 'CreateOrgFullScan' > > {
485
- const absFilepaths = resolveAbsPaths ( filepaths , pathsRelativeTo )
502
+ const basePath = resolveBasePath ( pathsRelativeTo )
503
+ const absFilepaths = resolveAbsPaths ( filepaths , basePath )
486
504
try {
487
505
const data = await getResponseJson (
488
506
await createUploadRequest (
489
507
this . #baseUrl,
490
508
`orgs/${ encodeURIComponent ( orgSlug ) } /full-scans?${ new URLSearchParams ( queryParams ?? '' ) } ` ,
491
- createRequestBodyForFilepaths ( absFilepaths ) ,
509
+ createRequestBodyForFilepaths ( absFilepaths , basePath ) ,
492
510
this . #reqOptions
493
511
)
494
512
)
@@ -522,15 +540,16 @@ export class SocketSdk {
522
540
pathsRelativeTo : string = '.' ,
523
541
issueRules ?: Record < string , boolean >
524
542
) : Promise < SocketSdkResultType < 'createReport' > > {
525
- const absFilepaths = resolveAbsPaths ( filepaths , pathsRelativeTo )
543
+ const basePath = resolveBasePath ( pathsRelativeTo )
544
+ const absFilepaths = resolveAbsPaths ( filepaths , basePath )
526
545
try {
527
546
const data = await createUploadRequest (
528
547
this . #baseUrl,
529
548
'report/upload' ,
530
549
[
531
- ...createRequestBodyForFilepaths ( absFilepaths ) ,
550
+ ...createRequestBodyForFilepaths ( absFilepaths , basePath ) ,
532
551
...( issueRules
533
- ? createRequestBodyForJson ( issueRules , 'issueRules.json ' )
552
+ ? createRequestBodyForJson ( issueRules , 'issueRules' )
534
553
: [ ] )
535
554
] ,
536
555
{
0 commit comments