<commit_before>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/go-swagger/go-swagger/client"
	"github.com/go-swagger/go-swagger/httpkit"
	"github.com/go-swagger/go-swagger/strfmt"
)

// NewRequest creates a new swagger http client request
func newRequest(method, pathPattern string, writer client.RequestWriter) (*request, error) {
	return &request{
		pathPattern: pathPattern,
		method:      method,
		writer:      writer,
		header:      make(http.Header),
		query:       make(url.Values),
	}, nil
}

// Request represents a swagger client request.
//
// This Request struct converts to a HTTP request.
// There might be others that convert to other transports.
// There is no error checking here, it is assumed to be used after a spec has been validated.
// so impossible combinations should not arise (hopefully).
//
// The main purpose of this struct is to hide the machinery of adding params to a transport request.
// The generated code only implements what is necessary to turn a param into a valid value for these methods.
type request struct {
	pathPattern string
	method      string
	writer      client.RequestWriter

	pathParams map[string]string
	header     http.Header
	query      url.Values
	formFields url.Values
	fileFields map[string]*os.File
	payload    interface{}
}

var (
	// ensure interface compliance
	_ client.Request = new(request)
)

// BuildHTTP creates a new http request based on the data from the params
func (r *request) BuildHTTP(mediaType string, producers map[string]httpkit.Producer, registry strfmt.Registry) (*http.Request, error) {
	// build the data
	if err := r.writer.WriteToRequest(r, registry); err != nil {
		return nil, err
	}

	// create http request
	path := r.pathPattern
	for k, v := range r.pathParams {
		path = strings.Replace(path, "{"+k+"}", v, -1)
	}

	var body io.ReadCloser
	var pr *io.PipeReader
	var pw *io.PipeWriter
	buf := bytes.NewBuffer(nil)
	body = ioutil.NopCloser(buf)
	if r.fileFields != nil {
		pr, pw = io.Pipe()
		body = pr
	}
	req, err := http.NewRequest(r.method, path, body)
	if err != nil {
		return nil, err
	}
	req.URL.RawQuery = r.query.Encode()
	req.Header = r.header

	// check if this is a form type request
	if len(r.formFields) > 0 || len(r.fileFields) > 0 {
		// check if this is multipart
		if len(r.fileFields) > 0 {
			mp := multipart.NewWriter(pw)
			req.Header.Set(httpkit.HeaderContentType, mp.FormDataContentType())

			go func() {
				defer func() {
					mp.Close()
					pw.Close()
				}()

				for fn, v := range r.formFields {
					if len(v) > 0 {
						if err := mp.WriteField(fn, v[0]); err != nil {
							pw.CloseWithError(err)
							log.Fatal(err)
						}
					}
				}

				for fn, f := range r.fileFields {
					wrtr, err := mp.CreateFormFile(fn, filepath.Base(f.Name()))
					if err != nil {
						pw.CloseWithError(err)
						log.Fatal(err)
					}
					defer func() {
						for _, ff := range r.fileFields {
							ff.Close()
						}

					}()
					if _, err := io.Copy(wrtr, f); err != nil {
						pw.CloseWithError(err)
						log.Fatal(err)
					}
				}

			}()
			return req, nil
		}
		// write the form values as the body
		buf.WriteString(r.formFields.Encode())
		return req, nil
	}

	// if there is payload, use the producer to write the payload, and then
	// set the header to the content-type appropriate for the payload produced
	if r.payload != nil {
		// TODO: infer most appropriate content type based on the producer used,
		// and the `consumers` section of the spec/operation
		producer := producers[mediaType]
		if err := producer.Produce(buf, r.payload); err != nil {
			return nil, err
		}
		r.SetHeaderParam(httpkit.HeaderContentType, mediaType)
	}
	return req, nil
}

// SetHeaderParam adds a header param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetHeaderParam(name string, values ...string) error {
	if r.header == nil {
		r.header = make(http.Header)
	}
	r.header[http.CanonicalHeaderKey(name)] = values
	return nil
}<commit_msg>Bugfix for POST Ops not setting Content Length<commit_after>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/go-swagger/go-swagger/client"
	"github.com/go-swagger/go-swagger/httpkit"
	"github.com/go-swagger/go-swagger/strfmt"
)

// NewRequest creates a new swagger http client request
func newRequest(method, pathPattern string, writer client.RequestWriter) (*request, error) {
	return &request{
		pathPattern: pathPattern,
		method:      method,
		writer:      writer,
		header:      make(http.Header),
		query:       make(url.Values),
	}, nil
}

// Request represents a swagger client request.
//
// This Request struct converts to a HTTP request.
// There might be others that convert to other transports.
// There is no error checking here, it is assumed to be used after a spec has been validated.
// so impossible combinations should not arise (hopefully).
//
// The main purpose of this struct is to hide the machinery of adding params to a transport request.
// The generated code only implements what is necessary to turn a param into a valid value for these methods.
type request struct {
	pathPattern string
	method      string
	writer      client.RequestWriter

	pathParams map[string]string
	header     http.Header
	query      url.Values
	formFields url.Values
	fileFields map[string]*os.File
	payload    interface{}
}

var (
	// ensure interface compliance
	_ client.Request = new(request)
)

// BuildHTTP creates a new http request based on the data from the params
func (r *request) BuildHTTP(mediaType string, producers map[string]httpkit.Producer, registry strfmt.Registry) (*http.Request, error) {
	// build the data
	if err := r.writer.WriteToRequest(r, registry); err != nil {
		return nil, err
	}

	// create http request
	path := r.pathPattern
	for k, v := range r.pathParams {
		path = strings.Replace(path, "{"+k+"}", v, -1)
	}

	var body io.ReadCloser
	var pr *io.PipeReader
	var pw *io.PipeWriter
	buf := bytes.NewBuffer(nil)
	body = ioutil.NopCloser(buf)
	if r.fileFields != nil {
		pr, pw = io.Pipe()
		body = pr
	}
	req, err := http.NewRequest(r.method, path, body)
	if err != nil {
		return nil, err
	}
	req.URL.RawQuery = r.query.Encode()
	req.Header = r.header

	// check if this is a form type request
	if len(r.formFields) > 0 || len(r.fileFields) > 0 {
		// check if this is multipart
		if len(r.fileFields) > 0 {
			mp := multipart.NewWriter(pw)
			req.Header.Set(httpkit.HeaderContentType, mp.FormDataContentType())

			go func() {
				defer func() {
					mp.Close()
					pw.Close()
				}()

				for fn, v := range r.formFields {
					if len(v) > 0 {
						if err := mp.WriteField(fn, v[0]); err != nil {
							pw.CloseWithError(err)
							log.Fatal(err)
						}
					}
				}

				for fn, f := range r.fileFields {
					wrtr, err := mp.CreateFormFile(fn, filepath.Base(f.Name()))
					if err != nil {
						pw.CloseWithError(err)
						log.Fatal(err)
					}
					defer func() {
						for _, ff := range r.fileFields {
							ff.Close()
						}

					}()
					if _, err := io.Copy(wrtr, f); err != nil {
						pw.CloseWithError(err)
						log.Fatal(err)
					}
				}

			}()
			return req, nil
		}
		// write the form values as the body
		buf.WriteString(r.formFields.Encode())
		return req, nil
	}

	// if there is payload, use the producer to write the payload, and then
	// set the header to the content-type appropriate for the payload produced
	if r.payload != nil {
		// TODO: infer most appropriate content type based on the producer used,
		// and the `consumers` section of the spec/operation

		// set the content length of the request or else a chunked transfer is
		// declared, and this corrupts outgoing JSON payloads. the content's
		// length must be set prior to the body being written per the spec at
		// https://golang.org/pkg/net/http
		//
		//     If Body is present, Content-Length is <= 0 and TransferEncoding
		//     hasn't been set to "identity", Write adds
		//     "Transfer-Encoding: chunked" to the header. Body is closed
		//     after it is sent.
		//
		// to that end a temporary buffer, b, is created to produce the payload
		// body, and then its size is used to set the request's content length
		b := &bytes.Buffer{}
		producer := producers[mediaType]
		if err := producer.Produce(b, r.payload); err != nil {
			return nil, err
		}
		req.ContentLength = int64(b.Len())
		if _, err := buf.Write(b.Bytes()); err != nil {
			return nil, err
		}
		r.SetHeaderParam(httpkit.HeaderContentType, mediaType)
	}
	return req, nil
}

// SetHeaderParam adds a header param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetHeaderParam(name string, values ...string) error {
	if r.header == nil {
		r.header = make(http.Header)
	}
	r.header[http.CanonicalHeaderKey(name)] = values
	return nil
}
{'fraction_non_alphanumeric': 0.11126031076155764, 'fraction_numerical': 0.0031651640130443124, 'mean_word_length': 3.0150173276857912, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 11, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '184125', 'n_tokens_mistral': 3650, 'n_tokens_neox': 3252, 'n_words': 1176}