/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#ifndef DO_NO_IMPORTS
import "oaidl.idl";
import "ocidl.idl";
import "IWebURLRequest.idl";
#endif

interface IWebURLRequest;

[
    object,
    oleautomation,
    hidden,
    uuid(C4042773-371F-427e-AFA9-9D4B358A0D93),
    pointer_default(unique)
]
interface IWebMutableURLRequest : IWebURLRequest
{
    /*
        - (void)addValue:(NSString *)value forHTTPHeaderField:(NSString *)field
    */
    HRESULT addValue([in] BSTR value, [in] BSTR field);

    /*
        - (void)setAllHTTPHeaderFields:(NSDictionary *)headerFields
    */
    HRESULT setAllHTTPHeaderFields([in] IPropertyBag* headerFields);

    /*
        - (void)setCachePolicy:(NSURLRequestCachePolicy)policy
    */
    HRESULT setCachePolicy([in] WebURLRequestCachePolicy policy);

    /*
        - (void)setHTTPBody:(NSData *)data
    */
    HRESULT setHTTPBody([in] IStream* data);

    /*
        - (void)setHTTPBodyStream:(NSInputStream *)inputStream
    */
    HRESULT setHTTPBodyStream([in] IStream* data);

    /*
        - (void)setHTTPMethod:(NSString *)method
    */
    HRESULT setHTTPMethod([in] BSTR method);

    /*
        - (void)setHTTPShouldHandleCookies:(BOOL)handleCookies
    */
    HRESULT setHTTPShouldHandleCookies([in] BOOL handleCookies);

    /*
        - (void)setMainDocumentURL:(NSURL *)theURL
    */
    HRESULT setMainDocumentURL([in] BSTR theURL);

    /*
        - (void)setTimeoutInterval:(NSTimeInterval)timeoutInterval
    */
    HRESULT setTimeoutInterval([in] double timeoutInterval);

    /*
        - (void)setURL:(NSURL *)theURL
    */
    HRESULT setURL([in] BSTR theURL);

    /*
        - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
    */
    HRESULT setValue([in] BSTR value, [in] BSTR field);

    HRESULT setAllowsAnyHTTPSCertificate();
}
