Skip to content

Instantly share code, notes, and snippets.

@faultier
Created September 27, 2010 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save faultier/598972 to your computer and use it in GitHub Desktop.
Save faultier/598972 to your computer and use it in GitHub Desktop.
<?php
$user_provider = 'livedoor'; // or 'pixiv', 'dlsite', etc.
$user_name = '<#USERNAME#>';
$blog_provider = $user_provider;
$blog_name = $user_name;
$api_key = '<#APIKEY#>';
$api_base_url = sprintf(
'http://%s.blogcms.jp/atom/%s/%s',
$user_provider,
($blog_provider === $user_provider ? 'blog' : $blog_provider),
$blog_name
);
$created = gmdate('Y-m-d\TH:i:s\Z');
$nonce = pack('H*', sha1(mt_rand()));
$digest = base64_encode(pack('H*',sha1($nonce.$created.$api_key)));
$token = sprintf(
'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
$user_name,
$digest,
base64_encode($nonce),
$created
);
$headers = array('X-WSSE: '.$token, 'Expect:');
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
// post jpeg image
//$filename = '<#FILENAME#>';
//$fh = fopen($filename,'r');
//$media = fread($fh,filesize($filename));
//fclose($fh);
//curl_setopt($ch, CURLOPT_URL, $api_base_url.'/image');
//curl_setopt($ch, CURLOPT_POSTFIELDS, $media);
//array_push($headers, 'Content-Type: image/jpeg');
// post article
$entry = <<< EOS
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app"
xmlns:blogcms="http://blogcms.jp/-/spec/atompub/1.0/">
<title>Article Title</title>
<updated>2011-07-28T00:00:00+09:00</updated>
<published>2011-07-28T00:00:00+09:00</published>
<category scheme="http://livedoor.blogcms.jp/blog/staff/category" term="Category" />
<blogcms:source>
<blogcms:body><![CDATA[<p>Body</p>]]></blogcms:body>
<blogcms:more><![CDATA[<p>Body More</p>]]></blogcms:more>
<blogcms:private><![CDATA[<p>Body Private</p>]]></blogcms:private>
</blogcms:source>
</entry>
EOS;
curl_setopt($ch, CURLOPT_URL, $api_base_url.'/article');
curl_setopt($ch, CURLOPT_POSTFIELDS, $entry);
array_push($headers, 'Content-Type: application/atom+xml;type=entry');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$res = curl_exec($ch);
curl_close($ch);
echo $res;
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
@interface NSDate (Atompub)
- (NSString *)stringFormattedISO8601;
@end
@implementation NSDate (Atompub)
- (NSString *)stringFormattedISO8601 {
NSUInteger unitFlags = NSYearCalendarUnit
| NSMonthCalendarUnit
| NSDayCalendarUnit
| NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit;
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[cal setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSDateComponents *comps = [cal components:unitFlags fromDate:self];
NSString *created = [NSString stringWithFormat:
@"%d-%02d-%02dT%02d:%02d:%02dZ",
[comps year],
[comps month],
[comps day],
[comps hour],
[comps minute],
[comps second]];
[cal release];
return created;
}
@end
@interface NSData (Atompub)
- (NSString *)stringEncodedBase64;
- (NSData *)SHA1Digest;
- (NSString *)SHA1DigestStringEncodedBase64;
@end
@implementation NSData (Atompub)
- (NSString *)stringEncodedBase64 {
static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const unsigned char *bytes = [self bytes];
NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
long position = 0;
long length = [self length];
char buffer[3];
char output[4];
while(position < length) {
int i;
for(i = 0; i < 3; i++ ) {
int j = position + i;
if(j < length) buffer[i] = bytes[j];
else buffer[i] = 0;
}
output[0] = (buffer[0] & 0xFC) >> 2;
output[1] = ((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4);
output[2] = ((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6);
output[3] = buffer[2] & 0x3F;
int buffer_length = ((length - position) < 3) ? (length - position) + 1 : 4;
for(i = 0; i < buffer_length; i++)
[result appendFormat:@"%c", table[output[i]]];
for(i = buffer_length; i < 4; i++)
[result appendString:@"="];
position += 3;
}
return result;
}
- (NSData *)SHA1Digest {
unsigned char digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([self bytes], [self length], digest);
return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
}
- (NSString *)SHA1DigestStringEncodedBase64 {
return [[self SHA1Digest] stringEncodedBase64];
}
@end
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *apiURL = [NSURL URLWithString:[NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding]];
NSString *userName = [NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding];
NSString *apiKey = [NSString stringWithCString:argv[3] encoding:NSUTF8StringEncoding];
NSData *image = [NSData dataWithContentsOfFile:[NSString stringWithCString:argv[4] encoding:NSUTF8StringEncoding]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:apiURL];
[request setTimeoutInterval:5];
[request setValue:@"LDBlogAtomPubTest/1.0" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:image];
[request setHTTPMethod:@"POST"];
NSString *created = [[NSDate date] stringFormattedISO8601];
NSString *nonce = [[[[[NSDate dateWithTimeIntervalSinceNow:rand()] description]
dataUsingEncoding:NSUTF8StringEncoding]
SHA1DigestStringEncodedBase64]
substringToIndex:7];
NSString *digest = [[[NSString stringWithFormat:@"%@%@%@",nonce,created,apiKey]
dataUsingEncoding:NSUTF8StringEncoding]
SHA1DigestStringEncodedBase64];
NSString *token = [NSString stringWithFormat:
@"UsernameToken Username=\"%@\", PasswordDigest=\"%@\", Nonce=\"%@\", Created=\"%@\"",
userName,
digest,
[[nonce dataUsingEncoding:NSUTF8StringEncoding] stringEncodedBase64],
created];
[request setValue:@"WSSE profile=\"UsernameToken\"" forHTTPHeaderField:@"Authorization"];
[request setValue:token forHTTPHeaderField:@"X-WSSE"];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *resData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
NSLog(@"%@", [NSString stringWithCString:[resData bytes] encoding:NSUTF8StringEncoding]);
[pool release];
return 0;
}
// vim: set ft=objc :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment