Showing 6 changed files with 65 additions and 621 deletions
+6
gitprep.conf
... ...
@@ -8,6 +8,12 @@
8 8
 ;;; Tags limit
9 9
 ;tags_limit=1000
10 10
 
11
+;;; Prevent XSS
12
+;;; If prevent_xss is set to 1,
13
+;;; raw content exept text, png, gif, jpeg image,
14
+;;; file is donwloaded, not displayed.
15
+;prevent_xss=1
16
+
11 17
 [admin]
12 18
 ;;; If you forget admin password,
13 19
 ;;; set this value to 1 and access /reset-password page.
+1 -1
lib/Gitprep.pm
... ...
@@ -194,7 +194,7 @@ sub startup {
194 194
       $r->get('/blobdiff/(#diff)/(*file)')->name('blobdiff');
195 195
       
196 196
       # Raw
197
-      $r->get('/raw/:rev/(*file)', {file => undef})->name('raw');
197
+      $r->get('/raw/:rev/(*file)', {file => undef})->to('controller#raw');
198 198
       
199 199
       # Archive
200 200
       $r->get('/archive/(#rev).tar.gz')->name('archive')->to(archive_type => 'tar');
+21 -36
templates/raw.html.ep → lib/Gitprep/Controller.pm
... ...
@@ -1,12 +1,14 @@
1
-<%
2
-  # API
3
-  my $api = gitprep_api;
1
+package Gitprep::Controller;
2
+use Mojo::Base 'Mojolicious::Controller';
3
+
4
+sub raw {
5
+  my $self = shift;
4 6
   
5 7
   # Parameters
6
-  my $user = param('user');
7
-  my $project = param('project');
8
-  my $rev = param('rev');
9
-  my $file = param('file');
8
+  my $user = $self->param('user');
9
+  my $project = $self->param('project');
10
+  my $rev = $self->param('rev');
11
+  my $file = $self->param('file');
10 12
 
11 13
   # Git
12 14
   my $git = $self->app->git;
... ...
@@ -14,32 +16,16 @@
14 16
   # Commit
15 17
   my $commit_log = $git->latest_commit_log($user, $project, $rev, $file);
16 18
   
17
-  # Blob content
18
-  my $bid = $git->id_by_path($user, $project, $rev, $file, 'blob')
19
-    or $api->croak('Cannot find file');
20
-  
21
-  my @cmd = $git->cmd(
22
-    $user,
23
-    $project,
24
-    'cat-file',
25
-    'blob',
26
-    $bid
27
-  );
28
-  open my $fh, '-|', @cmd
29
-    or $api->croak(qq/Couldn't cat "$file", "$bid"/);
30
-  
31
-  # Blob plain
32
-  my $commit;
33
-  my $mimetype;
34
-  my $lines =[];
19
+  # Blob raw
20
+  my $blob_raw = $git->blob_raw($user, $project, $rev, $file);
35 21
   
36 22
   # Content type
37 23
   my $type = $git->blob_contenttype($user, $project, $rev, $file);
38 24
 
39 25
   # Convert text/* content type to text/plain
40
-  if ($self->config('prevent_xss') &&
26
+  if ($self->app->config->{basic}{prevent_xss} &&
41 27
     ($type =~ m#^text/[a-z]+\b(.*)$# ||
42
-    ($type =~ m#^[a-z]+/[a-z]\+xml\b(.*)$# && -T $fh)))
28
+    ($type =~ m#^[a-z]+/[a-z]\+xml\b(.*)$#)))
43 29
   {
44 30
     my $rest = $1;
45 31
     $rest = defined $rest ? $rest : '';
... ...
@@ -51,19 +37,18 @@
51 37
   if (defined $file) { $file_name = $file }
52 38
   elsif ($type =~ m/^text\//) { $file_name .= '.txt' }
53 39
   
54
-  # Content
55
-  my $content = do { local $/; <$fh> };
56
-  my $sandbox = $self->config('prevent_xss') &&
40
+  # Content disposition
41
+  my $sandbox = $self->app->config->{basic}{prevent_xss} &&
57 42
     $type !~ m#^(?:text/[a-z]+|image/(?:gif|png|jpeg))(?:[ ;]|$)#;
58 43
   my $content_disposition = $sandbox ? 'attachment' : 'inline';
59 44
   $content_disposition .= "; filename=$file_name";
60 45
   
61
-  # Render
46
+  # Response
62 47
   $self->res->headers->content_disposition($content_disposition);
63 48
   $self->res->headers->content_type($type);
64
-    use D;d $type;
65
-
66
-  $self->render(text => $content);
67 49
   
68
-  return $self->res->body;
69
-%>
50
+  $self->render(data => $blob_raw);
51
+}
52
+
53
+1;
54
+
+15
lib/Gitprep/Git.pm
... ...
@@ -172,6 +172,21 @@ sub blob_plain {
172 172
   return $content;
173 173
 }
174 174
 
175
+sub blob_raw {
176
+  my ($self, $user, $project, $rev, $path) = @_;
177
+  
178
+  # Get blob raw
179
+  my @cmd = $self->cmd($user, $project, 'cat-file', 'blob', "$rev:$path");
180
+  open my $fh, "-|", @cmd
181
+    or croak 500, "Open git-cat-file failed";
182
+  local $/;
183
+  my $blob_raw = scalar <$fh>;
184
+
185
+  close $fh or croak 'Reading git-shortlog failed';
186
+  
187
+  return $blob_raw;
188
+}
189
+
175 190
 sub blob_mimetype {
176 191
   my ($self, $user, $project, $rev, $file) = @_;
177 192
   
-584
lib/Gitprep/RepManager.pm
... ...
@@ -1,584 +0,0 @@
1
-package Gitprep::RepManager;
2
-use Mojo::Base -base;
3
-
4
-use Carp 'croak';
5
-use File::Copy 'move';
6
-use File::Path qw/mkpath rmtree/;
7
-use File::Temp ();
8
-use Encode 'encode';
9
-
10
-has 'app';
11
-
12
-sub default_branch {
13
-  my ($self, $user, $project) = @_;
14
-  
15
-  my $default_branch = $self->app->dbi->model('project')
16
-    ->select('default_branch', id => [$user, $project])
17
-    ->value;
18
-  
19
-  return $default_branch;
20
-}
21
-
22
-sub members {
23
-  my ($self, $user, $project) = @_;
24
-  
25
-  # DBI
26
-  my $dbi = $self->app->dbi;
27
-  
28
-  # Original project id
29
-  my $original_pid = $dbi->model('project')
30
-    ->select('original_pid', id => [$user, $project])->value;
31
-  
32
-  # Members
33
-  my $members = $dbi->model('project')->select(
34
-    ['user_id as id', 'name as project'],
35
-    where => [
36
-      ['and',
37
-        ':original_pid{=}',
38
-        ['or', ':user_id{<>}', ':name{<>}']
39
-      ],
40
-      {
41
-        original_pid => $original_pid,
42
-        user_id => $user,
43
-        name => $project
44
-      }
45
-    ],
46
-    append => 'order by user_id, name'
47
-  )->all;
48
-  
49
-  warn $dbi->last_sql;
50
-  use D;d $members;
51
-
52
-  return $members;
53
-}
54
-
55
-sub create_project {
56
-  my ($self, $user, $project, $opts) = @_;
57
-  
58
-  my $dbi = $self->app->dbi;
59
-  
60
-  # Create project
61
-  my $error;
62
-  eval {
63
-    $dbi->connector->txn(sub {
64
-      eval { $self->_create_project($user, $project) };
65
-      croak $error = $@ if $@;
66
-      eval {$self->_create_rep($user, $project, $opts) };
67
-      croak $error = $@ if $@;
68
-    });
69
-  };
70
-  croak $error if $@;
71
-}
72
-
73
-sub create_user {
74
-  my ($self, $user, $data) = @_;
75
-
76
-  my $dbi = $self->app->dbi;
77
-  
78
-  # Create user
79
-  my $error;
80
-  eval {
81
-    $dbi->connector->txn(sub {
82
-      eval { $self->_create_db_user($user, $data) };
83
-      croak $error = $@ if $@;
84
-      eval {$self->_create_user_dir($user) };
85
-      croak $error = $@ if $@;
86
-    });
87
-  };
88
-  croak $error if $@;
89
-}
90
-
91
-sub delete_project {
92
-  my ($self, $user, $project) = @_;
93
-  
94
-  my $dbi = $self->app->dbi;
95
-  
96
-  # Delete project
97
-  my $error;
98
-  eval {
99
-    $dbi->connector->txn(sub {
100
-      eval { $self->_delete_project($user, $project) };
101
-      croak $error = $@ if $@;
102
-      eval {$self->_delete_rep($user, $project) };
103
-      croak $error = $@ if $@;
104
-    });
105
-  };
106
-  croak $error if $@;
107
-  
108
-  return 1;
109
-}
110
-
111
-sub delete_user {
112
-  my ($self, $user) = @_;
113
-  
114
-  my $dbi = $self->app->dbi;
115
-  
116
-  # Delete user
117
-  my $error;
118
-  eval {
119
-    $dbi->connector->txn(sub {
120
-      eval { $self->_delete_db_user($user) };
121
-      croak $error = $@ if $@;
122
-      eval {$self->_delete_user_dir($user) };
123
-      croak $error = $@ if $@;
124
-    });
125
-  };
126
-  croak $error if $@;
127
-  
128
-  return 1;
129
-}
130
-
131
-sub original_project {
132
-  my ($self, $user, $project) = @_;
133
-  
134
-  my $dbi = $self->app->dbi;
135
-  
136
-  my $original_project = $dbi->model('project')
137
-    ->select('original_project', id => [$user, $project])
138
-    ->value;
139
-  return unless defined $original_project && length $original_project;
140
-  
141
-  return $original_project;
142
-}
143
-
144
-sub original_user {
145
-  my ($self, $user, $project) = @_;
146
-  
147
-  my $dbi = $self->app->dbi;
148
-  
149
-  my $original_user = $dbi->model('project')
150
-    ->select('original_user', id => [$user, $project])
151
-    ->value;
152
-  return unless defined $original_user && length $original_user;
153
-  
154
-  return $original_user;
155
-}
156
-
157
-sub _delete_db_user {
158
-  my ($self, $user) = @_;
159
-  
160
-  $self->app->dbi->model('user')->delete(id => $user);
161
-}
162
-
163
-sub _delete_user_dir {
164
-  my ($self, $user) = @_;
165
-
166
-  my $home = $self->app->git->rep_home;
167
-  my $user_dir = "$home/$user";
168
-  rmtree $user_dir;
169
-}
170
-
171
-sub _create_db_user {
172
-  my ($self, $user, $data) = @_;
173
-  
174
-  $self->app->dbi->model('user')->insert($data, id => $user);
175
-}
176
-
177
-sub _create_user_dir {
178
-  my ($self, $user) = @_;
179
-
180
-  my $home = $self->app->git->rep_home;
181
-  my $user_dir = "$home/$user";
182
-  mkpath $user_dir;
183
-}
184
-
185
-sub exists_project { shift->_exists_project(@_) }
186
-
187
-sub fork_project {
188
-  my ($self, $user, $original_user, $project) = @_;
189
-  
190
-  # DBI
191
-  my $dbi = $self->app->dbi;
192
-  
193
-  # Fork project
194
-  my $error;
195
-  eval {
196
-    $dbi->connector->txn(sub {
197
-      
198
-      # Original project id
199
-      my $original_pid = $dbi->model('project')
200
-        ->select('original_pid', id => [$original_user, $project])->value;
201
-      
202
-      croak "Can't get original project id"
203
-        unless defined $original_pid && $original_pid > 0;
204
-      
205
-      # Create project
206
-      eval {
207
-        $self->_create_project(
208
-          $user,
209
-          $project,
210
-          {
211
-            original_user => $original_user,
212
-            original_project => $project,
213
-            original_pid => $original_pid
214
-          }
215
-        );
216
-      };
217
-      croak $error = $@ if $@;
218
-      
219
-      # Create repository
220
-      eval {
221
-        $self->_fork_rep($original_user, $project, $user, $project);
222
-      };
223
-      croak $error = $@ if $@;
224
-    });
225
-  };
226
-  croak $error if $@;
227
-}
228
-
229
-sub _fork_rep {
230
-  my ($self, $user, $project, $to_user, $to_project) = @_;
231
-  
232
-  # Git
233
-  my $git = $self->app->git;
234
-  
235
-  # Git clone
236
-  my $rep = $git->rep($user, $project);
237
-  my $to_rep = $git->rep($to_user, $to_project);
238
-  my @git_clone_cmd = (
239
-    $git->bin,
240
-    'clone',
241
-    '-q',
242
-    '--bare',
243
-    $rep,
244
-    $to_rep
245
-  );
246
-  system(@git_clone_cmd) == 0
247
-    or croak "Can't execute git clone";
248
-}
249
-
250
-sub rename_project {
251
-  my ($self, $user, $project, $renamed_project) = @_;
252
-  
253
-  my $git = $self->app->git;
254
-  my $dbi = $self->app->dbi;
255
-  
256
-  my $error = {};
257
-  
258
-  if ($self->_exists_project($user, $renamed_project)
259
-    || $self->_exists_rep($user, $renamed_project))
260
-  {
261
-    $error->{message} = 'Already exists';
262
-    return $error;
263
-  }
264
-  else {
265
-    $dbi->connector->txn(sub {
266
-      $self->_rename_project($user, $project, $renamed_project);
267
-      $self->_rename_rep($user, $project, $renamed_project);
268
-    });
269
-    if ($@) {
270
-      $error->{message} = 'Rename failed';
271
-      return $error;
272
-    }
273
-  }
274
-  
275
-  return 1;
276
-}
277
-
278
-sub setup_database {
279
-  my $self = shift;
280
-  
281
-  my $dbi = $self->app->dbi;
282
-  
283
-  # Create user table
284
-  eval {
285
-    my $sql = <<"EOS";
286
-create table user (
287
-  row_id integer primary key autoincrement,
288
-  id not null unique default ''
289
-);
290
-EOS
291
-    $dbi->execute($sql);
292
-  };
293
-
294
-  # Create usert columns
295
-  my $user_columns = [
296
-    "admin not null default '0'",
297
-    "password not null default ''",
298
-    "salt not null default ''"
299
-  ];
300
-  for my $column (@$user_columns) {
301
-    eval { $dbi->execute("alter table user add column $column") };
302
-  }
303
-  
304
-  # Check user table
305
-  eval { $dbi->select([qw/row_id id admin password salt/], table => 'user') };
306
-  if ($@) {
307
-    my $error = "Can't create user table properly: $@";
308
-    $self->app->log->error($error);
309
-    croak $error;
310
-  }
311
-  
312
-  # Create project table
313
-  eval {
314
-    my $sql = <<"EOS";
315
-create table project (
316
-  row_id integer primary key autoincrement,
317
-  user_id not null,
318
-  name not null,
319
-  unique(user_id, name)
320
-);
321
-EOS
322
-    $dbi->execute($sql);
323
-  };
324
-  
325
-  # Create Project columns
326
-  my $project_columns = [
327
-    "default_branch not null default 'master'",
328
-    "original_user not null default ''",
329
-    "original_project not null default ''",
330
-    "original_pid integer not null default 0"
331
-  ];
332
-  for my $column (@$project_columns) {
333
-    eval { $dbi->execute("alter table project add column $column") };
334
-  }
335
-
336
-  # Check project table
337
-  eval { $dbi->select([qw/default_branch original_user original_project original_pid/], table => 'project') };
338
-  if ($@) {
339
-    my $error = "Can't create project table properly: $@";
340
-    $self->app->log->error($error);
341
-    croak $error;
342
-  }
343
-
344
-  # Create number table
345
-  eval {
346
-    my $sql = <<"EOS";
347
-create table number (
348
-  row_id integer primary key autoincrement,
349
-  key not null unique
350
-);
351
-EOS
352
-    $dbi->execute($sql);
353
-  };
354
-  
355
-  # Create number columns
356
-  my $number_columns = [
357
-    "value integer not null default '0'"
358
-  ];
359
-  for my $column (@$number_columns) {
360
-    eval { $dbi->execute("alter table number add column $column") };
361
-  }
362
-
363
-  # Check number table
364
-  eval { $dbi->select([qw/row_id key value/], table => 'number') };
365
-  if ($@) {
366
-    my $error = "Can't create number table properly: $@";
367
-    $self->app->log->error($error);
368
-    croak $error;
369
-  }
370
-  
371
-  # Original project id numbert
372
-  eval { $dbi->insert({key => 'original_pid'}, table => 'number') };
373
-  my $original_pid = $dbi->select(
374
-    'key',
375
-    table => 'number',
376
-    where => {key => 'original_pid'}
377
-  )->value;
378
-  unless (defined $original_pid) {
379
-    my $error = "Can't create original_pid row in number table";
380
-    $self->app->log->error($error);
381
-    croak $error;
382
-  }
383
-}
384
-
385
-sub _create_project {
386
-  my ($self, $user, $project, $params) = @_;
387
-  $params ||= {};
388
-  
389
-  # DBI
390
-  my $dbi = $self->app->dbi;
391
-  
392
-  # Create project
393
-  $dbi->connector->txn(sub {
394
-    unless (defined $params->{original_pid}) {
395
-      my $number = $dbi->model('number')->select('value', where => {key => 'original_pid'})->value;
396
-      $number++;
397
-      $dbi->model('number')->update({value => $number}, where => {key => 'original_pid'});
398
-      $params->{original_pid} = $number;
399
-    }
400
-    $dbi->model('project')->insert($params, id => [$user, $project]);
401
-  });
402
-}
403
-
404
-sub _create_rep {
405
-  my ($self, $user, $project, $opts) = @_;
406
-  
407
-  # Git
408
-  my $git = $self->app->git;
409
-  
410
-  # Create repository directory
411
-  my $rep = $git->rep($user, $project);
412
-  mkdir $rep
413
-    or croak "Can't create directory $rep: $!";
414
-
415
-  eval {
416
-    # Git init
417
-    {
418
-      my @git_init_cmd = $git->cmd_rep($rep, 'init', '--bare');
419
-      open my $fh, "-|", @git_init_cmd
420
-        or croak  "Can't execute git init";
421
-      close $fh;
422
-    }
423
-    
424
-    # Add git-daemon-export-ok
425
-    {
426
-      my $file = "$rep/git-daemon-export-ok";
427
-      open my $fh, '>', $file
428
-        or croak "Can't create git-daemon-export-ok: $!"
429
-    }
430
-    
431
-    # HTTP support
432
-    my @git_update_server_info_cmd = $git->cmd_rep(
433
-      $rep,
434
-      '--bare',
435
-      'update-server-info'
436
-    );
437
-    system(@git_update_server_info_cmd) == 0
438
-      or croak "Can't execute git --bare update-server-info";
439
-    move("$rep/hooks/post-update.sample", "$rep/hooks/post-update")
440
-      or croak "Can't move post-update";
441
-    
442
-    # Description
443
-    {
444
-      my $description = $opts->{description};
445
-      $description = '' unless defined $description;
446
-      my $file = "$rep/description";
447
-      open my $fh, '>', $file
448
-        or croak "Can't open $file: $!";
449
-      print $fh encode('UTF-8', $description)
450
-        or croak "Can't write $file: $!";
451
-      close $fh;
452
-    }
453
-    
454
-    # Add README and commit
455
-    if ($opts->{readme}) {
456
-      # Create working directory
457
-      my $temp_dir =  File::Temp->newdir;
458
-      my $temp_work = "$temp_dir/work";
459
-      mkdir $temp_work
460
-        or croak "Can't create directory $temp_work: $!";
461
-
462
-      # Git init
463
-      my @git_init_cmd = $git->cmd_rep($temp_work, 'init', '-q');
464
-      system(@git_init_cmd) == 0
465
-        or croak "Can't execute git init";
466
-      
467
-      # Add README
468
-      my $file = "$temp_work/README";
469
-      open my $fh, '>', $file
470
-        or croak "Can't create $file: $!";
471
-      my @git_add_cmd = $git->cmd_rep(
472
-        $temp_work,
473
-        "--work-tree=$temp_work",
474
-        'add',
475
-        'README'
476
-      );
477
-      system(@git_add_cmd) == 0
478
-        or croak "Can't execute git add";
479
-      
480
-      # Commit
481
-      my @git_commit_cmd = $git->cmd_rep(
482
-        $temp_work,
483
-        "--work-tree=$temp_work",
484
-        'commit',
485
-        '-q',
486
-        '-m',
487
-        'first commit'
488
-      );
489
-      system(@git_commit_cmd) == 0
490
-        or croak "Can't execute git commit";
491
-      
492
-      # Push
493
-      {
494
-        my @git_push_cmd = $git->cmd_rep(
495
-          $temp_work,
496
-          "--work-tree=$temp_work",
497
-          'push',
498
-          '-q',
499
-          $rep,
500
-          'master'
501
-        );
502
-        # (This is bad, but --quiet option can't supress in old git)
503
-        my $git_push_cmd = join(' ', @git_push_cmd);
504
-        system("$git_push_cmd 2> /dev/null") == 0
505
-          or croak "Can't execute git push";
506
-      }
507
-    }
508
-  };
509
-  if ($@) {
510
-    rmtree $rep;
511
-    croak $@;
512
-  }
513
-}
514
-
515
-sub _delete_project {
516
-  my ($self, $user, $project) = @_;
517
-  
518
-  my $dbi = $self->app->dbi;
519
-  $dbi->model('project')->delete(id => [$user, $project]);
520
-}
521
-
522
-sub _delete_rep {
523
-  my ($self, $user, $project) = @_;
524
-
525
-  my $rep_home = $self->app->git->rep_home;
526
-  croak "Can't remove repository. repositry home is empty"
527
-    if !defined $rep_home || $rep_home eq '';
528
-  my $rep = "$rep_home/$user/$project.git";
529
-  rmtree $rep;
530
-  croak "Can't remove repository. repository is rest"
531
-    if -e $rep;
532
-}
533
-
534
-sub _exists_project {
535
-  my ($self, $user, $project) = @_;
536
-
537
-  my $dbi = $self->app->dbi;
538
-  my $row = $dbi->model('project')->select(id => [$user, $project])->one;
539
-  
540
-  return $row ? 1 : 0;
541
-}
542
-
543
-sub _exists_rep {
544
-  my ($self, $user, $project) = @_;
545
-  
546
-  my $rep = $self->app->git->rep($user, $project);
547
-  
548
-  return -e $rep;
549
-}
550
-
551
-sub _rename_project {
552
-  my ($self, $user, $project, $renamed_project) = @_;
553
-  
554
-  my $dbi = $self->app->dbi;
555
-  
556
-  croak "Invalid parameters"
557
-    unless defined $user && defined $project && defined $renamed_project;
558
-  
559
-  # Rename project
560
-  $dbi->model('project')->update(
561
-    {name => $renamed_project},
562
-    id => [$user, $project]
563
-  );
564
-  
565
-  # Rename related project
566
-  $dbi->model('project')->update(
567
-    {original_project => $renamed_project},
568
-    where => {original_user => $user, original_project => $project},
569
-  );
570
-}
571
-
572
-sub _rename_rep {
573
-  my ($self, $user, $project, $renamed_project) = @_;
574
-  
575
-  croak "Invalid user name or project"
576
-    unless defined $user && defined $project && defined $renamed_project;
577
-  my $rep = $self->app->git->rep($user, $project);
578
-  my $renamed_rep = $self->app->git->rep($user, $renamed_project);
579
-  
580
-  move($rep, $renamed_rep)
581
-    or croak "Can't move $rep to $renamed_rep: $!";
582
-}
583
-
584
-1;
+22
xt/basic.t
... ...
@@ -1,9 +1,11 @@
1 1
 use Test::More 'no_plan';
2 2
 
3 3
 use FindBin;
4
+use utf8;
4 5
 use lib "$FindBin::Bin/../mojo/lib";
5 6
 use lib "$FindBin::Bin/../lib";
6 7
 use lib "$FindBin::Bin/../extlib/lib/perl5";
8
+use Encode qw/encode decode/;
7 9
 
8 10
 use Test::Mojo;
9 11
 
... ...
@@ -120,3 +122,23 @@ note 'Tags page';
120 122
   # Tar.gz link
121 123
   $t->content_like(qr#/$user/$project/archive/t1.tar.gz#);
122 124
 }
125
+
126
+note 'blob page';
127
+{
128
+  # Page access
129
+  $t->get_ok("/$user/$project/blob/b9f0f107672b910a44d22d4623ce7445d40565aa/a_renamed.txt");
130
+  
131
+  # Content
132
+  $t->content_like(qr/あああ/);
133
+}
134
+
135
+note 'raw page';
136
+{
137
+  # Page access
138
+  $t->get_ok("/$user/$project/raw/b9f0f107672b910a44d22d4623ce7445d40565aa/a_renamed.txt");
139
+  
140
+  # Content
141
+  my $content_binary = $t->tx->res->body;
142
+  my $content = decode('UTF-8', $content_binary);
143
+  like($content, qr/あああ/);
144
+}