-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
608 lines (293 loc) · 40 KB
/
index.html
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Jonathan Hernandez</title>
<meta name="author" content="Jonathan Hernandez">
<meta name="description" content="I’ve not found any blog post or article about how to easily test CORS support implemented in a Rack middleware (e.g. using the rack-cors gem) …">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="http://jbilbo.com">
<link href="/favicon.png" rel="icon">
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
<link href="/atom.xml" rel="alternate" title="Jonathan Hernandez" type="application/atom+xml">
<script src="/javascripts/modernizr-2.0.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="./javascripts/libs/jquery.min.js"%3E%3C/script%3E'))</script>
<script src="/javascripts/octopress.js" type="text/javascript"></script>
<!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="//fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Fjalla+One" rel="stylesheet" type="text/css">
<!--- MathJax Configuration -->
<script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="collapse-sidebar sidebar-footer" >
<header role="banner"><hgroup>
<h1><a href="/">Jonathan Hernandez</a></h1>
<h2>Rails developer. Free (as in freedom) software enthusiast. Gamer.</h2>
</hgroup>
</header>
<nav role="navigation"><ul class="subscribe" data-subscription="rss">
<li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25" height="25" viewbox="0 0 100 100"><path class="social" d="M 13.310204,73.332654 C 5.967347,73.332654 0,79.322448 0,86.621428 c 0,7.338776 5.967347,13.262246 13.310204,13.262246 7.370408,0 13.328572,-5.92245 13.328572,-13.262246 0,-7.29898 -5.958164,-13.288774 -13.328572,-13.288774 z M 0.01530612,33.978572 V 53.143878 C 12.493878,53.143878 24.229592,58.02347 33.068368,66.865306 41.894898,75.685714 46.767346,87.47449 46.767346,100 h 19.25 C 66.017346,63.592858 36.4,33.979592 0.01530612,33.978572 l 0,0 z M 0.03877552,0 V 19.17449 C 44.54796,19.17551 80.77551,55.437756 80.77551,100 H 100 C 100,44.87653 55.15102,0 0.03877552,0 z"></path></svg></a></li>
</ul>
<ul class="subscribe">
<li><a href="https://github.com/jbilbo" rel="subscribe-github" title="@jbilbo on GitHub"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25" height="25" viewbox="0 0 100 100"><path class="social" d="M 50,0 C 22.385714,0 0,22.385714 0,50 0,77.614286 22.385714,100 50,100 77.614286,100 100,77.614286 100,50 100,22.385714 77.614286,0 50,0 z m 29.692858,79.692858 c -3.859184,3.859182 -8.351022,6.887754 -13.35,9.00306 -1.27041,0.536736 -2.560204,1.009184 -3.867348,1.415306 v -7.493878 c 0,-3.938774 -1.35102,-6.835714 -4.053062,-8.690816 1.692858,-0.163264 3.24694,-0.390816 4.663266,-0.683672 1.416326,-0.292858 2.913266,-0.716328 4.491838,-1.27041 1.57857,-0.55408 2.994896,-1.213264 4.247958,-1.97755 1.253062,-0.765306 2.458164,-1.758164 3.613266,-2.978572 1.155102,-1.220408 2.12449,-2.604082 2.905102,-4.15 0.780612,-1.545918 1.4,-3.40204 1.855102,-5.566326 0.455102,-2.164286 0.683674,-4.54898 0.683674,-7.153062 0,-5.045918 -1.643878,-9.341836 -4.931634,-12.890816 C 77.44796,33.35 77.285714,29.10204 75.463266,24.512244 l -1.22143,-0.145918 c -0.845918,-0.09796 -2.368366,0.260204 -4.565306,1.07449 -2.196938,0.814286 -4.663264,2.14796 -7.396938,4.004082 -3.87449,-1.07449 -7.893878,-1.611224 -12.061224,-1.611224 -4.19898,0 -8.203062,0.536734 -12.012246,1.611224 -1.72449,-1.17245 -3.361224,-2.139796 -4.907142,-2.905102 C 31.753062,25.77449 30.516326,25.254082 29.587756,24.97653 28.660204,24.7 27.79796,24.528572 27,24.463266 c -0.79796,-0.0653 -1.310204,-0.08062 -1.537756,-0.04898 -0.22755,0.03164 -0.390816,0.0653 -0.487754,0.09796 -1.82347,4.62245 -1.985714,8.87143 -0.487756,12.743878 -3.287754,3.54796 -4.931632,7.844898 -4.931632,12.890816 0,2.604082 0.227552,4.988776 0.683674,7.153062 0.456122,2.164286 1.07449,4.020408 1.855102,5.566326 0.780612,1.545918 1.75,2.929592 2.905102,4.15 1.155102,1.220408 2.360204,2.213266 3.613264,2.978572 1.253062,0.766326 2.669388,1.42449 4.24796,1.97755 1.578572,0.554082 3.07551,0.976532 4.491836,1.27041 1.416328,0.292856 2.970408,0.521428 4.663266,0.683672 -2.669388,1.82347 -4.004082,4.720408 -4.004082,8.690816 v 7.639796 C 36.536734,89.818368 35.083674,89.3 33.656122,88.695918 c -4.99898,-2.115306 -9.490816,-5.143878 -13.35,-9.00306 -3.859184,-3.859184 -6.887754,-8.351022 -9.00306,-13.35 C 9.1163263,61.171428 8.0071428,55.67347 8.0071428,50 c 0,-5.67347 1.1091835,-11.171428 3.2969392,-16.342858 2.115306,-4.998978 5.143878,-9.490816 9.00306,-13.35 3.859184,-3.859182 8.351022,-6.887754 13.35,-9.00306 C 38.828572,9.1163266 44.32653,8.0071428 50,8.0071428 c 5.67347,0 11.171428,1.1091838 16.342858,3.2969392 5,2.115306 9.490816,5.143878 13.35,9.00306 3.859182,3.859184 6.887754,8.351022 9.00306,13.35 2.186736,5.17245 3.295918,10.67041 3.295918,16.342858 0,5.672448 -1.109182,11.171428 -3.296938,16.342858 -2.115306,4.998978 -5.143878,9.490816 -9.00204,13.35 l 0,0 z"></path></svg></a></li>
</ul>
<form action="https://www.google.com/search" method="get">
<fieldset role="search">
<input type="hidden" name="q" value="site:jbilbo.com" />
<input class="search" type="text" name="q" results="0" placeholder="Search"/>
</fieldset>
</form>
<ul class="main-navigation">
<li><a href="/">Blog</a></li>
<li><a href="/blog/archives">Archives</a></li>
<li><a href="http://about.me/jbilbo">About me</a></li>
</ul>
</nav>
<div id="main">
<div id="content">
<div class="blog-index">
<article>
<header>
<h1 class="entry-title"><a href="/blog/2015/05/19/testing-cors-with-rspec/">Testing CORS Headers With RSpec and Rack in Rails</a></h1>
<p class="meta">
<time class='entry-date' datetime='2015-05-19T01:16:17+01:00'><span class='date'><span class='date-month'>May</span> <span class='date-day'>19</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>1:16 am</span></time>
| <a href="/blog/2015/05/19/testing-cors-with-rspec/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content"><p>I’ve not found any blog post or article about how to easily test <a href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS</a> support implemented in a <a href="http://rack.github.io/">Rack</a> middleware (e.g. using the <a href="https://github.com/cyu/rack-cors">rack-cors</a> gem) with RSpec in Rails. So, after figured out I decided to write some small tips I learned from it.</p>
<p>I assume you have a fairly updated Rails app, I tested it with Rails 4.2.x, with <code>RSpec</code> tests support, and you want to add support for <code>CORS</code> headers.</p>
<h2>Install rack-cors gem</h2>
<p>it’s better to follow the gem instructions (you’ll find the most updated instructions there) than a blog post, but anyway here’s how I did it:</p>
<p>Add this to your <code>Gemfile</code>:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>gem <span class="s1">'rack-cors'</span>, :require <span class="o">=</span>> <span class="s1">'rack/cors'</span>
</span></code></pre></td></tr></table></div></figure>
<p>Add this to your <code>config/application.rb</code>:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">middleware</span><span class="o">.</span><span class="n">insert_before</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">"Rack::Cors"</span><span class="p">,</span> <span class="ss">logger</span><span class="p">:</span> <span class="p">(</span><span class="o">-></span> <span class="p">{</span> <span class="no">Rails</span><span class="o">.</span><span class="n">logger</span> <span class="p">}))</span> <span class="k">do</span>
</span><span class='line'> <span class="n">allow</span> <span class="k">do</span>
</span><span class='line'> <span class="n">origins</span> <span class="s1">'*'</span>
</span><span class='line'> <span class="n">resource</span> <span class="s1">'*'</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="ss">:any</span><span class="p">,</span> <span class="nb">methods</span><span class="p">:</span> <span class="o">[</span><span class="ss">:get</span><span class="p">,</span> <span class="ss">:post</span><span class="p">,</span> <span class="ss">:patch</span><span class="p">,</span> <span class="ss">:options</span><span class="o">]</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>These are the common options, tune it to your needs. Here we’re allowing requests from any domain for the <code>get</code>, <code>post</code>, <code>patch</code> and <code>options</code> methods. <code>options</code> is a special method used for <a href="http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/">preflight</a> requests.</p>
<p>That’s it. <code>CORS</code> is now active in this Rails app. Every time we send a request with the <code>CORS</code> headers, we’ll receive the <code>CORS</code> response headers.</p>
<h2>How to test it with cURL</h2>
<p>With <a href="http://curl.haxx.se/">cURL</a>, it’s easy to test <code>CORS</code>. Let’s see the most common scenarios:</p>
<h4>Sending the <code>Origin</code> header:</h4>
<ul>
<li><code>-H</code>: Header to include in the request.</li>
<li><code>-I</code>: Fetch the <code>HTTP</code> header only.</li>
</ul>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>curl -H <span class="s2">"Origin:*"</span> -I http://localhost:3000/people/1234
</span></code></pre></td></tr></table></div></figure>
<p>We should receive: <code>Access-Control-Allow-Origin: *</code>.</p>
<h4>Sending the preflight options method:</h4>
<p>Send a options request with <code>Origin: *</code>, <code>Access-Control-Request-Method: get</code> and <code>Access-Control-Request-Headers: test</code>.
* <code>-X</code>: Specifies a custom request method</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>curl -X OPTIONS -I http://localhost:3000 -H <span class="s1">'Origin: *'</span> -H <span class="s1">'Access-Control-Request-Method: GET'</span> -H <span class="s1">'Access-Control-Request-Headers: test'</span>
</span></code></pre></td></tr></table></div></figure>
<p>We should receive <code>Access-Control-Allow-Origin: *</code>, <code>Access-Control-Allow-Methods: get, post, patch, options</code>, and <code>Access-Control-Allow-Headers: test</code>.</p>
<h2>How to test it with <code>RSpec</code></h2>
<p>Support CORS is a bit tricky to test with <code>RSpec</code>, because we don’t have a real server (like <a href="https://github.com/nahi/webrick">Webrick</a>, <a href="http://unicorn.bogomips.org/">Unicorn</a> or <a href="https://github.com/puma/puma">Puma</a>) between the code and the client. This usually is not a problem but it does affect in this particular case, and the <a href="https://tools.ietf.org/html/rfc3875#section-4.1.18">rfc3875</a> explains why. The server translate the custom <code>HTTP</code> request headers in this way:</p>
<ul>
<li>Convert to upper case.</li>
<li>Replace <code>-</code> with <code>_</code></li>
<li>Prepend <code>HTTP_</code>.</li>
</ul>
<p>Because we don’t have the server to do it for us, we must do it manually. For example, the <code>Origin</code> becomes <code>HTTP_ORIGIN</code> and <code>Http-Access-Control-Request-Method</code> becomes <code>HTTP_ACCESS_CONTROL_REQUEST_METHOD</code>.
Let’s see some example tests:</p>
<h4>Sending the Origin header:</h4>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">RSpec</span><span class="o">.</span><span class="n">feature</span> <span class="s2">"the requests support CORS headers"</span><span class="p">,</span> <span class="ss">type</span><span class="p">:</span> <span class="ss">:feature</span> <span class="k">do</span>
</span><span class='line'> <span class="n">scenario</span> <span class="s1">'Returns the response CORS headers'</span> <span class="k">do</span>
</span><span class='line'> <span class="n">get</span> <span class="s1">'/people/1234'</span><span class="p">,</span> <span class="kp">nil</span><span class="p">,</span> <span class="s1">'HTTP_ORIGIN'</span> <span class="o">=></span> <span class="s1">'*'</span>
</span><span class='line'>
</span><span class='line'> <span class="n">expect</span><span class="p">(</span><span class="n">last_response</span><span class="o">.</span><span class="n">headers</span><span class="o">[</span><span class="s1">'Access-Control-Allow-Origin'</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">to</span> <span class="n">eq</span><span class="p">(</span><span class="s1">'*'</span><span class="p">)</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<h4>Sending the preflight options method:</h4>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">RSpec</span><span class="o">.</span><span class="n">feature</span> <span class="s2">"the requests support CORS headers"</span><span class="p">,</span> <span class="ss">type</span><span class="p">:</span> <span class="ss">:feature</span> <span class="k">do</span>
</span><span class='line'> <span class="n">scenario</span> <span class="s1">'Send the CORS preflight OPTIONS request'</span> <span class="k">do</span>
</span><span class='line'> <span class="n">options</span> <span class="s1">'/'</span><span class="p">,</span> <span class="kp">nil</span><span class="p">,</span> <span class="s1">'HTTP_ORIGIN'</span> <span class="o">=></span> <span class="s1">'*'</span><span class="p">,</span> <span class="s1">'HTTP_ACCESS_CONTROL_REQUEST_METHOD'</span> <span class="o">=></span> <span class="s1">'GET'</span><span class="p">,</span> <span class="s1">'HTTP_ACCESS_CONTROL_REQUEST_HEADERS'</span> <span class="o">=></span> <span class="s1">'test'</span>
</span><span class='line'>
</span><span class='line'> <span class="n">expect</span><span class="p">(</span><span class="n">last_response</span><span class="o">.</span><span class="n">headers</span><span class="o">[</span><span class="s1">'Access-Control-Allow-Origin'</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">to</span> <span class="n">eq</span><span class="p">(</span><span class="s1">'*'</span><span class="p">)</span>
</span><span class='line'> <span class="n">expect</span><span class="p">(</span><span class="n">last_response</span><span class="o">.</span><span class="n">headers</span><span class="o">[</span><span class="s1">'Access-Control-Allow-Methods'</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">to</span> <span class="n">eq</span><span class="p">(</span><span class="s1">'GET, POST, PATCH, OPTIONS'</span><span class="p">)</span>
</span><span class='line'> <span class="n">expect</span><span class="p">(</span><span class="n">last_response</span><span class="o">.</span><span class="n">headers</span><span class="o">[</span><span class="s1">'Access-Control-Allow-Headers'</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">to</span> <span class="n">eq</span><span class="p">(</span><span class="s1">'test'</span><span class="p">)</span>
</span><span class='line'> <span class="n">expect</span><span class="p">(</span><span class="n">last_response</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span><span class="o">.</span><span class="n">to</span> <span class="n">have_key</span><span class="p">(</span><span class="s1">'Access-Control-Max-Age'</span><span class="p">)</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>Note: You must use integration tests to be able the test through <code>rack</code>. A controller test doesn’t trigger <code>rack</code>, it’s like an unit test for the controller.</p>
<p>Don’t forget to uppercase, replace <code>-</code> and prepend <code>HTTP_</code> to all your custom HTTP headers when testing!</p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2014/12/18/relanzando-el-blog/">Relanzando El Blog</a></h1>
<p class="meta">
<time class='entry-date' datetime='2014-12-18T19:04:49+00:00'><span class='date'><span class='date-month'>Dec</span> <span class='date-day'>18</span><span class='date-suffix'>th</span>, <span class='date-year'>2014</span></span> <span class='time'>7:04 pm</span></time>
| <a href="/blog/2014/12/18/relanzando-el-blog/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content"><p>En estos últimos 3 años no he escrito casi nada, creo que <a href="http://twitter.com/jbilbob">Twitter</a> tiene gran parte de culpa. El hecho de ir poniendo por ahí comentarios cortos como que me hizo perder las ganas de invertir en más de 140 caracteres, quizás también pensando que la gente ya no invierte tanto tiempo en leer artículos como antes. No es nuevo que hemos ido hacia el consumo rápido, tiene lógica teniendo en cuenta la cantidad enorme de información a la que tenemos acceso diariamente. Un formato como Twitter, el formato “titular”, es más óptimo para el consumidor, que adquiere multitud de pequeñas gotas de información de las cuales unas pocas que filtrará las expandirá un poco más accediendo al enlace.</p>
<p>Mientras Twitter sigue siendo una opción muy válida, creo que seguir poniendo pensamientos, tutoriales y demás en un blog es algo enriquecedor para el autor, y en ocasiones útil para el lector. Puede que nadie lo lea, o muy pocos, pero el propósito del músico no es que su canción tenga éxito (aunque eso está muy bien), sinó componer, tocar o cantar.</p>
<p>Una de las cosas que quiero también aprovechar con el blog para mejorar es mi escritura del inglés. Creo que los artículos técnicos es una buena manera de hacerlo, es un tipo de artículo que puede servir a nivel global y la audiencia a la que va dirigida es muy probable que entienda el inglés, como mínimo el escrito.</p>
<p>Pues eso es todo, por ahora el único cambio importante en el blog es la migración que he hecho de <a href="http://blogger.com">Blogger</a> a <a href="http://github.com/jbilbo">Github</a> usando <a href="http://jekyllrb.com">Jekyll</a> y <a href="http://octopress.org">Octopress</a>.</p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2014/07/11/ms-sqlserver-numeric-primary-key/">MS SQLServer Numeric Primary Key Hibernate</a></h1>
<p class="meta">
<time class='entry-date' datetime='2014-07-11T02:29:00-07:00'><span class='date'><span class='date-month'>Jul</span> <span class='date-day'>11</span><span class='date-suffix'>th</span>, <span class='date-year'>2014</span></span> <span class='time'>2:29 am</span></time>
| <a href="/blog/2014/07/11/ms-sqlserver-numeric-primary-key/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Related to this old hibernate problem: <a href="http://grails.1312388.n4.nabble.com/MS-SQLServer-numeric-primary-key-hibernate-td3565392.html">http://grails.1312388.n4.nabble.com/MS-SQLServer-numeric-primary-key-hibernate-td3565392.html</a><br /><br /><blockquote class="tr_bq"><span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;">By default Gorm/hiberate is generating id columns as the numeric(19,0) on SQLServer. I’d like those to be of type BIGINT instead.</span></blockquote><span style="background-color: white; font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13px;"><br /></span>The solution is to use the correct dialect for hibernate. In Grails, you can configure it like this:<br /><br />grails-app/conf/DataSource.groovy:<br /><br /> dataSource {<br /> driverClassName = “com.microsoft.sqlserver.jdbc.SQLServerDriver”<br /> username = “xxx”<br /> password = “xxx”<br /> dbCreate = “create-drop” // one of ‘create’, ‘create-drop’, ‘update’, ‘validate’, ”<br /> url = “jdbc:sqlserver://host\instance;databaseName=databaseName”<br /> <b>dialect = “org.hibernate.dialect.SQLServer2008Dialect”</b><br /> }<br /><div><br /></div></div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2011/10/07/que-yo-tenga-que-defender-steve-jobs-y/">Que Yo Tenga Que Defender a Steve Jobs Y Apple…</a></h1>
<p class="meta">
<time class='entry-date' datetime='2011-10-07T00:57:00-07:00'><span class='date'><span class='date-month'>Oct</span> <span class='date-day'>7</span><span class='date-suffix'>th</span>, <span class='date-year'>2011</span></span> <span class='time'>12:57 am</span></time>
| <a href="/blog/2011/10/07/que-yo-tenga-que-defender-steve-jobs-y/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content"><p><em>Nota: A raíz de la muerte de Steve Jobs, no me gusta nada cómo se frivoliza por parte de algunos blogs/comentarios la aportación de Apple al mundo de la tecnología. Cabe decir que yo jamás he comprado para mi NADA de Apple, y además soy desarrollador de Android.</em></p>
<p>Quizás la crítica más frecuente a Apple tiene que ver con el fenómeno fanboy. En relación al fanboyismo o elitismo, es un problema que podemos encontrar en cualquier ámbito: Los videojuegos, (entre marcas como Nintendo, Sega, Sony o plataformas como Consolas vs PC), marcas de coche (Ferrari, Porsche…), deportes y un largo etc. Esta parte de Apple no me interesa nada, así que ni voy a entrar.</p>
<p>Lo importante: ¿Qué ha hecho Apple bien? Es muy sencillo y a la vez complicado, pero que se resume en: <strong>Impulsar mercados</strong></p>
<p>Los smartphones empezaron después del iPhone. Por supuesto antes del iPhone habían smartphones pero el producto de apple fué el que impulsó el mercado de los smartphones. Con los mp3 y el iPod pasó igual pero me interesa más el mercado de los smartphones y las tablet (iPad, también lo mismo).
Pero mi impulso de mercado preferido fué el de las apps, lo que considero ha generado una época dorada para el programador (sobretodo el indie, tanto de juegos como de aplicaciones de cualquier tipo), y que ha supuesto muchísimos puestos de trabajo.</p>
<p>Y qué ha hecho Steve Jobs en concreto:</p>
<p>Pues de todo esto él tiene mucha culpa, pero quizás lo que fascina a mucha gente de su figura es la capacidad de echarse a las espaldas a una empresa a punto de morir y ponerla en la número 1 mundial (<a href="http://www.elpais.com/articulo/economia/Apple/supera/Exxon/empresa/valiosa/mundo/elpepueco/20110809elpepueco_10/Tes">la jodida número 1</a> del todo el planeta, que es muy fácil decirlo, por encima de: Microsoft, Google (en tecnología) y por encima incluso de petroleras que eran las número 1 indiscutibles hasta el momento).</p>
<p>¿Steve Jobs es un cabrón? He oído de gente que lo afirma. No lo sé, pero es un tema que puedo ni podré entrar a valorar porque no he trabajado con él. Lo que sí creo es que es un genio, en su campo de trabajo: Sabe lo que quiere la gente, sabe poner precio a las cosas sin perder dinero, sabe perfilar los detalles, sabe presentar las cosas, sabe hablar en público como pocos, un carisma inmenso, este tío SABE de su trabajo. No tiene porqué ser talentoso en todo lo que hace, a lo mejor sabe rodearse de otros que saben lo que hacen. En cualquier caso, la finalidad es conseguir el objetivo que te propones. Y eso, se le ha dado muy bien. ¿Las maneras? Sólo unos pocos las conocen. Quizás no sean éticas, no lo sé, eso es algo que jamás podré valorar y por tanto no entraré.</p>
<p>Desde la propia Google (por nombrar a su mayor competencia) también se le admira, por ej. mirad este post de Vic Gundotra (Senior vicepres. de Google), 25 de agosto: <a href="https://plus.google.com/107117483540235115863/posts/gcSStkKxXTw" style="color: #1155cc;" target="_blank"><a href="https://plus.google.com/107117483540235115863/posts/gcSStkKxXTw">https://plus.google.com/107117483540235115863/posts/gcSStkKxXTw</a></a> </p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2010/06/21/woices-para-android/">Woices Para Android</a></h1>
<p class="meta">
<time class='entry-date' datetime='2010-06-21T14:27:00-07:00'><span class='date'><span class='date-month'>Jun</span> <span class='date-day'>21</span><span class='date-suffix'>st</span>, <span class='date-year'>2010</span></span> <span class='time'>2:27 pm</span></time>
| <a href="/blog/2010/06/21/woices-para-android/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Mi último proyecto (o subproyecto dentro del GRAN proyecto <a href="http://woices.com/">Woices</a>) es la aplicación de esta plataforma para el sistema operativo libre de Google: <a href="http://www.android.com/">Android</a>. <br /><br />Hay una <a href="http://en.wikipedia.org/wiki/List_of_Android_devices">gran lista</a> de dispositivos que usan Android, sobretodo teléfonos móviles, algunos de los más populares son los HTC <a href="http://www.htc.com/es/product/magic/overview.html">Magic</a>, <a href="http://www.htc.com/es/product/hero/overview.html">Hero</a>, <a href="http://www.htc.com/es/product/desire/overview.html">Desire</a>, Evo 4G, <a href="http://www.google.com/phone/">Nexus One</a>… o el Motorola <a href="http://www.motorola.com/Consumers/ES-ES/Consumer-Products-and-Services/Mobile-Phones/Motorola-MILESTONE-ES-ES">Droid/Milestone</a>.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://woices.com/android" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/_Nv1OUwX9fDo/TB-pUzz50pI/AAAAAAAAADQ/u6OEv2FQR9M/s320/droid-with-woices.png" /></a></div><br />Después de estar más de 2 meses empapándome de documentación, APIs, conferencias, código fuente de ejemplo y búsquedas en google, google groups, stackoverflow y en mis notas de Tomboy y papeles con dibujitos o esquemas en Google Docs… por fin ha salido a la luz la primera versión de <a href="http://woices.com/android">woices para android</a>.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://woices.com/android" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://1.bp.blogspot.com/_Nv1OUwX9fDo/TB_YJXvGquI/AAAAAAAAADg/vlGp4eIhwQI/s400/woices-guia-patrocinada.png" width="237" /></a></div><br />La idea es que lleves la aplicación “a cuestas” y puedas beneficiarte in-situ de la información (audioguías) que los usuarios dejan en los diferentes puntos del planeta en forma de audio. Puedes encontrate <a href="http://woices.com/help#echo1">ecos</a>, <a href="http://woices.com/help#walk1">rutas</a> o <a href="http://woices.com/guides">guías patrocinadas </a>según el sitio donde estés. También esta disponible la función de búsqueda (por título, lugar, ciudad o <a href="http://woices.com/help#mobile2">e-code</a>).<br /><br />Si tienes un teléfono Android <a href="http://woices.com/android">pruébala</a> y dime qué te parece. Mientras, sigo trabajando en la siguiente versión.</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2010/05/05/ii-jornadas-de-gpltarragona/">II Jornadas De GPLTarragona</a></h1>
<p class="meta">
<time class='entry-date' datetime='2010-05-05T09:46:00-07:00'><span class='date'><span class='date-month'>May</span> <span class='date-day'>5</span><span class='date-suffix'>th</span>, <span class='date-year'>2010</span></span> <span class='time'>9:46 am</span></time>
| <a href="/blog/2010/05/05/ii-jornadas-de-gpltarragona/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Mañana son las II Jornadas de GPLTarragona:<br /><br /><i>Per celebrar el 7e aniversari de l’associació GPL Tarragona i continuar demostrant el compromís per promocionar les tecnologies de la informació i el programari lliure a la província de Tarragona, el dijous 6 de maig de 2010 tindran lloc les II Jornades GPL Tarragona a la Sala de Graus del campus Sescelades (ETSE – Universitat Rovira i Virgili).<br /><br />Les jornades són completament gratuïtes i es troben destinades a professionals, aficionats, professors i estudiants en general.<br /><br />Xerrades:<br /><br />16:00 – Desevolupament amb iPhone – Oleguer Huguet de <a href="http://woices.com">Woices</a><br />16:45 – La Singularitat: una perspectiva OpenSource – Joan Baz de Adaptiva<br />Sistemas<br />17:30 – KISS IT – Joan Puig<br />18:15 – Auditories de Sistemes, l’inici d’una carrera professional apassionant – <a href="http://marblestation.com">Sergi Blanco Cuaresma</a><br />19:00 – Clausura<br /><br />Les xerrades tindran una duració de 30 min. + 15 min. per preguntes/debat. No es necessari fer reserva, és un esdeveniment obert i gratuït. Es pot assistir a aquelles xerrades que més interessin lliurement.</i><br /><br /><a href="http://www.gpltarragona.org/wp-content/uploads/2010/05/II-Jornades-GPL-Tarragona-Programa.pdf">Programa Completo</a> (PDF)<br /><br /><img src="http://www.gpltarragona.org/wp-content/themes/producer/images/gpltarragona-normal.gif" /></div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2010/04/29/actualizando-ubuntu-1004-lucid-lynx/">Actualizando a Ubuntu 10.04 Lucid Lynx</a></h1>
<p class="meta">
<time class='entry-date' datetime='2010-04-29T12:57:00-07:00'><span class='date'><span class='date-month'>Apr</span> <span class='date-day'>29</span><span class='date-suffix'>th</span>, <span class='date-year'>2010</span></span> <span class='time'>12:57 pm</span></time>
| <a href="/blog/2010/04/29/actualizando-ubuntu-1004-lucid-lynx/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Ya esta disponible la última versión de Ubuntu, 10.04 llamada Lucid Lynx desde la misma <a href="http://www.ubuntu.com/">web de Ubuntu</a> o desde vuestro “Gestor de actualizaciones”.<br />Esta vez no he tenido que cambiar el mirror, el español iba a tope:<br /><br /><img style="margin: 0px auto 10px; display: block; text-align: center; width: 400px; height: 303px;" src="http://1.bp.blogspot.com/_Nv1OUwX9fDo/S9nlXJMZ4GI/AAAAAAAAABg/BSj9GWSNMyw/s400/actualizando-a-lucid.png" alt="" id="BLOGGER_PHOTO_ID_5465651808558506082" border="0" /></div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2010/04/29/nexus-one-datos-3g-movistartelefonica/">Nexus One Datos 3G Movistar/Telefonica</a></h1>
<p class="meta">
<time class='entry-date' datetime='2010-04-29T08:54:00-07:00'><span class='date'><span class='date-month'>Apr</span> <span class='date-day'>29</span><span class='date-suffix'>th</span>, <span class='date-year'>2010</span></span> <span class='time'>8:54 am</span></time>
| <a href="/blog/2010/04/29/nexus-one-datos-3g-movistartelefonica/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Tengo unos datos que funcionan para conectarte al 3G de Movistar (Telefónica) en España con el Nexus One de Google (supongo que funcionarían en cualquier teléfono Android).<br /><br />Los que no tienen valor dejarlo vacío o por defecto.<br /><br />Nombre: Movistar 3G<br />APN: movistar.es<br />Proxy:<br />Puerto:<br />Nombre de usuario: MOVISTAR<br />Contraseña: MOVISTAR<br />Servidor: 194.179.1.100<br />MMSC:<br />Proxy MMS:<br />Puerto MMS:<br />MCC: 214<br />MNC: 07<br />Tipo de APN:<br /><br />Lo que no he encontrado son los datos del MMS, pero bueno tampoco lo uso.<br /><br />PD: No pongais datos de 3G a no ser que tengais un plan de datos con vuestra operadora, sinó luego la factura se resentirá…</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2010/04/19/de-vuelta-en-blogger/">De Vuelta… En Blogger</a></h1>
<p class="meta">
<time class='entry-date' datetime='2010-04-19T10:54:00-07:00'><span class='date'><span class='date-month'>Apr</span> <span class='date-day'>19</span><span class='date-suffix'>th</span>, <span class='date-year'>2010</span></span> <span class='time'>10:54 am</span></time>
| <a href="/blog/2010/04/19/de-vuelta-en-blogger/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Después de varios días off i’m back. El blog anterior estaba alojado en el servidor de GPLTarragona, que le dió por petar el disco duro (no entiendo por qué, era de estos nuevos IDE de 8Gb….. oh wait). Nada que hacer, fallo de hardware con ruido muy feo.<br />De GPLTarragona no hay problema porque hacíamos 1 backup diario al día, pero de mi pobre blog… bueno… como que no lo cuidaba mucho y me despreocupé de él… y resulta que no tenía ningún backup por ahí. Bueno tenía un backup por ahí del 2005 y el resto es como un puzzle :D Pero no hay problema, ya iré reestableciendo los posts poco a poco… que me da pena (ahora) perderlos, por ahora sólo estan hasta el 2005 (quedan unos cuantos :P).<br /><br />Ahora como veis he migrado a blogger, básicamente para tener dominio propio en un blog y no preocuparme por su mantenimiento. Mirando sobre cómo migrar de Wordpress a Blogger me he encontrado con un par de recursos útiles:<br /><br /><a href="http://technosailor.com/2006/07/05/wordpress-to-wordpress-import/">Exportar Xml de todo el blog en Wordpress</a><br /><a href="http://wordpress2blogger.appspot.com/">Convertir Xml de Wordpress en Xml de Blogger</a><br /><a href="http://blogandweb.com/blogger/importar-y-exportar-contenido-en-blogger/">Importar desde Blogger un Xml</a></div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2009/03/11/articulo-random-en-rails/">Articulo Random en Rails</a></h1>
<p class="meta">
<time class='entry-date' datetime='2009-03-11T13:45:00-07:00'><span class='date'><span class='date-month'>Mar</span> <span class='date-day'>11</span><span class='date-suffix'>th</span>, <span class='date-year'>2009</span></span> <span class='time'>1:45 pm</span></time>
| <a href="/blog/2009/03/11/articulo-random-en-rails/#disqus_thread">Comments</a>
</p>
</header>
<div class="entry-content">Queremos obtener un registro aleatorio de la BD en Rails:<br /><br />def random<br /> @articulo = Articulo.find(:first, :order => ‘RAND()’)<br />end</div>
</article>
<div class="pagination">
<a class="prev" href="/posts/2">← Older</a>
<a href="/blog/archives">Blog Archives</a>
</div>
</div>
<aside class="sidebar">
</aside>
</div>
</div>
<footer role="contentinfo"><p>
Copyright © 2015 - Jonathan Hernandez -
<span class="credit">Powered by <a href="http://octopress.org">Octopress</a> | Themed with <a href="https://github.com/jbilbo/whitespace">Whitespace</a></span>
</p>
</footer>
<script type="text/javascript">
var disqus_shortname = 'jbilbo';
var disqus_script = 'count.js';
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/' + disqus_script;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}());
</script>
<script type="text/javascript">
(function(){
var twitterWidgets = document.createElement('script');
twitterWidgets.type = 'text/javascript';
twitterWidgets.async = true;
twitterWidgets.src = '//platform.twitter.com/widgets.js';
document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
})();
</script>
</body>
</html>