XMPPHTTPFileUpload.m
3.19 KB
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//
// XMPPHTTPFileUpload.m
// Mangosta
//
// Created by Andres Canal on 5/19/16.
// Copyright © 2016 Inaka. All rights reserved.
//
#import "XMPPHTTPFileUpload.h"
@implementation XMPPHTTPFileUpload
- (id)init
{
// This will cause a crash - it's designed to.
return [self initWithServiceName:nil dispatchQueue:nil];
}
- (id)initWithDispatchQueue:(dispatch_queue_t)queue
{
// This will cause a crash - it's designed to.
return [self initWithServiceName:nil dispatchQueue:queue];
}
- (id)initWithServiceName:(NSString *)serviceName {
return [self initWithServiceName:serviceName dispatchQueue:nil];
}
- (id)initWithServiceName:(NSString *)serviceName dispatchQueue:(dispatch_queue_t)queue {
NSParameterAssert(serviceName != nil);
if ((self = [super initWithDispatchQueue:queue])){
_serviceName = serviceName;
}
return self;
}
- (BOOL)activate:(XMPPStream *)aXmppStream {
if ([super activate:aXmppStream]) {
responseTracker = [[XMPPIDTracker alloc] initWithDispatchQueue:moduleQueue];
return YES;
}
return NO;
}
- (void)deactivate {
dispatch_block_t block = ^{ @autoreleasepool {
[responseTracker removeAllIDs];
responseTracker = nil;
}};
if (dispatch_get_specific(moduleQueueTag))
block();
else
dispatch_sync(moduleQueue, block);
[super deactivate];
}
- (void)requestSlotForFilename:(NSString *) filename size:(NSInteger) size contentType:(NSString*) contentType {
dispatch_block_t block = ^{ @autoreleasepool {
// <iq from='romeo@montague.tld/garden' id='step_03'
// to='upload.montague.tld' type='get'>
// <request xmlns='urn:xmpp:http:upload'>
// <filename>my_juliet.png</filename>
// <size>23456</size>
// <content-type>image/jpeg</content-type>
// </request>
// </iq>
NSString *iqID = [XMPPStream generateUUID];
XMPPJID *uploadService = [XMPPJID jidWithString:self.serviceName];
XMPPIQ *iq = [XMPPIQ iqWithType:@"get" to:uploadService elementID:iqID];
XMPPElement *request = [XMPPElement elementWithName:@"request"];
[request setXmlns:XMPPHTTPFileUploadNamespace];
[request addChild:[XMPPElement elementWithName:@"filename" stringValue:filename]];
[request addChild:[XMPPElement elementWithName:@"size" numberValue:[NSNumber numberWithInteger:size]]];
[request addChild:[XMPPElement elementWithName:@"content-type" stringValue:contentType]];
[iq addChild:request];
[responseTracker addID:iqID
target:self
selector:@selector(handleRequestSlot:withInfo:)
timeout:60.0];
[xmppStream sendElement:iq];
}};
if (dispatch_get_specific(moduleQueueTag))
block();
else
dispatch_async(moduleQueue, block);
}
- (void)handleRequestSlot:(XMPPIQ *)iq withInfo:(id <XMPPTrackingInfo>)info{
if ([[iq type] isEqualToString:@"result"]){
XMPPSlot *slot = [[XMPPSlot alloc] initWithIQ:iq];
[multicastDelegate xmppHTTPFileUpload:self didAssignSlot:slot];
} else {
[multicastDelegate xmppHTTPFileUpload:self didFailToAssignSlotWithError:iq];
}
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
NSString *type = [iq type];
if ([type isEqualToString:@"result"] || [type isEqualToString:@"error"])
{
return [responseTracker invokeForID:[iq elementID] withObject:iq];
}
return NO;
}
@end