@@ -12,6 +12,11 @@ import (
1212 "strings"
1313)
1414
15+ type readCloser struct {
16+ io.Reader
17+ io.Closer
18+ }
19+
1520// A Command represents a cURL command.
1621type Command struct {
1722 // tokens holds the complete lines of the command.
@@ -20,12 +25,12 @@ type Command struct {
2025 // cfg holds all user-configurable settings.
2126 cfg config
2227
23- // model is the pre-processed request data used by the builders .
24- model parsedRequest
28+ // data contains the details extracted from the *http.Request .
29+ data requestData
2530}
2631
27- // parsedRequest holds pre-calculated data from the *http.Request.
28- type parsedRequest struct {
32+ // requestData holds pre-calculated data from the *http.Request.
33+ type requestData struct {
2934 request * http.Request
3035
3136 hasAuth bool
@@ -60,20 +65,19 @@ func NewFromRequest(r *http.Request, opts ...Option) (*Command, error) {
6065 return nil , fmt .Errorf ("request url is nil" )
6166 }
6267
63- if err := c .model . build (r , c .cfg ); err != nil {
68+ if err := c .data . load (r , c .cfg ); err != nil {
6469 return nil , err
6570 }
6671
67- c .construct ()
72+ c .compile ()
6873
6974 return & c , nil
7075}
7176
72- // build preprocesses the *http.Request into the internal parsedRequest.
73- // It non-destructively reads (peeks) the request body, sets flags for
74- // truncation and data presence, and then restores the body so it can be
75- // read again by subsequent handlers.
76- func (m * parsedRequest ) build (r * http.Request , cfg config ) error {
77+ // load extracts relevant data from the *http.Request and populates the internal model.
78+ // It performs a non-destructive read (peek) of the body and restores it,
79+ // ensuring the request remains valid for subsequent handlers.
80+ func (m * requestData ) load (r * http.Request , cfg config ) error {
7781 m .request = r
7882 m .user , m .pass , m .hasAuth = r .BasicAuth ()
7983 // Store the original content length
@@ -124,26 +128,30 @@ func (m *parsedRequest) build(r *http.Request, cfg config) error {
124128 }
125129
126130 // Restore the full request body for subsequent handlers.
127- r .Body = io .NopCloser (b )
131+ r .Body = & readCloser {
132+ Reader : b ,
133+ Closer : r .Body ,
134+ }
128135
129136 return nil
130137}
131138
132- // construct is the internal orchestrator.
133- // It runs all the small autonomous builder functions in order.
134- func (c * Command ) construct () {
139+ // compile assembles the final cURL command tokens.
140+ // It executes the specific builder functions (headers, auth, body, etc.)
141+ // and aggregates their output into the final command structure.
142+ func (c * Command ) compile () {
135143 // handledHeaders tracks headers handled by builders (e.g., Auth)
136144 handledHeaders := make (map [string ]bool )
137145
138146 commandParts := []string {"curl" }
139147 commandParts = buildOptions (commandParts , c .cfg )
140- commandParts = buildAuth (commandParts , c .cfg , c .model , handledHeaders )
141- commandParts = buildCookies (commandParts , c .cfg , c .model , handledHeaders )
142- commandParts = buildData (commandParts , c .cfg , c .model )
143- commandParts = buildMethod (commandParts , c .cfg , c .model )
144- commandParts = buildURL (commandParts , c .cfg , c .model )
148+ commandParts = buildAuth (commandParts , c .cfg , c .data , handledHeaders )
149+ commandParts = buildCookies (commandParts , c .cfg , c .data , handledHeaders )
150+ commandParts = buildData (commandParts , c .cfg , c .data )
151+ commandParts = buildMethod (commandParts , c .cfg , c .data )
152+ commandParts = buildURL (commandParts , c .cfg , c .data )
145153
146- headerParts := buildHeaders (c .cfg , c .model , handledHeaders )
154+ headerParts := buildHeaders (c .cfg , c .data , handledHeaders )
147155
148156 c .tokens = assembleTokens (commandParts , headerParts )
149157}
@@ -179,8 +187,8 @@ func buildOptions(args []string, cfg config) []string {
179187 return args
180188}
181189
182- // buildAuth adds the -u/--user flag and handle the Authorization header.
183- func buildAuth (args []string , cfg config , model parsedRequest , handledHeaders map [string ]bool ) []string {
190+ // buildAuth adds the -u/--user flag and handles the Authorization header.
191+ func buildAuth (args []string , cfg config , model requestData , handledHeaders map [string ]bool ) []string {
184192 if ! model .hasAuth {
185193 return args
186194 }
@@ -192,8 +200,8 @@ func buildAuth(args []string, cfg config, model parsedRequest, handledHeaders ma
192200 return args
193201}
194202
195- // buildCookies adds the -b/--cookie flag and handle the Cookie header.
196- func buildCookies (args []string , cfg config , model parsedRequest , handledHeaders map [string ]bool ) []string {
203+ // buildCookies adds the -b/--cookie flag and handles the Cookie header.
204+ func buildCookies (args []string , cfg config , model requestData , handledHeaders map [string ]bool ) []string {
197205 if ! model .hasCookies {
198206 return args
199207 }
@@ -205,7 +213,7 @@ func buildCookies(args []string, cfg config, model parsedRequest, handledHeaders
205213}
206214
207215// buildData adds the --data-raw flag if data exists.
208- func buildData (args []string , cfg config , model parsedRequest ) []string {
216+ func buildData (args []string , cfg config , model requestData ) []string {
209217 // We only add the flag if a body was present (even if empty).
210218 if model .body == nil {
211219 return args
@@ -226,7 +234,7 @@ func buildData(args []string, cfg config, model parsedRequest) []string {
226234}
227235
228236// buildMethod adds the -X flag if it is not a cURL default.
229- func buildMethod (args []string , cfg config , model parsedRequest ) []string {
237+ func buildMethod (args []string , cfg config , model requestData ) []string {
230238 method := model .request .Method
231239 if method == "" {
232240 if model .hasData {
@@ -247,12 +255,12 @@ func buildMethod(args []string, cfg config, model parsedRequest) []string {
247255}
248256
249257// buildURL escapes and adds the URL to the end of the main args.
250- func buildURL (args []string , cfg config , model parsedRequest ) []string {
258+ func buildURL (args []string , cfg config , model requestData ) []string {
251259 return append (args , escape (cfg .style , model .request .URL .String ()))
252260}
253261
254262// buildHeaders builds all non-handled HTTP headers.
255- func buildHeaders (cfg config , model parsedRequest , handledHeaders map [string ]bool ) []string {
263+ func buildHeaders (cfg config , model requestData , handledHeaders map [string ]bool ) []string {
256264 r := model .request
257265 if len (r .Header ) == 0 && r .Host == "" {
258266 return nil
0 commit comments