ENH: to_csv HTTP options / raw string compression
Hello,

I'm using changed to_csv method to write to correct:
- Raw string/bytes write with compression; when path_or_buf=None, it doesnt allow to compress it
- http(s) files with more options like method, headers (already exists) and other from requests module

If you think it can be added natively, would be nice

Br
Nicolas

```python
import typing, pandas, io
from pandas.core.generic import NDFrame
from urllib.parse import urlparse

def to_csv(
    self, path_or_buf: typing.Any = None, sep=',', na_rep='', float_format=None, columns=None, header=True, index=None,
    index_label=None, mode='w', encoding=None, compression='infer', quoting=None, quotechar='"',
    line_terminator=None, chunksize=None, date_format=None, doublequote=True, escapechar=None, decimal='.',
    errors='strict', storage_options=None
):
    if index is None:
        index = self.index.names[0] is not None # infer index write
    
    # Path/Buffer Check
    if isinstance(path_or_buf, str):
        url = urlparse(path_or_buf)
        
        if url.scheme in ('http', 'https'):
            
            # request method
            if mode.upper() not in ('GET', 'PUT', 'POST', 'UPDATE'):
                mode = 'UPDATE' if 'a' in mode else 'POST'
            
            if storage_options is None:
                storage_options = {
                    "method": mode, "verify": False, "headers": {}
                }
            else:
                for k, v in [
                    ('method', mode), ('verify', False), ('headers', {})
                ]:
                    storage_options[k] = storage_options.get(k, v)
                    
            if compression == 'infer': compression = None
            if encoding is None: encoding = 'utf-8'
                
            storage_options['headers']['Content-Type'] = 'text/csv' if compression is None else 'text/%s+csv' % compression
            storage_options['headers']['Content-Sep'] = sep
            storage_options['headers']['Content-Decimal'] = decimal
            storage_options['headers']['Content-Encoding'] = encoding
            if compression is not None:
                storage_options['headers']['Content-Compression'] = compression
            if line_terminator is not None:
                storage_options['headers']['Content-Line-Terminator'] = line_terminator
                
            storage_options['data'] = to_csv(
                self, path_or_buf=None,
                sep=sep, na_rep=na_rep, float_format=float_format, columns=columns, header=header,
                index=index, index_label=index_label, mode='w', encoding=encoding, compression=compression,
                quoting=quoting, quotechar=quotechar, line_terminator=line_terminator, chunksize=None,
                date_format=date_format, doublequote=doublequote, escapechar=escapechar, decimal=decimal,
                errors=errors, storage_options=None
            )
            
            if isinstance(storage_options['data'], str):
                storage_options['data'] = storage_options['data'].encode(encoding)
                
            with requests.request(
                url=path_or_buf, **storage_options
            ) as r:
                r.raise_for_status()
                return path_or_buf
        
        if '*' in path_or_buf:
            path_or_buf = path_or_buf.replace('*', str(uuid.uuid4()))
    
    if path_or_buf is None:
        # RuntimeWarning: compression has no effect when passing a non-binary object as input.
        if compression is None:
            return NDFrame.to_csv(
                self, path_or_buf=path_or_buf,
                sep=sep, na_rep=na_rep, float_format=float_format, columns=columns, header=header,
                index=index, index_label=index_label, mode=mode, encoding=encoding, compression=compression,
                quoting=quoting, quotechar=quotechar, line_terminator=line_terminator, chunksize=chunksize,
                date_format=date_format, doublequote=doublequote, escapechar=escapechar, decimal=decimal,
                errors=errors, storage_options=storage_options
            )
        path_or_buf = io.BytesIO()
        NDFrame.to_csv(
            self, path_or_buf=path_or_buf,
            sep=sep, na_rep=na_rep, float_format=float_format, columns=columns, header=header,
            index=index, index_label=index_label, mode=mode, encoding=encoding, compression=compression,
            quoting=quoting, quotechar=quotechar, line_terminator=line_terminator, chunksize=chunksize,
            date_format=date_format, doublequote=doublequote, escapechar=escapechar, decimal=decimal,
            errors=errors, storage_options=storage_options
        )
        path_or_buf.seek(0)
        return path_or_buf.read()
        
    NDFrame.to_csv(
        self, path_or_buf=path_or_buf,
        sep=sep, na_rep=na_rep, float_format=float_format, columns=columns, header=header,
        index=index, index_label=index_label, mode=mode, encoding=encoding, compression=compression,
        quoting=quoting, quotechar=quotechar, line_terminator=line_terminator, chunksize=chunksize,
        date_format=date_format, doublequote=doublequote, escapechar=escapechar, decimal=decimal,
        errors=errors, storage_options=storage_options
    )
    return path_or_buf
```