@@ -581,25 +581,9 @@ func (s *Server) parseRequest(ctx context.Context, r *http.Request) (*CalculateR
581581
582582 // Handle GET requests with query parameters
583583 if r .Method == http .MethodGet {
584- req .URL = r .URL .Query ().Get ("url" )
585-
586- // Parse optional config parameters
587- if salaryStr := r .URL .Query ().Get ("salary" ); salaryStr != "" {
588- if req .Config == nil {
589- req .Config = & cost.Config {}
590- }
591- if salary , err := strconv .ParseFloat (salaryStr , 64 ); err == nil {
592- req .Config .AnnualSalary = salary
593- }
594- }
595- if benefitsStr := r .URL .Query ().Get ("benefits" ); benefitsStr != "" {
596- if req .Config == nil {
597- req .Config = & cost.Config {}
598- }
599- if benefits , err := strconv .ParseFloat (benefitsStr , 64 ); err == nil {
600- req .Config .BenefitsMultiplier = benefits
601- }
602- }
584+ query := r .URL .Query ()
585+ req .URL = query .Get ("url" )
586+ req .Config = parseConfigFromQuery (query )
603587 } else {
604588 // Handle POST requests with JSON body
605589 // SECURITY: Limit request body size to prevent memory exhaustion DoS.
@@ -626,6 +610,28 @@ func (s *Server) parseRequest(ctx context.Context, r *http.Request) (*CalculateR
626610 return & req , nil
627611}
628612
613+ // parseConfigFromQuery extracts salary and benefits from query parameters.
614+ func parseConfigFromQuery (query url.Values ) * cost.Config {
615+ salaryStr := query .Get ("salary" )
616+ benefitsStr := query .Get ("benefits" )
617+ if salaryStr == "" && benefitsStr == "" {
618+ return nil
619+ }
620+
621+ cfg := & cost.Config {}
622+ if salaryStr != "" {
623+ if salary , err := strconv .ParseFloat (salaryStr , 64 ); err == nil {
624+ cfg .AnnualSalary = salary
625+ }
626+ }
627+ if benefitsStr != "" {
628+ if benefits , err := strconv .ParseFloat (benefitsStr , 64 ); err == nil {
629+ cfg .BenefitsMultiplier = benefits
630+ }
631+ }
632+ return cfg
633+ }
634+
629635// validateGitHubPRURL performs strict validation of GitHub PR URLs.
630636func (* Server ) validateGitHubPRURL (prURL string ) error {
631637 // Length check prevents DoS attacks with extremely long URLs.
@@ -1128,36 +1134,22 @@ func (s *Server) parseRepoSampleRequest(ctx context.Context, r *http.Request) (*
11281134
11291135 // Handle GET requests with query parameters
11301136 if r .Method == http .MethodGet {
1131- req .Owner = r .URL .Query ().Get ("owner" )
1132- req .Repo = r .URL .Query ().Get ("repo" )
1137+ query := r .URL .Query ()
1138+ req .Owner = query .Get ("owner" )
1139+ req .Repo = query .Get ("repo" )
11331140
11341141 // Parse optional parameters
1135- if sampleStr := r . URL . Query () .Get ("sample" ); sampleStr != "" {
1142+ if sampleStr := query .Get ("sample" ); sampleStr != "" {
11361143 if sample , err := strconv .Atoi (sampleStr ); err == nil {
11371144 req .SampleSize = sample
11381145 }
11391146 }
1140- if daysStr := r . URL . Query () .Get ("days" ); daysStr != "" {
1147+ if daysStr := query .Get ("days" ); daysStr != "" {
11411148 if days , err := strconv .Atoi (daysStr ); err == nil {
11421149 req .Days = days
11431150 }
11441151 }
1145- if salaryStr := r .URL .Query ().Get ("salary" ); salaryStr != "" {
1146- if req .Config == nil {
1147- req .Config = & cost.Config {}
1148- }
1149- if salary , err := strconv .ParseFloat (salaryStr , 64 ); err == nil {
1150- req .Config .AnnualSalary = salary
1151- }
1152- }
1153- if benefitsStr := r .URL .Query ().Get ("benefits" ); benefitsStr != "" {
1154- if req .Config == nil {
1155- req .Config = & cost.Config {}
1156- }
1157- if benefits , err := strconv .ParseFloat (benefitsStr , 64 ); err == nil {
1158- req .Config .BenefitsMultiplier = benefits
1159- }
1160- }
1152+ req .Config = parseConfigFromQuery (query )
11611153 } else {
11621154 // Handle POST requests with JSON body
11631155 const maxRequestSize = 1 << 20 // 1MB
@@ -1204,35 +1196,21 @@ func (s *Server) parseOrgSampleRequest(ctx context.Context, r *http.Request) (*O
12041196
12051197 // Handle GET requests with query parameters
12061198 if r .Method == http .MethodGet {
1207- req .Org = r .URL .Query ().Get ("org" )
1199+ query := r .URL .Query ()
1200+ req .Org = query .Get ("org" )
12081201
12091202 // Parse optional parameters
1210- if sampleStr := r . URL . Query () .Get ("sample" ); sampleStr != "" {
1203+ if sampleStr := query .Get ("sample" ); sampleStr != "" {
12111204 if sample , err := strconv .Atoi (sampleStr ); err == nil {
12121205 req .SampleSize = sample
12131206 }
12141207 }
1215- if daysStr := r . URL . Query () .Get ("days" ); daysStr != "" {
1208+ if daysStr := query .Get ("days" ); daysStr != "" {
12161209 if days , err := strconv .Atoi (daysStr ); err == nil {
12171210 req .Days = days
12181211 }
12191212 }
1220- if salaryStr := r .URL .Query ().Get ("salary" ); salaryStr != "" {
1221- if req .Config == nil {
1222- req .Config = & cost.Config {}
1223- }
1224- if salary , err := strconv .ParseFloat (salaryStr , 64 ); err == nil {
1225- req .Config .AnnualSalary = salary
1226- }
1227- }
1228- if benefitsStr := r .URL .Query ().Get ("benefits" ); benefitsStr != "" {
1229- if req .Config == nil {
1230- req .Config = & cost.Config {}
1231- }
1232- if benefits , err := strconv .ParseFloat (benefitsStr , 64 ); err == nil {
1233- req .Config .BenefitsMultiplier = benefits
1234- }
1235- }
1213+ req .Config = parseConfigFromQuery (query )
12361214 } else {
12371215 // Handle POST requests with JSON body
12381216 const maxRequestSize = 1 << 20 // 1MB
0 commit comments