package proxy import ( "bytes" "context" "fmt" "io" "net/http" "devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/auth" ) // Client is responsible for making requests to the Healthcare API type Client struct { googleAuth *auth.GoogleClient projectID string location string dataset string dicomStore string } // NewClient creates a new Healthcare API client // Hanya menerima cfg.Google struct instead of all cfg.Config func NewClient(googleAuth *auth.GoogleClient, googleConfig struct { ProjectID string `mapstructure:"project_id"` Location string `mapstructure:"location"` Dataset string `mapstructure:"dataset"` DicomStore string `mapstructure:"dicom_store"` CredentialsPath string `mapstructure:"credentials_path"` }) *Client { return &Client{ googleAuth: googleAuth, projectID: googleConfig.ProjectID, location: googleConfig.Location, dataset: googleConfig.Dataset, dicomStore: googleConfig.DicomStore, } } // Response represents the HTTP response from the Healthcare API type Response struct { StatusCode int Headers map[string]string Body []byte } // ForwardRequest forwards a request to Google Healthcare API func (c *Client) ForwardRequest(ctx context.Context, method, path string, headers map[string]string, body []byte) (*Response, error) { token, err := c.googleAuth.GetAccessToken() if err != nil { return nil, fmt.Errorf("failed to get access token: %w", err) } // Build URL - Simplified to exactly match OHIF's expected structure baseURL := fmt.Sprintf("https://healthcare.googleapis.com/v1/projects/%s/locations/%s/datasets/%s/dicomStores/%s/dicomWeb", c.projectID, c.location, c.dataset, c.dicomStore) // Ensure path starts with / if len(path) > 0 && path[0] != '/' { path = "/" + path } fullURL := baseURL + path // Log the full URL for debugging fmt.Printf("Requesting URL: %s\n", fullURL) // Create request req, err := http.NewRequestWithContext(ctx, method, fullURL, bytes.NewReader(body)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } // Set headers for k, v := range headers { // Skip setting certain headers that might cause issues if k == "Host" || k == "Content-Length" { continue } req.Header.Set(k, v) } // Set auth header req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) // Make request client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("failed to execute request: %w", err) } defer resp.Body.Close() // Read response body respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response body: %w", err) } // Collect response headers respHeaders := make(map[string]string) for k, v := range resp.Header { if len(v) > 0 { respHeaders[k] = v[0] } } return &Response{ StatusCode: resp.StatusCode, Headers: respHeaders, Body: respBody, }, nil }