Re: Uploading file to auth http server, when login url is different to upload url??

  • Hi Theodore,

    It is complicated; passing POST parameters as parts of forms involves
    quite a bit of tomfoolery. I looked at the source for W3 client,
    though, and it's about 1700 lines for the two files comprising over
    750 line of C++ code.  I'm very impressed at what you consider "easy" ;)

    You should not have to do anything http manually on the mac; you can
    use NSURLConnection, NSMutableURLRequest and -- yes -- a delegate of
    your own writing.  You can set the method and store the user/password
    (this is more complicated than Windows), but you can use the same
    delegate for both.

    You will still have to put together the POST buffer manually from the
    arguments, but you should be able to use the W3Client sources to do
    that; as far as I can tell HTTP_ARGS should port fairly easily, it
    mostly uses standard C++ and the templates.

    Here is some "starter kit" code, perhaps it will help.  It doesn't
    handle errors, it doesn't create the POST buffer.. hope it helps.

    -- Rudi

    @interface W3Client : NSObject
    {
    NSString *mUser;
    NSString *mPassword;

    NSData *mArgData;    // these should be vectors or lists but you get
    the idea
    NSString *mArgParam;

    BOOL mDone;
    }
    - (W3Client *) initWithUser: (NSString *) user password: (NSString *)
    password;
    - (void) firstConnectToURL: (NSURL *) URL;
    - (void) addPostArgument: (NSString *) argName (NSData *) argData;
    - (void) postThisData: (NSData *) data toURL: (NSURL *) URL;

    - (void)connection:(NSURLConnection *)connection
    didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)
    challenge;
    -(NSURLRequest *)connection:(NSURLConnection *)connection
    willSendRequest:(NSURLRequest *)request redirectResponse:
    (NSURLResponse *)redirectResponse;

    - (void) dealloc;

    @end

    @implementation W3Client

    - (W3Client *) initWithUser: (NSString *) user password: (NSString *)
    password
    {
    self = [ super init ];
    if ( self != nil )
    {
      mUser = [ user retain ];
      mPassword = [ password retain ];
      mDone = NO;
    }
    return self;
    }

    - (void)connection:(NSURLConnection *)connection
    didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)
    challenge
    {
    [ [ challenge sender ] useCredential: [ NSURLCredential
    credentialWithUser:
            mUser password:
            mPassword persistence: NSURLCredentialPersistenceForSession ]
          forAuthenticationChallenge: challenge ];
    }

    -(NSURLRequest *)connection:(NSURLConnection *)connection
    willSendRequest:(NSURLRequest *)request redirectResponse:
    (NSURLResponse *)redirectResponse
    {
    return request;
    }

    - (void) addPostArgument: (NSString *) argName (NSData *) argData
    {
    }

    -(void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
    mDone = YES;
    }

    - (void)connection:(NSURLConnection *)connection didFailWithError:
    (NSError *)error
    {
    mDone = YES;
    }

    - (void) dealloc
    {
    [ mUser release ];
    [ mPassword release ];
    [ mArgData release ];
    [ mArgName release ];
    [ super dealloc ];
    }

    - (void) firstConnectToURL: (NSURL *) URL
    {
    NSURLRequest *r = [ NSURLRequest requestWithURL: URL ];
    NSURLConnection *c = [ NSURLConnection connectionWithRequest: r
    delegate: self ];
    while ( !mDone )
      [ [ NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopMode
    beforeDate: [ NSDate dateWithTimeIntervalSinceNow: 0.2 ] ];
    }

    - (void) postToURL: (NSURL *) URL
    {
    NSMutableURLRequest *r = [ NSMutableURLRequest requestWithURL: URL ];
    [ r setHTTPMethod: @"POST" ];

    // The hard part: creating the data buffer from the parameters; left
    to the reader as an exercise.
    NSData *data = CreateDataFromArgs(mArgName, mArgData);

    [ r setHTTPBody: data ];
    NSURLConnection *c = [ NSURLConnection connectionWithRequest: r
    delegate: self ];
    while ( !mDone )
      [ [ NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopMode
    beforeDate: [ NSDate dateWithTimeIntervalSinceNow: 0.2 ] ];
    }

    - (void) addPostArgument: (NSString *) argName (NSData *) argData
    {
    //    This can use the same std list and pairs as W3Client, for now just
    one param.
    mArgData = [ argData retain ];
    mArgName = [ argName retain ];
    }

    @end

    On Nov 1, 2006, at 9:20 AM, <cocoa-dev-request...> wrote:

    > Message: 19
    > Date: Wed, 1 Nov 2006 17:18:40 +0000
    > From: "Theodore H. Smith" <delete...>
    > Subject: Uploading file to auth http server,    when login url is
    > different to upload url??
    > To: Cocoa List <cocoa-dev...>
    > Message-ID: <7C781872-AFD9-4F97-8E65-027EF6E901B5...>
    > Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
    >
    > Hi people,
    >
    > I'm trying to do something that is actually quite simple on the PC,
    > but for the Mac I'm finding this hard. So this is a bit of a shame
    > really.
    >
    > I want to log into into a certain url with http auth by supplying a
    > name and password, and without breaking the http connection, then
    > upload a file to a different url!
    >
    > It's done on the PC using this library called W3Client which was
    > found on codeproject.com:
    >
    > W3Client w3;
    >
    > w3.Connect("http://gdst2.simslearning.co.uk/learnwise", username,
    > password); // logs in here
    >
    > w3.AddPostArgument("course", strFile, TRUE);
    >
    > w3.Request("/coursebuilder/importCourse/org/dep",
    > W3Client::reqPostMultipartsFormdata); // uploads!
    >
    >
    > See, easy!
    >
    > w3.Request will connect to the URL "http://gdst2.simslearning.co.uk/
    > learnwise/coursebuilder/importCourse/org/dep"
    >
    > So basically, it appends the thing to the URL it connected to.
    >
    > The uploading is done via the Post argument thingy.
    >
    > So, I can do this with 4 lines of code on the PC using W3Client.
    >
    > I tried with curl, which eventually I found couldn't work, simply
    > because... I can't log into one url and then upload to another.
    > Believe me I tried all sorts of different combinations with curl. I
    > tried multiple connection attempts (calling curl then calling it
    > again after it completes). I tried passing two urls to curl, that
    > also failed because the login page refuses to login if I've got any
    > POST arguments!
    >
    > It just won't work.
    >
    > I don't see the ability to post arguments using Cocoa? And also the
    > API is really hard to use. It's delegate madness and class madness. I
    > must use about 4 classes and a delegate to do something I could do
    > with 4 lines of code with W3Client. W3Client is written for the Win32
    > API however. And even then I haven't seen http post with
    > NSURLConnection, and I haven't seen the ability to log into a
    > different page than you upload to.
    >
    > So how can I upload using http post to a different url than the one I
    > logged in, to acheive what I did with the above 4 lines of W3Client
    > code?
    >
    > Can Macs even do this?
    >
    > Must I resort to writing my own socket wrapper and do all the http
    > stuff manually? :(
    >
    > --
    > http://elfdata.com/plugin/
    >
previous month november 2006 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      
Go to today